From 8085fcc792a72087d9402ae570623d2842d16b1b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 20 Dec 2013 20:02:42 +0100 Subject: [PATCH 001/168] Added Referencable checks class, added method to get refidcontainer, added method to get mBooks. Currently only books are checked, and only if name is present. --- apps/opencs/CMakeLists.txt | 2 +- .../opencs/model/tools/referenceablecheck.cpp | 63 +++++++++++++++++++ .../opencs/model/tools/referenceablecheck.hpp | 26 ++++++++ apps/opencs/model/tools/tools.cpp | 5 +- apps/opencs/model/world/refidcollection.cpp | 6 ++ apps/opencs/model/world/refidcollection.hpp | 2 + apps/opencs/model/world/refiddata.cpp | 7 ++- apps/opencs/model/world/refiddata.hpp | 3 + 8 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 apps/opencs/model/tools/referenceablecheck.cpp create mode 100644 apps/opencs/model/tools/referenceablecheck.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 1197e20140..baf677f8dd 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -38,7 +38,7 @@ opencs_units (model/tools opencs_units_noqt (model/tools mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck - birthsigncheck spellcheck + birthsigncheck spellcheck referenceablecheck ) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp new file mode 100644 index 0000000000..01c8d30a72 --- /dev/null +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -0,0 +1,63 @@ +#include "referenceablecheck.hpp" + +#include +#include +#include + +#include +#include "../world/record.hpp" + +#include "../world/universalid.hpp" + +CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable) : + mReferencables(referenceable), + mBooksSize(0) +{ + setSizeVariables(); +} + +void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) +{ + //Checks for books, than, when stage is above mBooksSize goes to other checks, with stage - minus prev sizes as stage. + bool CheckPerformed = false; + + if (stage <= mBooksSize) + { + bookCheck(stage, mReferencables.getBooks(), messages); + CheckPerformed = true; + } + + if (CheckPerformed) + { + return; + } +} + +int CSMTools::ReferenceableCheckStage::setup() +{ + return mReferencables.getSize(); +} + +void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Book& Book = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, Book.mId); + + //Checking for name + if (Book.mName.empty()) + { + messages.push_back(id.toString() + "|" + Book.mId + " has an empty name"); + } +} + +void CSMTools::ReferenceableCheckStage::setSizeVariables() +{ + mBooksSize = mReferencables.getBooks().getSize(); +} diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp new file mode 100644 index 0000000000..509e8d8c0f --- /dev/null +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -0,0 +1,26 @@ +#ifndef REFERENCEABLECHECKSTAGE_H +#define REFERENCEABLECHECKSTAGE_H + +#include "../world/universalid.hpp" +#include "../doc/stage.hpp" +#include "../world/data.hpp" +#include "../world/refiddata.hpp" + +namespace CSMTools +{ + class ReferenceableCheckStage : public CSMDoc::Stage + { + public: + ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable); + virtual void perform(int stage, std::vector< std::string >& messages); + virtual int setup(); + + private: + void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages); + void setSizeVariables(); + + const CSMWorld::RefIdData mReferencables; + int mBooksSize; + }; +} +#endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index cd4653280e..bca9f6fb7d 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -19,6 +19,7 @@ #include "regioncheck.hpp" #include "birthsigncheck.hpp" #include "spellcheck.hpp" +#include "referenceablecheck.hpp" CSMDoc::Operation *CSMTools::Tools::get (int type) { @@ -74,6 +75,8 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() mVerifier->appendStage (new BirthsignCheckStage (mData.getBirthsigns())); mVerifier->appendStage (new SpellCheckStage (mData.getSpells())); + + mVerifier->appendStage( new ReferenceableCheckStage (mData.getReferenceables().getDataSet())); } return mVerifier; @@ -138,4 +141,4 @@ void CSMTools::Tools::verifierMessage (const QString& message, int type) if (iter!=mActiveReports.end()) mReports[iter->second]->add (message.toStdString()); -} \ No newline at end of file +} diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 86a542c5c3..9ed5268183 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -549,3 +549,9 @@ void CSMWorld::RefIdCollection::save (int index, ESM::ESMWriter& writer) const { mData.save (index, writer); } + +const CSMWorld::RefIdData& CSMWorld::RefIdCollection::getDataSet() const +{ + return mData; +} + diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 5ff4a70bf2..70cae53c84 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -107,6 +107,8 @@ namespace CSMWorld /// \return Success? void save (int index, ESM::ESMWriter& writer) const; + + const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( }; } diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 8f59b0fe74..0fbfef4f10 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -230,4 +230,9 @@ void CSMWorld::RefIdData::save (int index, ESM::ESMWriter& writer) const throw std::logic_error ("invalid local index type"); iter->second->save (localIndex.first, writer); -} \ No newline at end of file +} + +const CSMWorld::RefIdDataContainer< ESM::Book >& CSMWorld::RefIdData::getBooks() const +{ + return mBooks; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 9595ab23b5..1590b58df3 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -219,6 +219,9 @@ namespace CSMWorld /// \param listDeleted include deleted record in the list void save (int index, ESM::ESMWriter& writer) const; + + //RECORD CONTAINERS ACCESS METHODS + const RefIdDataContainer& getBooks() const; }; } From f69465d7e0ca6a24f445825d6e0768463699fc1f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 20 Dec 2013 22:31:17 +0100 Subject: [PATCH 002/168] Added aditional checks for books. Activator check. --- .../opencs/model/tools/referenceablecheck.cpp | 72 +++++++++++++++++-- .../opencs/model/tools/referenceablecheck.hpp | 2 + apps/opencs/model/world/refiddata.cpp | 5 ++ apps/opencs/model/world/refiddata.hpp | 1 + 4 files changed, 74 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 01c8d30a72..f8dcd86a48 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -4,26 +4,27 @@ #include #include -#include #include "../world/record.hpp" #include "../world/universalid.hpp" CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable) : mReferencables(referenceable), - mBooksSize(0) + mBooksSize(0), + mActivatorsSize(0) { setSizeVariables(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) { - //Checks for books, than, when stage is above mBooksSize goes to other checks, with stage - minus prev sizes as stage. + //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. bool CheckPerformed = false; - + int PrevSum(0); + if (stage <= mBooksSize) - { - bookCheck(stage, mReferencables.getBooks(), messages); + { + bookCheck(stage, mReferencables.getBooks(), messages); CheckPerformed = true; } @@ -31,6 +32,21 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str { return; } + + PrevSum += mBooksSize; + + if ((stage - PrevSum) <= mActivatorsSize) + { + activatorCheck(stage - PrevSum, mReferencables.getActivator(), messages); + CheckPerformed = true; + } + + if (CheckPerformed) + { + return; + } + + PrevSum += mActivatorsSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -55,9 +71,53 @@ void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::Ref { messages.push_back(id.toString() + "|" + Book.mId + " has an empty name"); } + + //Checking for weight + if (Book.mData.mWeight < 0) + { + messages.push_back(id.toString() + "|" + Book.mId + " has a negative weight"); + } + + //Checking for value + if (Book.mData.mValue < 0) + { + messages.push_back(id.toString() + "|" + Book.mId + " has a negative value"); + } + +//checking for model + if (Book.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Book.mId + " has no model"); + } + + //checking for icon + if (Book.mIcon.empty()) + { + messages.push_back(id.toString() + "|" + Book.mId + " has no icon"); + } +} + +void CSMTools::ReferenceableCheckStage::activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Activator& Activator = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Activator, Activator.mId); + + //Checking for model, IIRC all activators should have a model + if (Activator.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Activator.mId + " has no model"); + } } void CSMTools::ReferenceableCheckStage::setSizeVariables() { mBooksSize = mReferencables.getBooks().getSize(); + mActivatorsSize = mReferencables.getActivator().getSize(); } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 509e8d8c0f..dc2913c22f 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -17,10 +17,12 @@ namespace CSMTools private: void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages); + void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages); void setSizeVariables(); const CSMWorld::RefIdData mReferencables; int mBooksSize; + int mActivatorsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 0fbfef4f10..2285790be9 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -236,3 +236,8 @@ const CSMWorld::RefIdDataContainer< ESM::Book >& CSMWorld::RefIdData::getBooks() { return mBooks; } + +const CSMWorld::RefIdDataContainer< ESM::Activator >& CSMWorld::RefIdData::getActivator() const +{ + return mActivators; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 1590b58df3..4a8e1e6f54 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -222,6 +222,7 @@ namespace CSMWorld //RECORD CONTAINERS ACCESS METHODS const RefIdDataContainer& getBooks() const; + const RefIdDataContainer& getActivator() const; }; } From 4842c56cb5849f6634a29f065064cd9704d70f37 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 21 Dec 2013 10:58:05 +0100 Subject: [PATCH 003/168] added getpotions --- apps/opencs/model/world/refiddata.cpp | 5 +++++ apps/opencs/model/world/refiddata.hpp | 1 + 2 files changed, 6 insertions(+) diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 2285790be9..ddbde099e0 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -241,3 +241,8 @@ const CSMWorld::RefIdDataContainer< ESM::Activator >& CSMWorld::RefIdData::getAc { return mActivators; } + +const CSMWorld::RefIdDataContainer< ESM::Potion >& CSMWorld::RefIdData::getPotions() const +{ + return mPotions; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 4a8e1e6f54..9f5cf9f9a0 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -223,6 +223,7 @@ namespace CSMWorld //RECORD CONTAINERS ACCESS METHODS const RefIdDataContainer& getBooks() const; const RefIdDataContainer& getActivator() const; + const RefIdDataContainer& getPotions() const; }; } From 385824aee0194d9ecf04c74303e7b225b880e687 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 21 Dec 2013 10:59:13 +0100 Subject: [PATCH 004/168] Renamed getActivator to getActivators. --- apps/opencs/model/tools/referenceablecheck.cpp | 2 +- apps/opencs/model/world/refiddata.cpp | 2 +- apps/opencs/model/world/refiddata.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index f8dcd86a48..eceaf999ba 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -37,7 +37,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str if ((stage - PrevSum) <= mActivatorsSize) { - activatorCheck(stage - PrevSum, mReferencables.getActivator(), messages); + activatorCheck(stage - PrevSum, mReferencables.getActivators(), messages); CheckPerformed = true; } diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index ddbde099e0..3a9d82630a 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -237,7 +237,7 @@ const CSMWorld::RefIdDataContainer< ESM::Book >& CSMWorld::RefIdData::getBooks() return mBooks; } -const CSMWorld::RefIdDataContainer< ESM::Activator >& CSMWorld::RefIdData::getActivator() const +const CSMWorld::RefIdDataContainer< ESM::Activator >& CSMWorld::RefIdData::getActivators() const { return mActivators; } diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 9f5cf9f9a0..1a4a416387 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -222,7 +222,7 @@ namespace CSMWorld //RECORD CONTAINERS ACCESS METHODS const RefIdDataContainer& getBooks() const; - const RefIdDataContainer& getActivator() const; + const RefIdDataContainer& getActivators() const; const RefIdDataContainer& getPotions() const; }; } From a6c36e23779251ad652312fe06742fa122880380 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 21 Dec 2013 11:01:40 +0100 Subject: [PATCH 005/168] Small optimization. --- apps/opencs/model/tools/referenceablecheck.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index eceaf999ba..8eff6ed0bc 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -20,7 +20,6 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. bool CheckPerformed = false; - int PrevSum(0); if (stage <= mBooksSize) { @@ -32,12 +31,11 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str { return; } - - PrevSum += mBooksSize; - - if ((stage - PrevSum) <= mActivatorsSize) + stage -= mBooksSize; + + if ((stage) <= mActivatorsSize) { - activatorCheck(stage - PrevSum, mReferencables.getActivators(), messages); + activatorCheck(stage, mReferencables.getActivators(), messages); CheckPerformed = true; } @@ -45,8 +43,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str { return; } - - PrevSum += mActivatorsSize; + stage -= mActivatorsSize; } int CSMTools::ReferenceableCheckStage::setup() From 21ee2a6d2e6384b794210b67215ae71dad51c62b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 21 Dec 2013 11:02:58 +0100 Subject: [PATCH 006/168] Getting size of potions. --- apps/opencs/model/tools/referenceablecheck.cpp | 6 ++++-- apps/opencs/model/tools/referenceablecheck.hpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 8eff6ed0bc..ff2d6e7135 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -11,7 +11,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable) : mReferencables(referenceable), mBooksSize(0), - mActivatorsSize(0) + mActivatorsSize(0), + mPotionsSize(0) { setSizeVariables(); } @@ -116,5 +117,6 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(int stage, const CSMWorld void CSMTools::ReferenceableCheckStage::setSizeVariables() { mBooksSize = mReferencables.getBooks().getSize(); - mActivatorsSize = mReferencables.getActivator().getSize(); + mActivatorsSize = mReferencables.getActivators().getSize(); + mPotionsSize = mReferencables.getPotions().getSize(); } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index dc2913c22f..fed662e27a 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -23,6 +23,7 @@ namespace CSMTools const CSMWorld::RefIdData mReferencables; int mBooksSize; int mActivatorsSize; + int mPotionsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H From ee5dfd1cc8d0b40b806391ced7b36641ade4241f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 21 Dec 2013 11:15:46 +0100 Subject: [PATCH 007/168] Adde potionCheck method --- .../opencs/model/tools/referenceablecheck.cpp | 69 +++++++++++++++---- .../opencs/model/tools/referenceablecheck.hpp | 10 +-- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index ff2d6e7135..59591ca023 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -20,31 +20,30 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. - bool CheckPerformed = false; if (stage <= mBooksSize) { bookCheck(stage, mReferencables.getBooks(), messages); - CheckPerformed = true; - } - - if (CheckPerformed) - { return; } + stage -= mBooksSize; - - if ((stage) <= mActivatorsSize) + + if (stage <= mActivatorsSize) { activatorCheck(stage, mReferencables.getActivators(), messages); - CheckPerformed = true; - } - - if (CheckPerformed) - { return; } + stage -= mActivatorsSize; + + if (stage <= mPotionsSize) + { + potionsCheck(stage, mReferencables.getPotions(), messages); + return; + } + + stage -= mPotionsSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -114,6 +113,50 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(int stage, const CSMWorld } } +void CSMTools::ReferenceableCheckStage::potionsCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Potion >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Potion& Potion = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, Potion.mId); + + //Checking for name + if (Potion.mName.empty()) + { + messages.push_back(id.toString() + "|" + Potion.mId + " has an empty name"); + } + + //Checking for weight + if (Potion.mData.mWeight < 0) + { + messages.push_back(id.toString() + "|" + Potion.mId + " has a negative weight"); + } + + //Checking for value + if (Potion.mData.mValue < 0) + { + messages.push_back(id.toString() + "|" + Potion.mId + " has a negative value"); + } + +//checking for model + if (Potion.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Potion.mId + " has no model"); + } + + //checking for icon + if (Potion.mIcon.empty()) + { + messages.push_back(id.toString() + "|" + Potion.mId + " has no icon"); + } + //IIRC potion can have empty effects list just fine. +} + void CSMTools::ReferenceableCheckStage::setSizeVariables() { mBooksSize = mReferencables.getBooks().getSize(); diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index fed662e27a..801a2232bb 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -18,12 +18,14 @@ namespace CSMTools private: void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages); void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages); - void setSizeVariables(); + void potionsCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + + void setSizeVariables(); const CSMWorld::RefIdData mReferencables; - int mBooksSize; - int mActivatorsSize; - int mPotionsSize; + int mBooksSize; + int mActivatorsSize; + int mPotionsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H From a27441720e20a119914d3ea512c1ff9298fac405 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 21 Dec 2013 12:07:40 +0100 Subject: [PATCH 008/168] Added enchantmnet check for books. --- .../opencs/model/tools/referenceablecheck.cpp | 85 ++++++++++++++++--- .../opencs/model/tools/referenceablecheck.hpp | 7 +- apps/opencs/model/world/refiddata.cpp | 5 ++ apps/opencs/model/world/refiddata.hpp | 1 + 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 59591ca023..b299744d6f 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -12,11 +12,20 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mReferencables(referenceable), mBooksSize(0), mActivatorsSize(0), - mPotionsSize(0) + mPotionsSize(0), + mApparatiSize(0) { setSizeVariables(); } +void CSMTools::ReferenceableCheckStage::setSizeVariables() +{ + mBooksSize = mReferencables.getBooks().getSize(); + mActivatorsSize = mReferencables.getActivators().getSize(); + mPotionsSize = mReferencables.getPotions().getSize(); + mApparatiSize = mReferencables.getApparati().getSize(); +} + void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. @@ -24,6 +33,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str if (stage <= mBooksSize) { bookCheck(stage, mReferencables.getBooks(), messages); + std::cout<<"Book checking \n"; return; } @@ -39,11 +49,19 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str if (stage <= mPotionsSize) { - potionsCheck(stage, mReferencables.getPotions(), messages); + potionCheck(stage, mReferencables.getPotions(), messages); return; } stage -= mPotionsSize; + + if (stage <= mApparatiSize) + { + apparatusCheck(stage, mReferencables.getApparati(), messages); + return; + } + + stage -= mApparatiSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -72,13 +90,13 @@ void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::Ref //Checking for weight if (Book.mData.mWeight < 0) { - messages.push_back(id.toString() + "|" + Book.mId + " has a negative weight"); + messages.push_back(id.toString() + "|" + Book.mId + " has negative weight"); } //Checking for value if (Book.mData.mValue < 0) { - messages.push_back(id.toString() + "|" + Book.mId + " has a negative value"); + messages.push_back(id.toString() + "|" + Book.mId + " has negative value"); } //checking for model @@ -92,6 +110,12 @@ void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::Ref { messages.push_back(id.toString() + "|" + Book.mId + " has no icon"); } + + //checking for enchantment points + if (Book.mData.mEnchant < 0) + { + messages.push_back(id.toString() + "|" + Book.mId + " has negative enchantment"); + } } void CSMTools::ReferenceableCheckStage::activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages) @@ -113,7 +137,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(int stage, const CSMWorld } } -void CSMTools::ReferenceableCheckStage::potionsCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Potion >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::potionCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Potion >& records, std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -134,13 +158,13 @@ void CSMTools::ReferenceableCheckStage::potionsCheck(int stage, const CSMWorld:: //Checking for weight if (Potion.mData.mWeight < 0) { - messages.push_back(id.toString() + "|" + Potion.mId + " has a negative weight"); + messages.push_back(id.toString() + "|" + Potion.mId + " has negative weight"); } //Checking for value if (Potion.mData.mValue < 0) { - messages.push_back(id.toString() + "|" + Potion.mId + " has a negative value"); + messages.push_back(id.toString() + "|" + Potion.mId + " has negative value"); } //checking for model @@ -157,9 +181,46 @@ void CSMTools::ReferenceableCheckStage::potionsCheck(int stage, const CSMWorld:: //IIRC potion can have empty effects list just fine. } -void CSMTools::ReferenceableCheckStage::setSizeVariables() + +void CSMTools::ReferenceableCheckStage::apparatusCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records, std::vector< std::string >& messages) { - mBooksSize = mReferencables.getBooks().getSize(); - mActivatorsSize = mReferencables.getActivators().getSize(); - mPotionsSize = mReferencables.getPotions().getSize(); -} + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Apparatus& Apparatus = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Apparatus, Apparatus.mId); + + //Checking for name + if (Apparatus.mName.empty()) + { + messages.push_back(id.toString() + "|" + Apparatus.mId + " has an empty name"); + } + + //Checking for weight + if (Apparatus.mData.mWeight < 0) + { + messages.push_back(id.toString() + "|" + Apparatus.mId + " has negative weight"); + } + + //Checking for value + if (Apparatus.mData.mValue < 0) + { + messages.push_back(id.toString() + "|" + Apparatus.mId + " has negative value"); + } + +//checking for model + if (Apparatus.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Apparatus.mId + " has no model"); + } + + //checking for icon + if (Apparatus.mIcon.empty()) + { + messages.push_back(id.toString() + "|" + Apparatus.mId + " has no icon"); + } +} \ No newline at end of file diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 801a2232bb..a40ca16a42 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -16,16 +16,21 @@ namespace CSMTools virtual int setup(); private: + //CONCRETE CHECKS void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages); void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages); - void potionsCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void potionCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void setSizeVariables(); const CSMWorld::RefIdData mReferencables; + + //SIZES OF CONCRETE TYPES int mBooksSize; int mActivatorsSize; int mPotionsSize; + int mApparatiSize; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 3a9d82630a..6f278cc024 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -246,3 +246,8 @@ const CSMWorld::RefIdDataContainer< ESM::Potion >& CSMWorld::RefIdData::getPotio { return mPotions; } + +const CSMWorld::RefIdDataContainer< ESM::Apparatus >& CSMWorld::RefIdData::getApparati() const +{ + return mApparati; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 1a4a416387..b32b0347a3 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -224,6 +224,7 @@ namespace CSMWorld const RefIdDataContainer& getBooks() const; const RefIdDataContainer& getActivators() const; const RefIdDataContainer& getPotions() const; + const RefIdDataContainer& getApparati() const; }; } From 1811f0a71b8b0695f7b510dd36288133c9876fc8 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 21 Dec 2013 15:40:39 +0100 Subject: [PATCH 009/168] Works, but it seems that I miss something in referencables. I will write post on the forum. --- apps/opencs/model/tools/referenceablecheck.cpp | 11 +++++------ apps/opencs/model/tools/reportmodel.cpp | 2 +- apps/opencs/model/tools/tools.cpp | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index b299744d6f..e86e8db545 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -30,16 +30,15 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. - if (stage <= mBooksSize) + if (stage < mBooksSize) { bookCheck(stage, mReferencables.getBooks(), messages); - std::cout<<"Book checking \n"; return; } stage -= mBooksSize; - if (stage <= mActivatorsSize) + if (stage < mActivatorsSize) { activatorCheck(stage, mReferencables.getActivators(), messages); return; @@ -47,7 +46,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str stage -= mActivatorsSize; - if (stage <= mPotionsSize) + if (stage < mPotionsSize) { potionCheck(stage, mReferencables.getPotions(), messages); return; @@ -55,7 +54,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str stage -= mPotionsSize; - if (stage <= mApparatiSize) + if (stage < mApparatiSize) { apparatusCheck(stage, mReferencables.getApparati(), messages); return; @@ -223,4 +222,4 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(int stage, const CSMWorld { messages.push_back(id.toString() + "|" + Apparatus.mId + " has no icon"); } -} \ No newline at end of file +} diff --git a/apps/opencs/model/tools/reportmodel.cpp b/apps/opencs/model/tools/reportmodel.cpp index b125318755..d883617464 100644 --- a/apps/opencs/model/tools/reportmodel.cpp +++ b/apps/opencs/model/tools/reportmodel.cpp @@ -68,4 +68,4 @@ void CSMTools::ReportModel::add (const std::string& row) const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) const { return mRows.at (row).first; -} \ No newline at end of file +} diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index bca9f6fb7d..d8cbb2fc11 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -76,7 +76,7 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() mVerifier->appendStage (new SpellCheckStage (mData.getSpells())); - mVerifier->appendStage( new ReferenceableCheckStage (mData.getReferenceables().getDataSet())); + mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet())); } return mVerifier; From 955fe3e8cf627977477542e96c25199c1844b3ec Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 22 Dec 2013 10:00:04 +0100 Subject: [PATCH 010/168] Added check for non-positive quality of alchemical apparatus --- apps/opencs/model/tools/referenceablecheck.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index e86e8db545..da63dce9fe 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -29,7 +29,6 @@ void CSMTools::ReferenceableCheckStage::setSizeVariables() void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. - if (stage < mBooksSize) { bookCheck(stage, mReferencables.getBooks(), messages); @@ -222,4 +221,10 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(int stage, const CSMWorld { messages.push_back(id.toString() + "|" + Apparatus.mId + " has no icon"); } + + //checking for quality, 0 → apparatus is basicly useless, any negative → apparatus is harmfull instead of helpfull + if (Apparatus.mData.mQuality <= 0) + { + messages.push_back(id.toString() + "|" + Apparatus.mId + " has non-positive quality"); + } } From 97fc8acbdb207cdfb301df7c1f32a52aa04e840d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 22 Dec 2013 14:22:03 +0100 Subject: [PATCH 011/168] Added armor check --- .../opencs/model/tools/referenceablecheck.cpp | 90 +++++++++++++++++-- .../opencs/model/tools/referenceablecheck.hpp | 2 + apps/opencs/model/world/refiddata.cpp | 5 ++ apps/opencs/model/world/refiddata.hpp | 1 + 4 files changed, 89 insertions(+), 9 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index da63dce9fe..b6c99960de 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -13,7 +13,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mBooksSize(0), mActivatorsSize(0), mPotionsSize(0), - mApparatiSize(0) + mApparatiSize(0), + mArmorsSzie(0) { setSizeVariables(); } @@ -24,6 +25,7 @@ void CSMTools::ReferenceableCheckStage::setSizeVariables() mActivatorsSize = mReferencables.getActivators().getSize(); mPotionsSize = mReferencables.getPotions().getSize(); mApparatiSize = mReferencables.getApparati().getSize(); + mArmorsSzie = mReferencables.getArmors().getSize(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) @@ -52,14 +54,22 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mPotionsSize; - + if (stage < mApparatiSize) { - apparatusCheck(stage, mReferencables.getApparati(), messages); - return; + apparatusCheck(stage, mReferencables.getApparati(), messages); + return; + } + + stage -= mApparatiSize; + + if (stage < mArmorsSzie) + { + armorCheck(stage, mReferencables.getArmors(), messages); + return; } - stage -= mApparatiSize; + stage -= mArmorsSzie; } int CSMTools::ReferenceableCheckStage::setup() @@ -108,11 +118,11 @@ void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::Ref { messages.push_back(id.toString() + "|" + Book.mId + " has no icon"); } - + //checking for enchantment points if (Book.mData.mEnchant < 0) { - messages.push_back(id.toString() + "|" + Book.mId + " has negative enchantment"); + messages.push_back(id.toString() + "|" + Book.mId + " has negative enchantment"); } } @@ -176,6 +186,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck(int stage, const CSMWorld::R { messages.push_back(id.toString() + "|" + Potion.mId + " has no icon"); } + //IIRC potion can have empty effects list just fine. } @@ -221,10 +232,71 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(int stage, const CSMWorld { messages.push_back(id.toString() + "|" + Apparatus.mId + " has no icon"); } - + //checking for quality, 0 → apparatus is basicly useless, any negative → apparatus is harmfull instead of helpfull if (Apparatus.mData.mQuality <= 0) { - messages.push_back(id.toString() + "|" + Apparatus.mId + " has non-positive quality"); + messages.push_back(id.toString() + "|" + Apparatus.mId + " has non-positive quality"); + } +} + +void CSMTools::ReferenceableCheckStage::armorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Armor >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Armor& Armor = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Armor, Armor.mId); + + //Checking for name + if (Armor.mName.empty()) + { + messages.push_back(id.toString() + "|" + Armor.mId + " has an empty name"); + } + + //Checking for weight + if (Armor.mData.mWeight < 0) + { + messages.push_back(id.toString() + "|" + Armor.mId + " has negative weight"); + } + + //Checking for value + if (Armor.mData.mValue < 0) + { + messages.push_back(id.toString() + "|" + Armor.mId + " has negative value"); + } + +//checking for model + if (Armor.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Armor.mId + " has no model"); + } + + //checking for icon + if (Armor.mIcon.empty()) + { + messages.push_back(id.toString() + "|" + Armor.mId + " has no icon"); + } + + //checking for enchantment points + if (Armor.mData.mEnchant < 0) + { + messages.push_back(id.toString() + "|" + Armor.mId + " has negative enchantment"); + } + + //checking for armor class, armor should have poistive armor class, but 0 is considered legal + if (Armor.mData.mArmor < 0) + { + messages.push_back(id.toString() + "|" + Armor.mId + " has negative armor class"); + } + + //checking for health. Only positive numbers are allowed, and 0 is illegal + if (Armor.mData.mHealth <= 0) + { + messages.push_back(id.toString() + "|" + Armor.mId + " has non positive health"); } } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index a40ca16a42..7e5b761afd 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -21,6 +21,7 @@ namespace CSMTools void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages); void potionCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void armorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void setSizeVariables(); @@ -31,6 +32,7 @@ namespace CSMTools int mActivatorsSize; int mPotionsSize; int mApparatiSize; + int mArmorsSzie; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 6f278cc024..98a81c7841 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -251,3 +251,8 @@ const CSMWorld::RefIdDataContainer< ESM::Apparatus >& CSMWorld::RefIdData::getAp { return mApparati; } + +const CSMWorld::RefIdDataContainer< ESM::Armor >& CSMWorld::RefIdData::getArmors() const +{ + return mArmors; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index b32b0347a3..f03da95884 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -225,6 +225,7 @@ namespace CSMWorld const RefIdDataContainer& getActivators() const; const RefIdDataContainer& getPotions() const; const RefIdDataContainer& getApparati() const; + const RefIdDataContainer& getArmors() const; }; } From bbcaef8e42be9decd6d082fd3981e1b4e2da6b27 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 22 Dec 2013 14:32:42 +0100 Subject: [PATCH 012/168] Added armor check and related stuff. --- .../opencs/model/tools/referenceablecheck.cpp | 75 +++++++++++++++++-- .../opencs/model/tools/referenceablecheck.hpp | 2 + apps/opencs/model/world/refiddata.cpp | 5 ++ apps/opencs/model/world/refiddata.hpp | 1 + 4 files changed, 75 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index b6c99960de..8f871fca2b 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -14,7 +14,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mActivatorsSize(0), mPotionsSize(0), mApparatiSize(0), - mArmorsSzie(0) + mArmorsSzie(0), + mClothingSize(0) { setSizeVariables(); } @@ -26,6 +27,7 @@ void CSMTools::ReferenceableCheckStage::setSizeVariables() mPotionsSize = mReferencables.getPotions().getSize(); mApparatiSize = mReferencables.getApparati().getSize(); mArmorsSzie = mReferencables.getArmors().getSize(); + mClothingSize = mReferencables.getClothing().getSize(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) @@ -68,8 +70,16 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str armorCheck(stage, mReferencables.getArmors(), messages); return; } - + stage -= mArmorsSzie; + + if (stage < mClothingSize) + { + clothingCheck(stage, mReferencables.getClothing(), messages); + return; + } + + stage -= mClothingSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -281,22 +291,71 @@ void CSMTools::ReferenceableCheckStage::armorCheck(int stage, const CSMWorld::Re { messages.push_back(id.toString() + "|" + Armor.mId + " has no icon"); } - - //checking for enchantment points + + //checking for enchantment points if (Armor.mData.mEnchant < 0) { messages.push_back(id.toString() + "|" + Armor.mId + " has negative enchantment"); } - + //checking for armor class, armor should have poistive armor class, but 0 is considered legal if (Armor.mData.mArmor < 0) { - messages.push_back(id.toString() + "|" + Armor.mId + " has negative armor class"); + messages.push_back(id.toString() + "|" + Armor.mId + " has negative armor class"); } - + //checking for health. Only positive numbers are allowed, and 0 is illegal if (Armor.mData.mHealth <= 0) { - messages.push_back(id.toString() + "|" + Armor.mId + " has non positive health"); + messages.push_back(id.toString() + "|" + Armor.mId + " has non positive health"); + } +} + +void CSMTools::ReferenceableCheckStage::clothingCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Clothing >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Clothing& Clothing = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, Clothing.mId); + + //Checking for name + if (Clothing.mName.empty()) + { + messages.push_back(id.toString() + "|" + Clothing.mId + " has an empty name"); + } + + //Checking for weight + if (Clothing.mData.mWeight < 0) + { + messages.push_back(id.toString() + "|" + Clothing.mId + " has negative weight"); + } + + //Checking for value + if (Clothing.mData.mValue < 0) + { + messages.push_back(id.toString() + "|" + Clothing.mId + " has negative value"); + } + +//checking for model + if (Clothing.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Clothing.mId + " has no model"); + } + + //checking for icon + if (Clothing.mIcon.empty()) + { + messages.push_back(id.toString() + "|" + Clothing.mId + " has no icon"); + } + + //checking for enchantment points + if (Clothing.mData.mEnchant < 0) + { + messages.push_back(id.toString() + "|" + Clothing.mId + " has negative enchantment"); } } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 7e5b761afd..a4146c4d24 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -22,6 +22,7 @@ namespace CSMTools void potionCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void armorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void clothingCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void setSizeVariables(); @@ -33,6 +34,7 @@ namespace CSMTools int mPotionsSize; int mApparatiSize; int mArmorsSzie; + int mClothingSize; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 98a81c7841..28cf28565f 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -256,3 +256,8 @@ const CSMWorld::RefIdDataContainer< ESM::Armor >& CSMWorld::RefIdData::getArmors { return mArmors; } + +const CSMWorld::RefIdDataContainer< ESM::Clothing >& CSMWorld::RefIdData::getClothing() const +{ + return mClothing; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index f03da95884..237c2f30bd 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -226,6 +226,7 @@ namespace CSMWorld const RefIdDataContainer& getPotions() const; const RefIdDataContainer& getApparati() const; const RefIdDataContainer& getArmors() const; + const RefIdDataContainer& getClothing() const; }; } From dc594da0ded4049c2d84e93c33f827c5894624a4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 22 Dec 2013 14:34:29 +0100 Subject: [PATCH 013/168] added getContainers --- apps/opencs/model/world/refiddata.cpp | 5 +++++ apps/opencs/model/world/refiddata.hpp | 1 + 2 files changed, 6 insertions(+) diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 28cf28565f..0a93d93ec4 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -261,3 +261,8 @@ const CSMWorld::RefIdDataContainer< ESM::Clothing >& CSMWorld::RefIdData::getClo { return mClothing; } + +const CSMWorld::RefIdDataContainer< ESM::Container >& CSMWorld::RefIdData::getContainers() const +{ + return mContainers; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 237c2f30bd..2f6ea187ea 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -227,6 +227,7 @@ namespace CSMWorld const RefIdDataContainer& getApparati() const; const RefIdDataContainer& getArmors() const; const RefIdDataContainer& getClothing() const; + const RefIdDataContainer& getContainers() const; }; } From 1a7f023237b8210b257dd2a1d0cc14bc091af7b4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 22 Dec 2013 14:35:40 +0100 Subject: [PATCH 014/168] added mContainersSize. --- apps/opencs/model/tools/referenceablecheck.cpp | 4 +++- apps/opencs/model/tools/referenceablecheck.hpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 8f871fca2b..055244cab4 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -15,7 +15,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mPotionsSize(0), mApparatiSize(0), mArmorsSzie(0), - mClothingSize(0) + mClothingSize(0), + mContainersSize(0) { setSizeVariables(); } @@ -28,6 +29,7 @@ void CSMTools::ReferenceableCheckStage::setSizeVariables() mApparatiSize = mReferencables.getApparati().getSize(); mArmorsSzie = mReferencables.getArmors().getSize(); mClothingSize = mReferencables.getClothing().getSize(); + mContainersSize = mReferencables.getContainers().getSize(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index a4146c4d24..1c88c8cfe7 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -35,6 +35,7 @@ namespace CSMTools int mApparatiSize; int mArmorsSzie; int mClothingSize; + int mContainersSize; }; } #endif // REFERENCEABLECHECKSTAGE_H From 16af9e69865632a88036ab32c70e6a6e3387ce40 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 22 Dec 2013 14:42:17 +0100 Subject: [PATCH 015/168] added container check --- .../opencs/model/tools/referenceablecheck.cpp | 39 +++++++++++++++++++ .../opencs/model/tools/referenceablecheck.hpp | 1 + 2 files changed, 40 insertions(+) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 055244cab4..f08aadf860 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -82,6 +82,14 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mClothingSize; + + if (stage < mContainersSize) + { + containerCheck(stage, mReferencables.getContainers(), messages); + return; + } + + stage -= mContainersSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -361,3 +369,34 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(int stage, const CSMWorld: messages.push_back(id.toString() + "|" + Clothing.mId + " has negative enchantment"); } } + +void CSMTools::ReferenceableCheckStage::containerCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Container >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Container& Container = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, Container.mId); + + //Checking for model, IIRC all containers should have a model + if (Container.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Container.mId + " has no model"); + } + + //Checking for capacity (weight) + if (Container.mWeight < 0) //0 is allowed + { + messages.push_back(id.toString() + "|" + Container.mId + " has negative weight (capacity)"); + } + + //checking for name + if (Container.mName.empty()) + { + messages.push_back(id.toString() + "|" + Container.mId + " has an empty name"); + } +} diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 1c88c8cfe7..b55db38c6d 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -23,6 +23,7 @@ namespace CSMTools void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void armorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void clothingCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void containerCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void setSizeVariables(); From 32046070d54d8231681c0e4b6efb1985c3ac6ba8 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 22 Dec 2013 14:44:22 +0100 Subject: [PATCH 016/168] Added getCreatures --- apps/opencs/model/world/refiddata.cpp | 5 +++++ apps/opencs/model/world/refiddata.hpp | 1 + 2 files changed, 6 insertions(+) diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 0a93d93ec4..266741155d 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -266,3 +266,8 @@ const CSMWorld::RefIdDataContainer< ESM::Container >& CSMWorld::RefIdData::getCo { return mContainers; } + +const CSMWorld::RefIdDataContainer< ESM::Creature >& CSMWorld::RefIdData::getCreatures() const +{ + return mCreatures; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 2f6ea187ea..6af433be26 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -228,6 +228,7 @@ namespace CSMWorld const RefIdDataContainer& getArmors() const; const RefIdDataContainer& getClothing() const; const RefIdDataContainer& getContainers() const; + const RefIdDataContainer& getCreatures() const; }; } From 94fcea4d4df7cea66629fefdea5b368269697e97 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 22 Dec 2013 14:46:07 +0100 Subject: [PATCH 017/168] added mCreaturesSize --- apps/opencs/model/tools/referenceablecheck.cpp | 4 +++- apps/opencs/model/tools/referenceablecheck.hpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index f08aadf860..750ef64487 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -16,7 +16,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mApparatiSize(0), mArmorsSzie(0), mClothingSize(0), - mContainersSize(0) + mContainersSize(0), + mCreaturesSize(0) { setSizeVariables(); } @@ -30,6 +31,7 @@ void CSMTools::ReferenceableCheckStage::setSizeVariables() mArmorsSzie = mReferencables.getArmors().getSize(); mClothingSize = mReferencables.getClothing().getSize(); mContainersSize = mReferencables.getContainers().getSize(); + mCreaturesSize = mReferencables.getCreatures().getSize(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index b55db38c6d..17897fe34a 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -37,6 +37,7 @@ namespace CSMTools int mArmorsSzie; int mClothingSize; int mContainersSize; + int mCreaturesSize; }; } #endif // REFERENCEABLECHECKSTAGE_H From e4e7d5062369570077172f1545c37e0c026253f7 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 23 Dec 2013 12:32:35 +0100 Subject: [PATCH 018/168] Added creatureCheck. I don't know meaning of all data fields here. --- .../opencs/model/tools/referenceablecheck.cpp | 104 +++++++++++++++++- .../opencs/model/tools/referenceablecheck.hpp | 1 + components/esm/loadcrea.hpp | 2 +- 3 files changed, 102 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 750ef64487..c8a310e9f3 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -84,13 +84,13 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mClothingSize; - + if (stage < mContainersSize) { - containerCheck(stage, mReferencables.getContainers(), messages); - return; + containerCheck(stage, mReferencables.getContainers(), messages); + return; } - + stage -= mContainersSize; } @@ -402,3 +402,99 @@ void CSMTools::ReferenceableCheckStage::containerCheck(int stage, const CSMWorld messages.push_back(id.toString() + "|" + Container.mId + " has an empty name"); } } + +void CSMTools::ReferenceableCheckStage::creatureCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Creature >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Creature& Creature = (static_cast&>(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Creature, Creature.mId); + + if (Creature.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has no model"); + } + + if (Creature.mName.empty()) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has an empty name"); + } + + //stats checks + if (Creature.mData.mLevel < 1) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has non-postive level"); + } + + if (Creature.mData.mStrength < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative strength"); + } + + if (Creature.mData.mIntelligence < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative intelligence"); + } + + if (Creature.mData.mWillpower < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative willpower"); + } + + if (Creature.mData.mAgility < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative agility"); + } + + if (Creature.mData.mSpeed < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative speed"); + } + + if (Creature.mData.mEndurance < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative endurance"); + } + + if (Creature.mData.mPersonality < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative personality"); + } + + if (Creature.mData.mLuck < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative luck"); + } + + if (Creature.mData.mHealth < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative health"); + } + + if (Creature.mData.mSoul < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative soul value"); + } + + for (int i = 0; i < 6; ++i) + { + if (Creature.mData.mAttack[i] < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative attack strength"); + break; + } + } + + //TODO, find meaning of other values + /* + if (Creature.mData.mGold < 0) + { + messages.push_back(id.toString() + "|" + Creature.mId + " has negative gold "); + } + */ +} diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 17897fe34a..72af4e0ff7 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -24,6 +24,7 @@ namespace CSMTools void armorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void clothingCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void containerCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void creatureCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void setSizeVariables(); diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index 99c4f52257..a39a7ebe13 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -66,7 +66,7 @@ struct Creature int mCombat, mMagic, mStealth; // Don't know yet. int mAttack[6]; // AttackMin1, AttackMax1, ditto2, ditto3 int mGold; - }; // 96 bytes + }; // 96 byte NPDTstruct mData; From c1715779fa626c2d28a944019c14df690128b22f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 26 Dec 2013 12:59:43 +0100 Subject: [PATCH 019/168] Added door check with related methods. --- .../opencs/model/tools/referenceablecheck.cpp | 40 +++++++++++++++++-- .../opencs/model/tools/referenceablecheck.hpp | 2 + apps/opencs/model/world/refiddata.cpp | 6 +++ apps/opencs/model/world/refiddata.hpp | 1 + 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index c8a310e9f3..03efb59cc5 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -17,7 +17,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mArmorsSzie(0), mClothingSize(0), mContainersSize(0), - mCreaturesSize(0) + mCreaturesSize(0), + mDoorsSize(0) { setSizeVariables(); } @@ -32,6 +33,7 @@ void CSMTools::ReferenceableCheckStage::setSizeVariables() mClothingSize = mReferencables.getClothing().getSize(); mContainersSize = mReferencables.getContainers().getSize(); mCreaturesSize = mReferencables.getCreatures().getSize(); + mDoorsSize = mReferencables.getDoors().getSize(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) @@ -92,6 +94,14 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mContainersSize; + + if (stage < mDoorsSize) + { + doorCheck(stage, mReferencables.getDoors(), messages); + return; + } + + stage -= mDoorsSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -491,10 +501,32 @@ void CSMTools::ReferenceableCheckStage::creatureCheck(int stage, const CSMWorld: } //TODO, find meaning of other values - /* - if (Creature.mData.mGold < 0) + if (Creature.mData.mGold < 0) //It seems that this is for gold in merchant creatures { messages.push_back(id.toString() + "|" + Creature.mId + " has negative gold "); } - */ +} + +void CSMTools::ReferenceableCheckStage::doorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Door >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Door& Door= (static_cast&>(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Door, Door.mId); + + //usual, name and model + if (Door.mName.empty()) + { + messages.push_back(id.toString() + "|" + Door.mId + " has an empty name"); + } + + if (Door.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Door.mId + " has no model"); + } } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 72af4e0ff7..3a0b2a4b8c 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -25,6 +25,7 @@ namespace CSMTools void clothingCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void containerCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void creatureCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void setSizeVariables(); @@ -39,6 +40,7 @@ namespace CSMTools int mClothingSize; int mContainersSize; int mCreaturesSize; + int mDoorsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 266741155d..83ff79cc8b 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -271,3 +271,9 @@ const CSMWorld::RefIdDataContainer< ESM::Creature >& CSMWorld::RefIdData::getCre { return mCreatures; } + +const CSMWorld::RefIdDataContainer< ESM::Door >& CSMWorld::RefIdData::getDoors() const +{ + return mDoors; +} + diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 6af433be26..87818c9c9e 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -229,6 +229,7 @@ namespace CSMWorld const RefIdDataContainer& getClothing() const; const RefIdDataContainer& getContainers() const; const RefIdDataContainer& getCreatures() const; + const RefIdDataContainer& getDoors() const; }; } From 6c95cea4c48c1e2dcde5819481715070b5289a65 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 26 Dec 2013 15:24:52 +0100 Subject: [PATCH 020/168] Added ingredient check --- .../opencs/model/tools/referenceablecheck.cpp | 61 ++++++++++++++++--- .../opencs/model/tools/referenceablecheck.hpp | 2 + apps/opencs/model/world/refiddata.cpp | 4 ++ apps/opencs/model/world/refiddata.hpp | 1 + 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 03efb59cc5..589372f8a2 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -18,7 +18,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mClothingSize(0), mContainersSize(0), mCreaturesSize(0), - mDoorsSize(0) + mDoorsSize(0), + mIngredientsSize(0) { setSizeVariables(); } @@ -34,6 +35,7 @@ void CSMTools::ReferenceableCheckStage::setSizeVariables() mContainersSize = mReferencables.getContainers().getSize(); mCreaturesSize = mReferencables.getCreatures().getSize(); mDoorsSize = mReferencables.getDoors().getSize(); + mIngredientsSize = mReferencables.getIngredients().getSize(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) @@ -94,13 +96,13 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mContainersSize; - + if (stage < mDoorsSize) { - doorCheck(stage, mReferencables.getDoors(), messages); - return; + doorCheck(stage, mReferencables.getDoors(), messages); + return; } - + stage -= mDoorsSize; } @@ -516,9 +518,9 @@ void CSMTools::ReferenceableCheckStage::doorCheck(int stage, const CSMWorld::Ref return; } - const ESM::Door& Door= (static_cast&>(baserecord)).get(); + const ESM::Door& Door = (static_cast&>(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Door, Door.mId); - + //usual, name and model if (Door.mName.empty()) { @@ -529,4 +531,49 @@ void CSMTools::ReferenceableCheckStage::doorCheck(int stage, const CSMWorld::Ref { messages.push_back(id.toString() + "|" + Door.mId + " has no model"); } + + //TODO, check what static unsigned int sRecordId; is for +} + +void CSMTools::ReferenceableCheckStage::ingredientCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Ingredient& Ingredient = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Ingredient, Ingredient.mId); + + //Checking for name + if (Ingredient.mName.empty()) + { + messages.push_back(id.toString() + "|" + Ingredient.mId + " has an empty name"); + } + + //Checking for weight + if (Ingredient.mData.mWeight < 0) + { + messages.push_back(id.toString() + "|" + Ingredient.mId + " has negative weight"); + } + + //Checking for value + if (Ingredient.mData.mValue < 0) + { + messages.push_back(id.toString() + "|" + Ingredient.mId + " has negative value"); + } + +//checking for model + if (Ingredient.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Ingredient.mId + " has no model"); + } + + //checking for icon + if (Ingredient.mIcon.empty()) + { + messages.push_back(id.toString() + "|" + Ingredient.mId + " has no icon"); + } } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 3a0b2a4b8c..c7c418ff64 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -26,6 +26,7 @@ namespace CSMTools void containerCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void creatureCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void setSizeVariables(); @@ -41,6 +42,7 @@ namespace CSMTools int mContainersSize; int mCreaturesSize; int mDoorsSize; + int mIngredientsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 83ff79cc8b..8af42703ec 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -277,3 +277,7 @@ const CSMWorld::RefIdDataContainer< ESM::Door >& CSMWorld::RefIdData::getDoors() return mDoors; } +const CSMWorld::RefIdDataContainer< ESM::Ingredient >& CSMWorld::RefIdData::getIngredients() const +{ + return mIngredients; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 87818c9c9e..6a67ed1c83 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -230,6 +230,7 @@ namespace CSMWorld const RefIdDataContainer& getContainers() const; const RefIdDataContainer& getCreatures() const; const RefIdDataContainer& getDoors() const; + const RefIdDataContainer& getIngredients() const; }; } From 360a939aa0f224c7870b1193f6916f75c0eb253e Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 26 Dec 2013 15:35:58 +0100 Subject: [PATCH 021/168] Working on leveled lists now. --- .../opencs/model/tools/referenceablecheck.cpp | 27 ++++++++++++++++++- .../opencs/model/tools/referenceablecheck.hpp | 2 ++ apps/opencs/model/world/refiddata.cpp | 5 ++++ apps/opencs/model/world/refiddata.hpp | 1 + 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 589372f8a2..12727d49c3 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -19,7 +19,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mContainersSize(0), mCreaturesSize(0), mDoorsSize(0), - mIngredientsSize(0) + mIngredientsSize(0), + mCreaturesLevListsSize(0) { setSizeVariables(); } @@ -36,6 +37,7 @@ void CSMTools::ReferenceableCheckStage::setSizeVariables() mCreaturesSize = mReferencables.getCreatures().getSize(); mDoorsSize = mReferencables.getDoors().getSize(); mIngredientsSize = mReferencables.getIngredients().getSize(); + mCreaturesLevListsSize = mReferencables.getCreatureLevelledLists().getSize(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) @@ -104,6 +106,14 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mDoorsSize; + + if (stage < mIngredientsSize) + { + ingredientCheck(stage, mReferencables.getIngredients(), messages); + return; + } + + stage -= mIngredientsSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -577,3 +587,18 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(int stage, const CSMWorl messages.push_back(id.toString() + "|" + Ingredient.mId + " has no icon"); } } + +void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::CreatureLevList& CreatureLevList = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevList, CreatureLevList.mId); + + //TODO(!) +} \ No newline at end of file diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index c7c418ff64..8fd123b062 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -27,6 +27,7 @@ namespace CSMTools void creatureCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void setSizeVariables(); @@ -43,6 +44,7 @@ namespace CSMTools int mCreaturesSize; int mDoorsSize; int mIngredientsSize; + int mCreaturesLevListsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 8af42703ec..aec20b1887 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -281,3 +281,8 @@ const CSMWorld::RefIdDataContainer< ESM::Ingredient >& CSMWorld::RefIdData::getI { return mIngredients; } + +const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& CSMWorld::RefIdData::getCreatureLevelledLists() const +{ + return mCreatureLevelledLists; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 6a67ed1c83..02ca539536 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -231,6 +231,7 @@ namespace CSMWorld const RefIdDataContainer& getCreatures() const; const RefIdDataContainer& getDoors() const; const RefIdDataContainer& getIngredients() const; + const RefIdDataContainer& getCreatureLevelledLists() const; }; } From c2993909cf0efce9850557d6b9519cefe0c533a0 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 26 Dec 2013 18:16:54 +0100 Subject: [PATCH 022/168] added creature leveled list check --- .../opencs/model/tools/referenceablecheck.cpp | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 12727d49c3..0abebc7097 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -106,14 +106,22 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mDoorsSize; - + if (stage < mIngredientsSize) { - ingredientCheck(stage, mReferencables.getIngredients(), messages); - return; + ingredientCheck(stage, mReferencables.getIngredients(), messages); + return; } - + stage -= mIngredientsSize; + + if (stage < mCreaturesLevListsSize) + { + creaturesLevListCheck(stage, mReferencables.getCreatureLevelledLists(), messages); + return; + } + + stage -= mCreaturesLevListsSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -590,7 +598,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(int stage, const CSMWorl void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); if (baserecord.isDeleted()) { @@ -598,7 +606,25 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const C } const ESM::CreatureLevList& CreatureLevList = (static_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevList, CreatureLevList.mId); - + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, CreatureLevList.mId); //CreatureLevList but Type_CreatureLevelledList :/ + + for (int i = 0; i < CreatureLevList.mList.size(); ++i) + { + if (CreatureLevList.mList[i].mId.empty()) + { + messages.push_back(id.toString() + "|" + CreatureLevList.mId + " contains item with empty Id"); + } + + if (CreatureLevList.mList[i].mLevel < 1) + { + messages.push_back(id.toString() + "|" + CreatureLevList.mId + " contains item with non-positive level"); + } + } + + if (CreatureLevList.mChanceNone < 0 or CreatureLevList.mChanceNone > 100) + { + messages.push_back(id.toString() + "|" + CreatureLevList.mId + " chance to be empty is not beetween 0 and 100"); + } + //TODO(!) -} \ No newline at end of file +} From 1da56e1790f084d267f802e32a746d4f61c1f2a7 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 26 Dec 2013 18:28:24 +0100 Subject: [PATCH 023/168] checkin leveled items lists --- .../opencs/model/tools/referenceablecheck.cpp | 45 +++++++++++++++++-- .../opencs/model/tools/referenceablecheck.hpp | 2 + apps/opencs/model/world/refiddata.cpp | 5 +++ apps/opencs/model/world/refiddata.hpp | 1 + 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 0abebc7097..e2091de2e2 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -20,7 +20,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mCreaturesSize(0), mDoorsSize(0), mIngredientsSize(0), - mCreaturesLevListsSize(0) + mCreaturesLevListsSize(0), + mItemLevelledListsSize(0) { setSizeVariables(); } @@ -38,6 +39,7 @@ void CSMTools::ReferenceableCheckStage::setSizeVariables() mDoorsSize = mReferencables.getDoors().getSize(); mIngredientsSize = mReferencables.getIngredients().getSize(); mCreaturesLevListsSize = mReferencables.getCreatureLevelledLists().getSize(); + mItemLevelledListsSize = mReferencables.getItemLevelledList().getSize(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) @@ -122,6 +124,14 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mCreaturesLevListsSize; + + if (stage < mItemLevelledListsSize) + { + mItemLevelledListCheck(stage, mReferencables.getItemLevelledList(), messages); + return; + } + + stage -= mItemLevelledListsSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -625,6 +635,35 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const C { messages.push_back(id.toString() + "|" + CreatureLevList.mId + " chance to be empty is not beetween 0 and 100"); } - - //TODO(!) +} + +void CSMTools::ReferenceableCheckStage::mItemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::ItemLevList& ItemLevList = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, CreatureLevList.mId); + + for (int i = 0; i < ItemLevList.mList.size(); ++i) + { + if (ItemLevList.mList[i].mId.empty()) + { + messages.push_back(id.toString() + "|" + ItemLevList.mId + " contains item with empty Id"); + } + + if (ItemLevList.mList[i].mLevel < 1) + { + messages.push_back(id.toString() + "|" + ItemLevList.mId + " contains item with non-positive level"); + } + } + + if (ItemLevList.mChanceNone < 0 or ItemLevList.mChanceNone > 100) + { + messages.push_back(id.toString() + "|" + ItemLevList.mId + " chance to be empty is not beetween 0 and 100"); + } } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 8fd123b062..5a0d39ec58 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -28,6 +28,7 @@ namespace CSMTools void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void mItemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void setSizeVariables(); @@ -45,6 +46,7 @@ namespace CSMTools int mDoorsSize; int mIngredientsSize; int mCreaturesLevListsSize; + int mItemLevelledListsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index aec20b1887..7f3e6506b6 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -286,3 +286,8 @@ const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& CSMWorld::RefIdData: { return mCreatureLevelledLists; } + +const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& CSMWorld::RefIdData::getItemLevelledList() const +{ + return mItemLevelledLists; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 02ca539536..6e7231a246 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -232,6 +232,7 @@ namespace CSMWorld const RefIdDataContainer& getDoors() const; const RefIdDataContainer& getIngredients() const; const RefIdDataContainer& getCreatureLevelledLists() const; + const RefIdDataContainer& getItemLevelledList() const; }; } From f04a727af67cd8bb1240f201a42fbb68837a7160 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 26 Dec 2013 18:40:47 +0100 Subject: [PATCH 024/168] removed set sizes, consted sizes, added itemleveledlist check --- .../opencs/model/tools/referenceablecheck.cpp | 52 +++++++------------ .../opencs/model/tools/referenceablecheck.hpp | 27 +++++----- apps/opencs/model/world/refiddata.cpp | 5 ++ apps/opencs/model/world/refiddata.hpp | 1 + 4 files changed, 37 insertions(+), 48 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index e2091de2e2..d37808810e 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -10,36 +10,20 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable) : mReferencables(referenceable), - mBooksSize(0), - mActivatorsSize(0), - mPotionsSize(0), - mApparatiSize(0), - mArmorsSzie(0), - mClothingSize(0), - mContainersSize(0), - mCreaturesSize(0), - mDoorsSize(0), - mIngredientsSize(0), - mCreaturesLevListsSize(0), - mItemLevelledListsSize(0) + mBooksSize(mReferencables.getBooks().getSize()), + mActivatorsSize(mReferencables.getActivators().getSize()), + mPotionsSize(mReferencables.getPotions().getSize()), + mApparatiSize(mReferencables.getApparati().getSize()), + mArmorsSzie(mReferencables.getArmors().getSize()), + mClothingSize(mReferencables.getClothing().getSize()), + mContainersSize(mReferencables.getContainers().getSize()), + mCreaturesSize(mReferencables.getCreatures().getSize()), + mDoorsSize(mReferencables.getDoors().getSize()), + mIngredientsSize(mReferencables.getIngredients().getSize()), + mCreaturesLevListsSize(mReferencables.getCreatureLevelledLists().getSize()), + mItemLevelledListsSize(mReferencables.getItemLevelledList().getSize()), + mLightsSize(mReferencables.getLights().getSize()) { - setSizeVariables(); -} - -void CSMTools::ReferenceableCheckStage::setSizeVariables() -{ - mBooksSize = mReferencables.getBooks().getSize(); - mActivatorsSize = mReferencables.getActivators().getSize(); - mPotionsSize = mReferencables.getPotions().getSize(); - mApparatiSize = mReferencables.getApparati().getSize(); - mArmorsSzie = mReferencables.getArmors().getSize(); - mClothingSize = mReferencables.getClothing().getSize(); - mContainersSize = mReferencables.getContainers().getSize(); - mCreaturesSize = mReferencables.getCreatures().getSize(); - mDoorsSize = mReferencables.getDoors().getSize(); - mIngredientsSize = mReferencables.getIngredients().getSize(); - mCreaturesLevListsSize = mReferencables.getCreatureLevelledLists().getSize(); - mItemLevelledListsSize = mReferencables.getItemLevelledList().getSize(); } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) @@ -124,13 +108,13 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mCreaturesLevListsSize; - + if (stage < mItemLevelledListsSize) { - mItemLevelledListCheck(stage, mReferencables.getItemLevelledList(), messages); - return; + mItemLevelledListCheck(stage, mReferencables.getItemLevelledList(), messages); + return; } - + stage -= mItemLevelledListsSize; } @@ -647,7 +631,7 @@ void CSMTools::ReferenceableCheckStage::mItemLevelledListCheck(int stage, const } const ESM::ItemLevList& ItemLevList = (static_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, CreatureLevList.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, ItemLevList.mId); for (int i = 0; i < ItemLevList.mList.size(); ++i) { diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 5a0d39ec58..6bffc2b255 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -30,23 +30,22 @@ namespace CSMTools void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void mItemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void setSizeVariables(); - const CSMWorld::RefIdData mReferencables; //SIZES OF CONCRETE TYPES - int mBooksSize; - int mActivatorsSize; - int mPotionsSize; - int mApparatiSize; - int mArmorsSzie; - int mClothingSize; - int mContainersSize; - int mCreaturesSize; - int mDoorsSize; - int mIngredientsSize; - int mCreaturesLevListsSize; - int mItemLevelledListsSize; + const int mBooksSize; + const int mActivatorsSize; + const int mPotionsSize; + const int mApparatiSize; + const int mArmorsSzie; + const int mClothingSize; + const int mContainersSize; + const int mCreaturesSize; + const int mDoorsSize; + const int mIngredientsSize; + const int mCreaturesLevListsSize; + const int mItemLevelledListsSize; + const int mLightsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 7f3e6506b6..54e2cd12f6 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -291,3 +291,8 @@ const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& CSMWorld::RefIdData::get { return mItemLevelledLists; } + +const CSMWorld::RefIdDataContainer< ESM::Light >& CSMWorld::RefIdData::getLights() const +{ + return mLights; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 6e7231a246..6b6e01e012 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -233,6 +233,7 @@ namespace CSMWorld const RefIdDataContainer& getIngredients() const; const RefIdDataContainer& getCreatureLevelledLists() const; const RefIdDataContainer& getItemLevelledList() const; + const RefIdDataContainer& getLights() const; }; } From 03235bf0a274b7dfd1e95a1a58f2662ffbbececc Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 27 Dec 2013 22:13:55 +0100 Subject: [PATCH 025/168] NPC. Still WIP. --- .../opencs/model/tools/referenceablecheck.cpp | 260 +++++++++++++++++- .../opencs/model/tools/referenceablecheck.hpp | 9 +- apps/opencs/model/world/refiddata.cpp | 229 ++++++++------- apps/opencs/model/world/refiddata.hpp | 4 + components/esm/loadnpc.hpp | 2 +- 5 files changed, 383 insertions(+), 121 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index d37808810e..6d06d61519 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "../world/record.hpp" @@ -22,7 +23,10 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefId mIngredientsSize(mReferencables.getIngredients().getSize()), mCreaturesLevListsSize(mReferencables.getCreatureLevelledLists().getSize()), mItemLevelledListsSize(mReferencables.getItemLevelledList().getSize()), - mLightsSize(mReferencables.getLights().getSize()) + mLightsSize(mReferencables.getLights().getSize()), + mLockpicksSize(mReferencables.getLocpicks().getSize()), + mMiscellaneousSize(mReferencables.getMiscellaneous().getSize()), + mNPCsSize(mReferencables.getNPCs().getSize()) { } @@ -111,11 +115,35 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str if (stage < mItemLevelledListsSize) { - mItemLevelledListCheck(stage, mReferencables.getItemLevelledList(), messages); + itemLevelledListCheck(stage, mReferencables.getItemLevelledList(), messages); return; } stage -= mItemLevelledListsSize; + + if (stage < mLightsSize) + { + lightCheck(stage, mReferencables.getLights(), messages); + return; + } + + stage -= mLightsSize; + + if (stage < mLockpicksSize) + { + lockpickCheck(stage, mReferencables.getLocpicks(), messages); + return; + } + + stage -= mLockpicksSize; + + if (stage < mMiscellaneousSize) + { + miscCheck(stage, mReferencables.getMiscellaneous(), messages); + return; + } + + stage -= mMiscellaneousSize; } int CSMTools::ReferenceableCheckStage::setup() @@ -602,7 +630,7 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const C const ESM::CreatureLevList& CreatureLevList = (static_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, CreatureLevList.mId); //CreatureLevList but Type_CreatureLevelledList :/ - for (int i = 0; i < CreatureLevList.mList.size(); ++i) + for (unsigned i = 0; i < CreatureLevList.mList.size(); ++i) { if (CreatureLevList.mList[i].mId.empty()) { @@ -614,14 +642,9 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const C messages.push_back(id.toString() + "|" + CreatureLevList.mId + " contains item with non-positive level"); } } - - if (CreatureLevList.mChanceNone < 0 or CreatureLevList.mChanceNone > 100) - { - messages.push_back(id.toString() + "|" + CreatureLevList.mId + " chance to be empty is not beetween 0 and 100"); - } } -void CSMTools::ReferenceableCheckStage::mItemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -633,7 +656,7 @@ void CSMTools::ReferenceableCheckStage::mItemLevelledListCheck(int stage, const const ESM::ItemLevList& ItemLevList = (static_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, ItemLevList.mId); - for (int i = 0; i < ItemLevList.mList.size(); ++i) + for (unsigned i = 0; i < ItemLevList.mList.size(); ++i) { if (ItemLevList.mList[i].mId.empty()) { @@ -645,9 +668,222 @@ void CSMTools::ReferenceableCheckStage::mItemLevelledListCheck(int stage, const messages.push_back(id.toString() + "|" + ItemLevList.mId + " contains item with non-positive level"); } } +} - if (ItemLevList.mChanceNone < 0 or ItemLevList.mChanceNone > 100) +void CSMTools::ReferenceableCheckStage::lightCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) { - messages.push_back(id.toString() + "|" + ItemLevList.mId + " chance to be empty is not beetween 0 and 100"); + return; + } + + const ESM::Light& Light = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Light, Light.mId); + + if (Light.mData.mRadius < 0) + { + messages.push_back(id.toString() + "|" + Light.mId + " has negative light radius"); + } + + if (Light.mData.mFlags & ESM::Light::Carry) + { + if (Light.mIcon.empty()) //Needs to be checked with carrable flag + { + messages.push_back(id.toString() + "|" + Light.mId + " has no icon"); + } + + if (Light.mData.mWeight < 0) //probabbly needs to be checked only for carrable lights TODO + { + messages.push_back(id.toString() + "|" + Light.mId + " has negative weight"); + } + + if (Light.mData.mValue < 0) //probabbly needs to be checked only for carrable lights TODO + { + messages.push_back(id.toString() + "|" + Light.mId + " has negative value"); + } + + if (Light.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Light.mId + " has no model"); + } + + if (Light.mData.mTime < 0) + { + messages.push_back(id.toString() + "|" + Light.mId + " has negative duration"); + } } } + +void CSMTools::ReferenceableCheckStage::lockpickCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Lockpick& Lockpick = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Lockpick, Lockpick.mId); + + //Checking for name + if (Lockpick.mName.empty()) + { + messages.push_back(id.toString() + "|" + Lockpick.mId + " has an empty name"); + } + + //Checking for weight + if (Lockpick.mData.mWeight < 0) + { + messages.push_back(id.toString() + "|" + Lockpick.mId + " has negative weight"); + } + + //Checking for value + if (Lockpick.mData.mValue < 0) + { + messages.push_back(id.toString() + "|" + Lockpick.mId + " has negative value"); + } + +//checking for model + if (Lockpick.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Lockpick.mId + " has no model"); + } + + //checking for icon + if (Lockpick.mIcon.empty()) + { + messages.push_back(id.toString() + "|" + Lockpick.mId + " has no icon"); + } + + if (Lockpick.mData.mQuality <= 0) + { + messages.push_back(id.toString() + "|" + Lockpick.mId + " has non-positive quality"); + } + + if (Lockpick.mData.mUses <= 0) + { + messages.push_back(id.toString() + "|" + Lockpick.mId + " has no uses left"); + } +} + +void CSMTools::ReferenceableCheckStage::miscCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Miscellaneous& Miscellaneous = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, Miscellaneous.mId); + + //Checking for name + if (Miscellaneous.mName.empty()) + { + messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has an empty name"); + } + + //Checking for weight + if (Miscellaneous.mData.mWeight < 0) + { + messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has negative weight"); + } + + //Checking for value + if (Miscellaneous.mData.mValue < 0) + { + messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has negative value"); + } + +//checking for model + if (Miscellaneous.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has no model"); + } + + //checking for icon + if (Miscellaneous.mIcon.empty()) + { + messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has no icon"); + } +} + +void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::NPC& NPC = (static_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc, NPC.mId); + + + + short level(NPC.mNpdt52.mLevel); + char Disposition(NPC.mNpdt52.mDisposition); + char Reputation(NPC.mNpdt52.mReputation); + char Rank(NPC.mNpdt52.mRank); + //Don't know what unknown is for + int Gold(NPC.mNpdt52.mGold); + + if (NPC.mNpdtType == 12) + { + if (NPC.mFlags ^ ESM::NPC::Flags::Autocalc) + { + messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType and flags mismatch!"); //should not happend? + return; + } + + level = NPC.mNpdt12.mLevel; + Disposition = NPC.mNpdt12.mDisposition; + Reputation = NPC.mNpdt12.mReputation; + Rank = NPC.mNpdt12.mRank; + Gold = NPC.mNpdt12.mGold; + } + else + { + if (NPC.mNpdt52.mHealth < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " health is negative value"); + } + + if (NPC.mNpdt52.mMana < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " mana is negative value"); + } + + if (NPC.mNpdt52.mFatigue < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " fatigue is negative value"); + } + } + + if (level < 1) + { + messages.push_back(id.toString() + "|" + NPC.mId + " level is non positive"); + } + + if (Gold < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " gold is negative value"); + } + + if (NPC.mName.empty()) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has any empty name"); + } + + if (NPC.mClass.empty()) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has any empty class"); + } + + //TODO: reputation, Disposition, rank, everything else +} diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 6bffc2b255..d4f7697aee 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -28,7 +28,11 @@ namespace CSMTools void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void mItemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void lightCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void miscCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); const CSMWorld::RefIdData mReferencables; @@ -46,6 +50,9 @@ namespace CSMTools const int mCreaturesLevListsSize; const int mItemLevelledListsSize; const int mLightsSize; + const int mLockpicksSize; + const int mMiscellaneousSize; + const int mNPCsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 54e2cd12f6..9c0a857a5b 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -9,187 +9,187 @@ CSMWorld::RefIdDataContainerBase::~RefIdDataContainerBase() {} CSMWorld::RefIdData::RefIdData() { - mRecordContainers.insert (std::make_pair (UniversalId::Type_Activator, &mActivators)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Potion, &mPotions)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Apparatus, &mApparati)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Armor, &mArmors)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Book, &mBooks)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Clothing, &mClothing)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Container, &mContainers)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Creature, &mCreatures)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Door, &mDoors)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Ingredient, &mIngredients)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, - &mCreatureLevelledLists)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_ItemLevelledList, &mItemLevelledLists)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Light, &mLights)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Lockpick, &mLockpicks)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Miscellaneous, &mMiscellaneous)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Npc, &mNpcs)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Probe, &mProbes)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Repair, &mRepairs)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Static, &mStatics)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Weapon, &mWeapons)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Activator, &mActivators)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Potion, &mPotions)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Apparatus, &mApparati)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Armor, &mArmors)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Book, &mBooks)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Clothing, &mClothing)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Container, &mContainers)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Creature, &mCreatures)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Door, &mDoors)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Ingredient, &mIngredients)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, + &mCreatureLevelledLists)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_ItemLevelledList, &mItemLevelledLists)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Light, &mLights)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Lockpick, &mLockpicks)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Miscellaneous, &mMiscellaneous)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Npc, &mNpcs)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Probe, &mProbes)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Repair, &mRepairs)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Static, &mStatics)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Weapon, &mWeapons)); } -CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::globalToLocalIndex (int index) const +CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::globalToLocalIndex(int index) const { - for (std::map::const_iterator iter ( - mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) + for (std::map::const_iterator iter( + mRecordContainers.begin()); iter != mRecordContainers.end(); ++iter) { - if (indexsecond->getSize()) - return LocalIndex (index, iter->first); + if (index < iter->second->getSize()) + return LocalIndex(index, iter->first); index -= iter->second->getSize(); } - throw std::runtime_error ("RefIdData index out of range"); + throw std::runtime_error("RefIdData index out of range"); } -int CSMWorld::RefIdData::localToGlobalIndex (const LocalIndex& index) - const +int CSMWorld::RefIdData::localToGlobalIndex(const LocalIndex& index) +const { - std::map::const_iterator end = - mRecordContainers.find (index.second); + std::map::const_iterator end = + mRecordContainers.find(index.second); - if (end==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (end == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); int globalIndex = index.first; - for (std::map::const_iterator iter ( - mRecordContainers.begin()); iter!=end; ++iter) + for (std::map::const_iterator iter( + mRecordContainers.begin()); iter != end; ++iter) globalIndex += iter->second->getSize(); return globalIndex; } -CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId ( +CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId( const std::string& id) const { - std::string id2 = Misc::StringUtils::lowerCase (id); + std::string id2 = Misc::StringUtils::lowerCase(id); - std::map >::const_iterator iter = mIndex.find (id2); + std::map >::const_iterator iter = mIndex.find(id2); - if (iter==mIndex.end()) - return std::make_pair (-1, CSMWorld::UniversalId::Type_None); + if (iter == mIndex.end()) + return std::make_pair(-1, CSMWorld::UniversalId::Type_None); return iter->second; } -void CSMWorld::RefIdData::erase (int index, int count) +void CSMWorld::RefIdData::erase(int index, int count) { - LocalIndex localIndex = globalToLocalIndex (index); + LocalIndex localIndex = globalToLocalIndex(index); - std::map::const_iterator iter = - mRecordContainers.find (localIndex.second); + std::map::const_iterator iter = + mRecordContainers.find(localIndex.second); - while (count>0 && iter!=mRecordContainers.end()) + while (count > 0 && iter != mRecordContainers.end()) { int size = iter->second->getSize(); - if (localIndex.first+count>size) + if (localIndex.first + count > size) { - erase (localIndex, size-localIndex.first); - count -= size-localIndex.first; + erase(localIndex, size - localIndex.first); + count -= size - localIndex.first; ++iter; - if (iter==mRecordContainers.end()) - throw std::runtime_error ("invalid count value for erase operation"); + if (iter == mRecordContainers.end()) + throw std::runtime_error("invalid count value for erase operation"); localIndex.first = 0; localIndex.second = iter->first; } else { - erase (localIndex, count); + erase(localIndex, count); count = 0; } } } -const CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) const +const CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord(const LocalIndex& index) const { - std::map::const_iterator iter = - mRecordContainers.find (index.second); + std::map::const_iterator iter = + mRecordContainers.find(index.second); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - return iter->second->getRecord (index.first); + return iter->second->getRecord(index.first); } -CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) +CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord(const LocalIndex& index) { - std::map::iterator iter = - mRecordContainers.find (index.second); + std::map::iterator iter = + mRecordContainers.find(index.second); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - return iter->second->getRecord (index.first); + return iter->second->getRecord(index.first); } -void CSMWorld::RefIdData::appendRecord (UniversalId::Type type, const std::string& id) +void CSMWorld::RefIdData::appendRecord(UniversalId::Type type, const std::string& id) { - std::map::iterator iter = - mRecordContainers.find (type); + std::map::iterator iter = + mRecordContainers.find(type); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - iter->second->appendRecord (id); + iter->second->appendRecord(id); - mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id), - LocalIndex (iter->second->getSize()-1, type))); + mIndex.insert(std::make_pair(Misc::StringUtils::lowerCase(id), + LocalIndex(iter->second->getSize() - 1, type))); } -int CSMWorld::RefIdData::getAppendIndex (UniversalId::Type type) const +int CSMWorld::RefIdData::getAppendIndex(UniversalId::Type type) const { int index = 0; - for (std::map::const_iterator iter ( - mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) + for (std::map::const_iterator iter( + mRecordContainers.begin()); iter != mRecordContainers.end(); ++iter) { index += iter->second->getSize(); - if (type==iter->first) + if (type == iter->first) break; } return index; } -void CSMWorld::RefIdData::load (const LocalIndex& index, ESM::ESMReader& reader, bool base) +void CSMWorld::RefIdData::load(const LocalIndex& index, ESM::ESMReader& reader, bool base) { - std::map::iterator iter = - mRecordContainers.find (index.second); + std::map::iterator iter = + mRecordContainers.find(index.second); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - iter->second->load (index.first, reader, base); + iter->second->load(index.first, reader, base); } -void CSMWorld::RefIdData::erase (const LocalIndex& index, int count) +void CSMWorld::RefIdData::erase(const LocalIndex& index, int count) { - std::map::iterator iter = - mRecordContainers.find (index.second); + std::map::iterator iter = + mRecordContainers.find(index.second); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - for (int i=index.first; i::iterator result = - mIndex.find (Misc::StringUtils::lowerCase (iter->second->getId (i))); + mIndex.find(Misc::StringUtils::lowerCase(iter->second->getId(i))); - if (result!=mIndex.end()) - mIndex.erase (result); + if (result != mIndex.end()) + mIndex.erase(result); } - iter->second->erase (index.first, count); + iter->second->erase(index.first, count); } int CSMWorld::RefIdData::getSize() const @@ -197,39 +197,39 @@ int CSMWorld::RefIdData::getSize() const return mIndex.size(); } -std::vector CSMWorld::RefIdData::getIds (bool listDeleted) const +std::vector CSMWorld::RefIdData::getIds(bool listDeleted) const { std::vector ids; - for (std::map::const_iterator iter (mIndex.begin()); iter!=mIndex.end(); - ++iter) + for (std::map::const_iterator iter(mIndex.begin()); iter != mIndex.end(); + ++iter) { - if (listDeleted || !getRecord (iter->second).isDeleted()) + if (listDeleted || !getRecord(iter->second).isDeleted()) { - std::map::const_iterator container = - mRecordContainers.find (iter->second.second); + std::map::const_iterator container = + mRecordContainers.find(iter->second.second); - if (container==mRecordContainers.end()) - throw std::logic_error ("Invalid referenceable ID type"); + if (container == mRecordContainers.end()) + throw std::logic_error("Invalid referenceable ID type"); - ids.push_back (container->second->getId (iter->second.first)); + ids.push_back(container->second->getId(iter->second.first)); } } return ids; } -void CSMWorld::RefIdData::save (int index, ESM::ESMWriter& writer) const +void CSMWorld::RefIdData::save(int index, ESM::ESMWriter& writer) const { - LocalIndex localIndex = globalToLocalIndex (index); + LocalIndex localIndex = globalToLocalIndex(index); - std::map::const_iterator iter = - mRecordContainers.find (localIndex.second); + std::map::const_iterator iter = + mRecordContainers.find(localIndex.second); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - iter->second->save (localIndex.first, writer); + iter->second->save(localIndex.first, writer); } const CSMWorld::RefIdDataContainer< ESM::Book >& CSMWorld::RefIdData::getBooks() const @@ -296,3 +296,18 @@ const CSMWorld::RefIdDataContainer< ESM::Light >& CSMWorld::RefIdData::getLights { return mLights; } + +const CSMWorld::RefIdDataContainer< ESM::Lockpick >& CSMWorld::RefIdData::getLocpicks() const +{ + return mLockpicks; +} + +const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& CSMWorld::RefIdData::getMiscellaneous() const +{ + return mMiscellaneous; +} + +const CSMWorld::RefIdDataContainer< ESM::NPC >& CSMWorld::RefIdData::getNPCs() const +{ + return mNpcs; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 6b6e01e012..8aa3c25222 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -234,7 +234,11 @@ namespace CSMWorld const RefIdDataContainer& getCreatureLevelledLists() const; const RefIdDataContainer& getItemLevelledList() const; const RefIdDataContainer& getLights() const; + const RefIdDataContainer& getLocpicks() const; + const RefIdDataContainer& getMiscellaneous() const; + const RefIdDataContainer& getNPCs() const; }; } #endif + diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index 1eac8d64fe..08f678b45f 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -105,7 +105,7 @@ struct NPC char mNpdtType; NPDTstruct52 mNpdt52; - NPDTstruct12 mNpdt12; // Use this if npdt52.gold == -10 + NPDTstruct12 mNpdt12; //for autocalculated characters int mFlags; From da3dda896ac2ad02f2ef8ad40f42c8fc4e0e3cd0 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 27 Dec 2013 22:57:36 +0100 Subject: [PATCH 026/168] Code compiles now --- apps/opencs/model/tools/referenceablecheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 6d06d61519..40f7c26d23 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -835,7 +835,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI if (NPC.mNpdtType == 12) { - if (NPC.mFlags ^ ESM::NPC::Flags::Autocalc) + if (NPC.mFlags ^ 0x0008) { messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType and flags mismatch!"); //should not happend? return; From 5406a70fdd7337d1aad3b4d86d9fae2eac2301f4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 28 Dec 2013 11:34:51 +0100 Subject: [PATCH 027/168] still working on npc check --- .../opencs/model/tools/referenceablecheck.cpp | 62 +++++++++++++++++-- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 40f7c26d23..8ab163fc55 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -833,9 +833,9 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI //Don't know what unknown is for int Gold(NPC.mNpdt52.mGold); - if (NPC.mNpdtType == 12) + if (NPC.mNpdtType == 12) //12 = autocalculated { - if (NPC.mFlags ^ 0x0008) + if (NPC.mFlags ^ 0x0008) //0x0008 = autocalculated flag { messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType and flags mismatch!"); //should not happend? return; @@ -851,18 +851,64 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI { if (NPC.mNpdt52.mHealth < 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " health is negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " health has negative value"); } if (NPC.mNpdt52.mMana < 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " mana is negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " mana has negative value"); } if (NPC.mNpdt52.mFatigue < 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " fatigue is negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " fatigue has negative value"); } + + if (NPC.mNpdt52.mAgility < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " agility has negative value"); + } + + if (NPC.mNpdt52.mEndurance < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " endurance has negative value"); + } + + if (NPC.mNpdt52.mIntelligence < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " intelligence has negative value"); + } + + if (NPC.mNpdt52.mLuck < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " luck has negative value"); + } + + if (NPC.mNpdt52.mPersonality < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " personality has negative value"); + } + + if (NPC.mNpdt52.mStrength < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " strength has negative value"); + } + + if (NPC.mNpdt52.mSpeed < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " speed has negative value"); + } + + if (NPC.mNpdt52.mAgility < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " agility has negative value"); + } + + if (NPC.mNpdt52.mWillpower < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " willpower has negative value"); + } + } if (level < 1) @@ -884,6 +930,10 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI { messages.push_back(id.toString() + "|" + NPC.mId + " has any empty class"); } - + + if (NPC.mRace.empty()) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has any empty race"); + } //TODO: reputation, Disposition, rank, everything else } From be6e47bcb6f40427a42bad1ec5f967be7cddbcfa Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 28 Dec 2013 15:51:38 +0100 Subject: [PATCH 028/168] Corrections --- .../opencs/model/tools/referenceablecheck.cpp | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 8ab163fc55..44dfbbef71 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -864,49 +864,44 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI messages.push_back(id.toString() + "|" + NPC.mId + " fatigue has negative value"); } - if (NPC.mNpdt52.mAgility < 0) + if (NPC.mNpdt52.mAgility == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " agility has negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " agility has zero value"); } - if (NPC.mNpdt52.mEndurance < 0) + if (NPC.mNpdt52.mEndurance == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " endurance has negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " endurance has zero value"); } - if (NPC.mNpdt52.mIntelligence < 0) + if (NPC.mNpdt52.mIntelligence == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " intelligence has negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " intelligence has zero value"); } - if (NPC.mNpdt52.mLuck < 0) + if (NPC.mNpdt52.mLuck == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " luck has negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " luck has zero value"); } - if (NPC.mNpdt52.mPersonality < 0) + if (NPC.mNpdt52.mPersonality == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " personality has negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " personality has zero value"); } - if (NPC.mNpdt52.mStrength < 0) + if (NPC.mNpdt52.mStrength == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " strength has negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " strength has zero value"); } - if (NPC.mNpdt52.mSpeed < 0) + if (NPC.mNpdt52.mSpeed == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " speed has negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " speed has zero value"); } - if (NPC.mNpdt52.mAgility < 0) + if (NPC.mNpdt52.mWillpower == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " agility has negative value"); - } - - if (NPC.mNpdt52.mWillpower < 0) - { - messages.push_back(id.toString() + "|" + NPC.mId + " willpower has negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " willpower has zero value"); } } From b9d1047ad640bb4a7b3c45d09f9a39fa36b3210f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 28 Dec 2013 16:18:16 +0100 Subject: [PATCH 029/168] Small fix for lights. --- apps/opencs/model/tools/referenceablecheck.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 44dfbbef71..752a57f3ee 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -694,12 +694,12 @@ void CSMTools::ReferenceableCheckStage::lightCheck(int stage, const CSMWorld::Re messages.push_back(id.toString() + "|" + Light.mId + " has no icon"); } - if (Light.mData.mWeight < 0) //probabbly needs to be checked only for carrable lights TODO + if (Light.mData.mWeight < 0) { messages.push_back(id.toString() + "|" + Light.mId + " has negative weight"); } - if (Light.mData.mValue < 0) //probabbly needs to be checked only for carrable lights TODO + if (Light.mData.mValue < 0) { messages.push_back(id.toString() + "|" + Light.mId + " has negative value"); } @@ -709,9 +709,9 @@ void CSMTools::ReferenceableCheckStage::lightCheck(int stage, const CSMWorld::Re messages.push_back(id.toString() + "|" + Light.mId + " has no model"); } - if (Light.mData.mTime < 0) + if (Light.mData.mTime == 0) { - messages.push_back(id.toString() + "|" + Light.mId + " has negative duration"); + messages.push_back(id.toString() + "|" + Light.mId + " has zero duration"); } } } @@ -930,5 +930,6 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI { messages.push_back(id.toString() + "|" + NPC.mId + " has any empty race"); } + //TODO: reputation, Disposition, rank, everything else } From 147ee0ace306f2dbfb452f95ab9727aa634cac98 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 28 Dec 2013 17:35:04 +0100 Subject: [PATCH 030/168] small oops + added new variables to the constructor --- apps/opencs/model/tools/referenceablecheck.cpp | 6 ++++-- apps/opencs/model/tools/referenceablecheck.hpp | 6 ++++-- apps/opencs/model/tools/tools.cpp | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 752a57f3ee..abf13ced96 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -9,8 +9,10 @@ #include "../world/universalid.hpp" -CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable) : +CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes) : mReferencables(referenceable), + mClasses(classes), + mRaces(races), mBooksSize(mReferencables.getBooks().getSize()), mActivatorsSize(mReferencables.getActivators().getSize()), mPotionsSize(mReferencables.getPotions().getSize()), @@ -913,7 +915,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI if (Gold < 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " gold is negative value"); + messages.push_back(id.toString() + "|" + NPC.mId + " gold has negative value"); } if (NPC.mName.empty()) diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index d4f7697aee..9e53f2b197 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -11,7 +11,7 @@ namespace CSMTools class ReferenceableCheckStage : public CSMDoc::Stage { public: - ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable); + ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes); virtual void perform(int stage, std::vector< std::string >& messages); virtual int setup(); @@ -34,7 +34,9 @@ namespace CSMTools void miscCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - const CSMWorld::RefIdData mReferencables; + const CSMWorld::RefIdData& mReferencables; + const CSMWorld::IdCollection mRaces; + const CSMWorld::IdCollection mClasses; //SIZES OF CONCRETE TYPES const int mBooksSize; diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index d8cbb2fc11..945fa191f2 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -76,7 +76,7 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() mVerifier->appendStage (new SpellCheckStage (mData.getSpells())); - mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet())); + mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet()), mData.getRaces(), mData.getClasses()); } return mVerifier; From bf0383fe056472442228e4cc4518dc2f47ee2d69 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 28 Dec 2013 18:07:01 +0100 Subject: [PATCH 031/168] Last fixes. --- .../opencs/model/tools/referenceablecheck.cpp | 54 +++++++++++++++---- .../opencs/model/tools/referenceablecheck.hpp | 4 +- apps/opencs/model/tools/tools.cpp | 2 +- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index abf13ced96..a6fbe7f80f 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -9,7 +9,7 @@ #include "../world/universalid.hpp" -CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes) : +CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes) : mReferencables(referenceable), mClasses(classes), mRaces(races), @@ -146,6 +146,12 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= mMiscellaneousSize; + + if (stage < mNPCsSize) + { + npcCheck(stage, mReferencables.getNPCs(), messages); + return; + } } int CSMTools::ReferenceableCheckStage::setup() @@ -837,7 +843,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI if (NPC.mNpdtType == 12) //12 = autocalculated { - if (NPC.mFlags ^ 0x0008) //0x0008 = autocalculated flag + if (! NPC.mFlags & 0x0008) //0x0008 = autocalculated flag { messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType and flags mismatch!"); //should not happend? return; @@ -851,11 +857,6 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI } else { - if (NPC.mNpdt52.mHealth < 0) - { - messages.push_back(id.toString() + "|" + NPC.mId + " health has negative value"); - } - if (NPC.mNpdt52.mMana < 0) { messages.push_back(id.toString() + "|" + NPC.mId + " mana has negative value"); @@ -927,11 +928,46 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI { messages.push_back(id.toString() + "|" + NPC.mId + " has any empty class"); } - + else //checking if there is such class + { + bool nosuchclass(true); + + for (int i = 0; i < mClasses.getSize(); ++i) + { + if (mClasses.getRecord(i).get().mName == NPC.mClass) + { + nosuchclass = false; + break; + } + } + + if (nosuchclass) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has invalid class"); + } + } + if (NPC.mRace.empty()) { messages.push_back(id.toString() + "|" + NPC.mId + " has any empty race"); } - + else //checking if there is a such race + { + bool nosuchrace(true); + + for (int i = 0; i < mRaces.getSize(); ++i) + { + if (mRaces.getRecord(i).get().mName == NPC.mRace) + { + nosuchrace = false; + break; + } + } + if (nosuchrace) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has invalid race"); + } + } + //TODO: reputation, Disposition, rank, everything else } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 9e53f2b197..c87d80b0f8 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -35,8 +35,8 @@ namespace CSMTools void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); const CSMWorld::RefIdData& mReferencables; - const CSMWorld::IdCollection mRaces; - const CSMWorld::IdCollection mClasses; + const CSMWorld::IdCollection& mRaces; + const CSMWorld::IdCollection& mClasses; //SIZES OF CONCRETE TYPES const int mBooksSize; diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 945fa191f2..15a7bd1816 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -76,7 +76,7 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() mVerifier->appendStage (new SpellCheckStage (mData.getSpells())); - mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet()), mData.getRaces(), mData.getClasses()); + mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses())); } return mVerifier; From 9df6d23afcc929bd93368a9e553d45dea611050d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 29 Dec 2013 20:15:00 +0100 Subject: [PATCH 032/168] removing member size values, since this does not work properly. --- .../opencs/model/tools/referenceablecheck.cpp | 113 ++++++++++-------- .../opencs/model/tools/referenceablecheck.hpp | 18 --- 2 files changed, 64 insertions(+), 67 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index a6fbe7f80f..79f6009dab 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -12,145 +12,159 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes) : mReferencables(referenceable), mClasses(classes), - mRaces(races), - mBooksSize(mReferencables.getBooks().getSize()), - mActivatorsSize(mReferencables.getActivators().getSize()), - mPotionsSize(mReferencables.getPotions().getSize()), - mApparatiSize(mReferencables.getApparati().getSize()), - mArmorsSzie(mReferencables.getArmors().getSize()), - mClothingSize(mReferencables.getClothing().getSize()), - mContainersSize(mReferencables.getContainers().getSize()), - mCreaturesSize(mReferencables.getCreatures().getSize()), - mDoorsSize(mReferencables.getDoors().getSize()), - mIngredientsSize(mReferencables.getIngredients().getSize()), - mCreaturesLevListsSize(mReferencables.getCreatureLevelledLists().getSize()), - mItemLevelledListsSize(mReferencables.getItemLevelledList().getSize()), - mLightsSize(mReferencables.getLights().getSize()), - mLockpicksSize(mReferencables.getLocpicks().getSize()), - mMiscellaneousSize(mReferencables.getMiscellaneous().getSize()), - mNPCsSize(mReferencables.getNPCs().getSize()) + mRaces(races) { } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. - if (stage < mBooksSize) + const int BookSize(mReferencables.getBooks().getSize()); + + if (stage < BookSize) { bookCheck(stage, mReferencables.getBooks(), messages); return; } - stage -= mBooksSize; + stage -= BookSize; - if (stage < mActivatorsSize) + const int ActivatorSize(mReferencables.getActivators().getSize()); + + if (stage < ActivatorSize) { activatorCheck(stage, mReferencables.getActivators(), messages); return; } - stage -= mActivatorsSize; + stage -= ActivatorSize; - if (stage < mPotionsSize) + const int PotionSize(mReferencables.getActivators().getSize()); + + if (stage < PotionSize) { potionCheck(stage, mReferencables.getPotions(), messages); return; } - stage -= mPotionsSize; + stage -= PotionSize; - if (stage < mApparatiSize) + const int ApparatusSize(mReferencables.getApparati().getSize()); + + if (stage < ApparatusSize) { apparatusCheck(stage, mReferencables.getApparati(), messages); return; } - stage -= mApparatiSize; + stage -= ApparatusSize; - if (stage < mArmorsSzie) + const int ArmorSize(mReferencables.getArmors().getSize()); + + if (stage < ArmorSize) { armorCheck(stage, mReferencables.getArmors(), messages); return; } - stage -= mArmorsSzie; + stage -= ArmorSize; - if (stage < mClothingSize) + const int ClothingSize(mReferencables.getClothing().getSize()); + + if (stage < ClothingSize) { clothingCheck(stage, mReferencables.getClothing(), messages); return; } - stage -= mClothingSize; + stage -= ClothingSize; - if (stage < mContainersSize) + const int ContainerSize(mReferencables.getContainers().getSize()); + + if (stage < ContainerSize) { containerCheck(stage, mReferencables.getContainers(), messages); return; } - stage -= mContainersSize; + stage -= ContainerSize; - if (stage < mDoorsSize) + const int DoorSize(mReferencables.getDoors().getSize()); + + if (stage < DoorSize) { doorCheck(stage, mReferencables.getDoors(), messages); return; } - stage -= mDoorsSize; + stage -= DoorSize; - if (stage < mIngredientsSize) + const int IngredientSize(mReferencables.getIngredients().getSize()); + + if (stage < IngredientSize) { ingredientCheck(stage, mReferencables.getIngredients(), messages); return; } - stage -= mIngredientsSize; + stage -= IngredientSize; - if (stage < mCreaturesLevListsSize) + const int CreatureLevListSize(mReferencables.getCreatureLevelledLists().getSize()); + + if (stage < CreatureLevListSize) { creaturesLevListCheck(stage, mReferencables.getCreatureLevelledLists(), messages); return; } - stage -= mCreaturesLevListsSize; + stage -= CreatureLevListSize; - if (stage < mItemLevelledListsSize) + const int ItemLevelledListSize(mReferencables.getItemLevelledList().getSize()); + + if (stage < ItemLevelledListSize) { itemLevelledListCheck(stage, mReferencables.getItemLevelledList(), messages); return; } - stage -= mItemLevelledListsSize; + stage -= ItemLevelledListSize; - if (stage < mLightsSize) + const int LightSize(mReferencables.getLights().getSize()); + + if (stage < LightSize) { lightCheck(stage, mReferencables.getLights(), messages); return; } - stage -= mLightsSize; + stage -= LightSize; - if (stage < mLockpicksSize) + const int LockpickSize(mReferencables.getLocpicks().getSize()); + + if (stage < LockpickSize) { lockpickCheck(stage, mReferencables.getLocpicks(), messages); return; } - stage -= mLockpicksSize; + stage -= LockpickSize; - if (stage < mMiscellaneousSize) + const int MiscSize(mReferencables.getMiscellaneous().getSize()); + + if (stage < MiscSize) { miscCheck(stage, mReferencables.getMiscellaneous(), messages); return; } - stage -= mMiscellaneousSize; - - if (stage < mNPCsSize) + stage -= MiscSize; + + const int NPCSize(mReferencables.getNPCs().getSize()); + + if (stage < NPCSize) { - npcCheck(stage, mReferencables.getNPCs(), messages); - return; + npcCheck(stage, mReferencables.getNPCs(), messages); + return; } } @@ -963,6 +977,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI break; } } + if (nosuchrace) { messages.push_back(id.toString() + "|" + NPC.mId + " has invalid race"); diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index c87d80b0f8..1d85dc310f 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -37,24 +37,6 @@ namespace CSMTools const CSMWorld::RefIdData& mReferencables; const CSMWorld::IdCollection& mRaces; const CSMWorld::IdCollection& mClasses; - - //SIZES OF CONCRETE TYPES - const int mBooksSize; - const int mActivatorsSize; - const int mPotionsSize; - const int mApparatiSize; - const int mArmorsSzie; - const int mClothingSize; - const int mContainersSize; - const int mCreaturesSize; - const int mDoorsSize; - const int mIngredientsSize; - const int mCreaturesLevListsSize; - const int mItemLevelledListsSize; - const int mLightsSize; - const int mLockpicksSize; - const int mMiscellaneousSize; - const int mNPCsSize; }; } #endif // REFERENCEABLECHECKSTAGE_H From e321d571e1ff72456aab8a78907489022576a248 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 29 Dec 2013 21:02:53 +0100 Subject: [PATCH 033/168] Added faction check. --- .../opencs/model/tools/referenceablecheck.cpp | 35 +++++++++++++++++-- .../opencs/model/tools/referenceablecheck.hpp | 3 +- apps/opencs/model/tools/tools.cpp | 2 +- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 79f6009dab..5406ca08e1 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -9,10 +9,11 @@ #include "../world/universalid.hpp" -CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes) : +CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes, const CSMWorld::IdCollection& faction) : mReferencables(referenceable), mClasses(classes), - mRaces(races) + mRaces(races), + mFactions(faction) { } @@ -857,7 +858,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI if (NPC.mNpdtType == 12) //12 = autocalculated { - if (! NPC.mFlags & 0x0008) //0x0008 = autocalculated flag + if (NPC.mFlags & 0x0008 == 0) //0x0008 = autocalculated flag { messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType and flags mismatch!"); //should not happend? return; @@ -984,5 +985,33 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI } } + if (Disposition < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has negative disposition"); + } + + if (Reputation < 0) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has negative reputation"); + } + + if(!NPC.mFaction.empty()) + { + bool nosuchfaction(true); + + for (int i = 0; i < mRaces.getSize(); ++i) + { + if (mFactions.getRecord(i).get().mName == NPC.mFaction) + { + nosuchfaction = false; + break; + } + } + + if (nosuchfaction) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has invalid faction"); + } + } //TODO: reputation, Disposition, rank, everything else } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 1d85dc310f..591e3d335f 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -11,7 +11,7 @@ namespace CSMTools class ReferenceableCheckStage : public CSMDoc::Stage { public: - ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes); + ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes, const CSMWorld::IdCollection& factions); virtual void perform(int stage, std::vector< std::string >& messages); virtual int setup(); @@ -37,6 +37,7 @@ namespace CSMTools const CSMWorld::RefIdData& mReferencables; const CSMWorld::IdCollection& mRaces; const CSMWorld::IdCollection& mClasses; + const CSMWorld::IdCollection& mFactions; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 15a7bd1816..b5320ff9f9 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -76,7 +76,7 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() mVerifier->appendStage (new SpellCheckStage (mData.getSpells())); - mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses())); + mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions())); } return mVerifier; From 13637e7166825a1c9dce6f06614b7b5e214b0ea0 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 29 Dec 2013 21:45:09 +0100 Subject: [PATCH 034/168] Dynamic_casting, checking rank. Commented out faction check, since it will not work. --- .../opencs/model/tools/referenceablecheck.cpp | 72 ++++++++++--------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 5406ca08e1..010fb868c8 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -183,7 +183,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::Ref return; } - const ESM::Book& Book = (static_cast& >(baserecord)).get(); + const ESM::Book& Book = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, Book.mId); //Checking for name @@ -232,7 +232,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(int stage, const CSMWorld return; } - const ESM::Activator& Activator = (static_cast& >(baserecord)).get(); + const ESM::Activator& Activator = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Activator, Activator.mId); //Checking for model, IIRC all activators should have a model @@ -251,7 +251,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck(int stage, const CSMWorld::R return; } - const ESM::Potion& Potion = (static_cast& >(baserecord)).get(); + const ESM::Potion& Potion = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, Potion.mId); //Checking for name @@ -297,7 +297,7 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(int stage, const CSMWorld return; } - const ESM::Apparatus& Apparatus = (static_cast& >(baserecord)).get(); + const ESM::Apparatus& Apparatus = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Apparatus, Apparatus.mId); //Checking for name @@ -346,7 +346,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck(int stage, const CSMWorld::Re return; } - const ESM::Armor& Armor = (static_cast& >(baserecord)).get(); + const ESM::Armor& Armor = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Armor, Armor.mId); //Checking for name @@ -407,7 +407,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(int stage, const CSMWorld: return; } - const ESM::Clothing& Clothing = (static_cast& >(baserecord)).get(); + const ESM::Clothing& Clothing = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, Clothing.mId); //Checking for name @@ -456,7 +456,7 @@ void CSMTools::ReferenceableCheckStage::containerCheck(int stage, const CSMWorld return; } - const ESM::Container& Container = (static_cast& >(baserecord)).get(); + const ESM::Container& Container = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, Container.mId); //Checking for model, IIRC all containers should have a model @@ -487,7 +487,7 @@ void CSMTools::ReferenceableCheckStage::creatureCheck(int stage, const CSMWorld: return; } - const ESM::Creature& Creature = (static_cast&>(baserecord)).get(); + const ESM::Creature& Creature = (dynamic_cast&>(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Creature, Creature.mId); if (Creature.mModel.empty()) @@ -581,7 +581,7 @@ void CSMTools::ReferenceableCheckStage::doorCheck(int stage, const CSMWorld::Ref return; } - const ESM::Door& Door = (static_cast&>(baserecord)).get(); + const ESM::Door& Door = (dynamic_cast&>(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Door, Door.mId); //usual, name and model @@ -607,7 +607,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(int stage, const CSMWorl return; } - const ESM::Ingredient& Ingredient = (static_cast& >(baserecord)).get(); + const ESM::Ingredient& Ingredient = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Ingredient, Ingredient.mId); //Checking for name @@ -650,7 +650,7 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const C return; } - const ESM::CreatureLevList& CreatureLevList = (static_cast& >(baserecord)).get(); + const ESM::CreatureLevList& CreatureLevList = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, CreatureLevList.mId); //CreatureLevList but Type_CreatureLevelledList :/ for (unsigned i = 0; i < CreatureLevList.mList.size(); ++i) @@ -676,7 +676,7 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(int stage, const C return; } - const ESM::ItemLevList& ItemLevList = (static_cast& >(baserecord)).get(); + const ESM::ItemLevList& ItemLevList = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, ItemLevList.mId); for (unsigned i = 0; i < ItemLevList.mList.size(); ++i) @@ -702,7 +702,7 @@ void CSMTools::ReferenceableCheckStage::lightCheck(int stage, const CSMWorld::Re return; } - const ESM::Light& Light = (static_cast& >(baserecord)).get(); + const ESM::Light& Light = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Light, Light.mId); if (Light.mData.mRadius < 0) @@ -748,7 +748,7 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(int stage, const CSMWorld: return; } - const ESM::Lockpick& Lockpick = (static_cast& >(baserecord)).get(); + const ESM::Lockpick& Lockpick = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Lockpick, Lockpick.mId); //Checking for name @@ -801,7 +801,7 @@ void CSMTools::ReferenceableCheckStage::miscCheck(int stage, const CSMWorld::Ref return; } - const ESM::Miscellaneous& Miscellaneous = (static_cast& >(baserecord)).get(); + const ESM::Miscellaneous& Miscellaneous = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, Miscellaneous.mId); //Checking for name @@ -844,7 +844,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI return; } - const ESM::NPC& NPC = (static_cast& >(baserecord)).get(); + const ESM::NPC& NPC = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc, NPC.mId); @@ -858,7 +858,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI if (NPC.mNpdtType == 12) //12 = autocalculated { - if (NPC.mFlags & 0x0008 == 0) //0x0008 = autocalculated flag + if ((NPC.mFlags & 0x0008) == 0) //0x0008 = autocalculated flag { messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType and flags mismatch!"); //should not happend? return; @@ -949,7 +949,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI for (int i = 0; i < mClasses.getSize(); ++i) { - if (mClasses.getRecord(i).get().mName == NPC.mClass) + if (dynamic_cast(mClasses.getRecord(i).get()).mId == NPC.mClass) { nosuchclass = false; break; @@ -972,7 +972,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI for (int i = 0; i < mRaces.getSize(); ++i) { - if (mRaces.getRecord(i).get().mName == NPC.mRace) + if (dynamic_cast(mRaces.getRecord(i).get()).mName == NPC.mRace) { nosuchrace = false; break; @@ -995,23 +995,31 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI messages.push_back(id.toString() + "|" + NPC.mId + " has negative reputation"); } - if(!NPC.mFaction.empty()) + if (!NPC.mFaction.empty()) { - bool nosuchfaction(true); - - for (int i = 0; i < mRaces.getSize(); ++i) + if (Rank < 0) { - if (mFactions.getRecord(i).get().mName == NPC.mFaction) - { - nosuchfaction = false; - break; - } + messages.push_back(id.toString() + "|" + NPC.mId + " has negative rank"); } - if (nosuchfaction) - { - messages.push_back(id.toString() + "|" + NPC.mId + " has invalid faction"); - } + //This code does not work at the moment. nosuchfaction is true for every npc record + /* + bool nosuchfaction(true); + for (int i = 0; i < mRaces.getSize(); ++i) + { + if (dynamic_cast(mFactions.getRecord(i).get()).mName == NPC.mFaction) + { + nosuchfaction = false; + break; + } + } + + if (nosuchfaction) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has invalid faction"); + } + */ } + //TODO: reputation, Disposition, rank, everything else } From 842e26b8e5bb17a76298308ac3c4565964b3c891 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 29 Dec 2013 21:53:33 +0100 Subject: [PATCH 035/168] added comment --- apps/opencs/model/tools/referenceablecheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 010fb868c8..d2053c1a6b 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -972,7 +972,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI for (int i = 0; i < mRaces.getSize(); ++i) { - if (dynamic_cast(mRaces.getRecord(i).get()).mName == NPC.mRace) + if (dynamic_cast(mRaces.getRecord(i).get()).mName == NPC.mRace) //mId in class, mName for race. Stupid. { nosuchrace = false; break; @@ -990,7 +990,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI messages.push_back(id.toString() + "|" + NPC.mId + " has negative disposition"); } - if (Reputation < 0) + if (Reputation < 0) //It seems that no character in Morrowind.esm have negative reputation. I'm assuming that negative reputation is invalid { messages.push_back(id.toString() + "|" + NPC.mId + " has negative reputation"); } From c89608f390c1d82a749aef448240481bc80afaff Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Dec 2013 11:39:03 +0100 Subject: [PATCH 036/168] Check for head and hair. Correct faction check. --- .../opencs/model/tools/referenceablecheck.cpp | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index d2053c1a6b..ad52c59621 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -995,30 +995,38 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI messages.push_back(id.toString() + "|" + NPC.mId + " has negative reputation"); } - if (!NPC.mFaction.empty()) + if (NPC.mFaction.empty() == false) { if (Rank < 0) { messages.push_back(id.toString() + "|" + NPC.mId + " has negative rank"); } - //This code does not work at the moment. nosuchfaction is true for every npc record - /* - bool nosuchfaction(true); - for (int i = 0; i < mRaces.getSize(); ++i) - { - if (dynamic_cast(mFactions.getRecord(i).get()).mName == NPC.mFaction) - { - nosuchfaction = false; - break; - } - } + bool nosuchfaction(true); - if (nosuchfaction) - { - messages.push_back(id.toString() + "|" + NPC.mId + " has invalid faction"); - } - */ + for (int i = 0; i < mFactions.getSize(); ++i) + { + if (dynamic_cast(mFactions.getRecord(i).get()).mId == NPC.mFaction) + { + nosuchfaction = false; + break; + } + } + + if (nosuchfaction) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has invalid faction"); + } + } + + if (NPC.mHead.empty()) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has no head"); + } + + if (NPC.mHair.empty()) + { + messages.push_back(id.toString() + "|" + NPC.mId + " has no har"); } //TODO: reputation, Disposition, rank, everything else From 3758fe38340ed147e0d73a2b8f8df0d886e8624e Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Dec 2013 13:23:16 +0100 Subject: [PATCH 037/168] reformatted --- .../opencs/model/tools/referenceablecheck.hpp | 22 +-- apps/opencs/model/tools/tools.cpp | 94 +++++------ apps/opencs/model/world/refidcollection.hpp | 48 +++--- apps/opencs/model/world/refiddata.hpp | 147 +++++++++--------- 4 files changed, 157 insertions(+), 154 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 591e3d335f..fcf774f148 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -16,7 +16,7 @@ namespace CSMTools virtual int setup(); private: - //CONCRETE CHECKS + //CONCRETE CHECKS void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages); void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages); void potionCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); @@ -26,18 +26,18 @@ namespace CSMTools void containerCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void creatureCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void lightCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void miscCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void lightCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void miscCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); const CSMWorld::RefIdData& mReferencables; - const CSMWorld::IdCollection& mRaces; - const CSMWorld::IdCollection& mClasses; - const CSMWorld::IdCollection& mFactions; + const CSMWorld::IdCollection& mRaces; + const CSMWorld::IdCollection& mClasses; + const CSMWorld::IdCollection& mFactions; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index b5320ff9f9..c25811ea4c 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -21,7 +21,7 @@ #include "spellcheck.hpp" #include "referenceablecheck.hpp" -CSMDoc::Operation *CSMTools::Tools::get (int type) +CSMDoc::Operation* CSMTools::Tools::get(int type) { switch (type) { @@ -31,60 +31,60 @@ CSMDoc::Operation *CSMTools::Tools::get (int type) return 0; } -const CSMDoc::Operation *CSMTools::Tools::get (int type) const +const CSMDoc::Operation* CSMTools::Tools::get(int type) const { - return const_cast (this)->get (type); + return const_cast(this)->get(type); } -CSMDoc::Operation *CSMTools::Tools::getVerifier() +CSMDoc::Operation* CSMTools::Tools::getVerifier() { if (!mVerifier) { - mVerifier = new CSMDoc::Operation (CSMDoc::State_Verifying, false); + mVerifier = new CSMDoc::Operation(CSMDoc::State_Verifying, false); - connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); - connect (mVerifier, SIGNAL (done (int)), this, SIGNAL (done (int))); - connect (mVerifier, SIGNAL (reportMessage (const QString&, int)), - this, SLOT (verifierMessage (const QString&, int))); + connect(mVerifier, SIGNAL(progress(int, int, int)), this, SIGNAL(progress(int, int, int))); + connect(mVerifier, SIGNAL(done(int)), this, SIGNAL(done(int))); + connect(mVerifier, SIGNAL(reportMessage(const QString&, int)), + this, SLOT(verifierMessage(const QString&, int))); std::vector mandatoryIds; // I want C++11, damn it! - mandatoryIds.push_back ("Day"); - mandatoryIds.push_back ("DaysPassed"); - mandatoryIds.push_back ("GameHour"); - mandatoryIds.push_back ("Month"); - mandatoryIds.push_back ("PCRace"); - mandatoryIds.push_back ("PCVampire"); - mandatoryIds.push_back ("PCWerewolf"); - mandatoryIds.push_back ("PCYear"); + mandatoryIds.push_back("Day"); + mandatoryIds.push_back("DaysPassed"); + mandatoryIds.push_back("GameHour"); + mandatoryIds.push_back("Month"); + mandatoryIds.push_back("PCRace"); + mandatoryIds.push_back("PCVampire"); + mandatoryIds.push_back("PCWerewolf"); + mandatoryIds.push_back("PCYear"); - mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(), - CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds)); + mVerifier->appendStage(new MandatoryIdStage(mData.getGlobals(), + CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Globals), mandatoryIds)); - mVerifier->appendStage (new SkillCheckStage (mData.getSkills())); + mVerifier->appendStage(new SkillCheckStage(mData.getSkills())); - mVerifier->appendStage (new ClassCheckStage (mData.getClasses())); + mVerifier->appendStage(new ClassCheckStage(mData.getClasses())); - mVerifier->appendStage (new FactionCheckStage (mData.getFactions())); + mVerifier->appendStage(new FactionCheckStage(mData.getFactions())); - mVerifier->appendStage (new RaceCheckStage (mData.getRaces())); + mVerifier->appendStage(new RaceCheckStage(mData.getRaces())); - mVerifier->appendStage (new SoundCheckStage (mData.getSounds())); + mVerifier->appendStage(new SoundCheckStage(mData.getSounds())); - mVerifier->appendStage (new RegionCheckStage (mData.getRegions())); + mVerifier->appendStage(new RegionCheckStage(mData.getRegions())); - mVerifier->appendStage (new BirthsignCheckStage (mData.getBirthsigns())); + mVerifier->appendStage(new BirthsignCheckStage(mData.getBirthsigns())); - mVerifier->appendStage (new SpellCheckStage (mData.getSpells())); - - mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions())); + mVerifier->appendStage(new SpellCheckStage(mData.getSpells())); + + mVerifier->appendStage(new ReferenceableCheckStage(mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions())); } return mVerifier; } -CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0) +CSMTools::Tools::Tools(CSMWorld::Data& data) : mData(data), mVerifier(0), mNextReportNumber(0) { - for (std::map::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter) + for (std::map::iterator iter(mReports.begin()); iter != mReports.end(); ++iter) delete iter->second; } @@ -95,17 +95,17 @@ CSMTools::Tools::~Tools() CSMWorld::UniversalId CSMTools::Tools::runVerifier() { - mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); - mActiveReports[CSMDoc::State_Verifying] = mNextReportNumber-1; + mReports.insert(std::make_pair(mNextReportNumber++, new ReportModel)); + mActiveReports[CSMDoc::State_Verifying] = mNextReportNumber - 1; getVerifier()->start(); - return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, mNextReportNumber-1); + return CSMWorld::UniversalId(CSMWorld::UniversalId::Type_VerificationResults, mNextReportNumber - 1); } -void CSMTools::Tools::abortOperation (int type) +void CSMTools::Tools::abortOperation(int type) { - if (CSMDoc::Operation *operation = get (type)) + if (CSMDoc::Operation* operation = get(type)) operation->abort(); } @@ -113,32 +113,32 @@ int CSMTools::Tools::getRunningOperations() const { static const int sOperations[] = { - CSMDoc::State_Verifying, + CSMDoc::State_Verifying, -1 }; int result = 0; - for (int i=0; sOperations[i]!=-1; ++i) - if (const CSMDoc::Operation *operation = get (sOperations[i])) + for (int i = 0; sOperations[i] != -1; ++i) + if (const CSMDoc::Operation* operation = get(sOperations[i])) if (operation->isRunning()) result |= sOperations[i]; return result; } -CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id) +CSMTools::ReportModel* CSMTools::Tools::getReport(const CSMWorld::UniversalId& id) { - if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults) - throw std::logic_error ("invalid request for report model: " + id.toString()); + if (id.getType() != CSMWorld::UniversalId::Type_VerificationResults) + throw std::logic_error("invalid request for report model: " + id.toString()); - return mReports.at (id.getIndex()); + return mReports.at(id.getIndex()); } -void CSMTools::Tools::verifierMessage (const QString& message, int type) +void CSMTools::Tools::verifierMessage(const QString& message, int type) { - std::map::iterator iter = mActiveReports.find (type); + std::map::iterator iter = mActiveReports.find(type); - if (iter!=mActiveReports.end()) - mReports[iter->second]->add (message.toStdString()); + if (iter != mActiveReports.end()) + mReports[iter->second]->add(message.toStdString()); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 70cae53c84..1a21de8f4f 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -25,9 +25,9 @@ namespace CSMWorld public: - RefIdColumn (int columnId, Display displayType, - int flag = Flag_Table | Flag_Dialogue, bool editable = true, - bool userEditable = true); + RefIdColumn(int columnId, Display displayType, + int flag = Flag_Table | Flag_Dialogue, bool editable = true, + bool userEditable = true); virtual bool isEditable() const; @@ -40,11 +40,11 @@ namespace CSMWorld RefIdData mData; std::deque mColumns; - std::map mAdapters; + std::map mAdapters; private: - const RefIdAdapter& findAdaptor (UniversalId::Type) const; + const RefIdAdapter& findAdaptor(UniversalId::Type) const; ///< Throws an exception if no adaptor for \a Type can be found. public: @@ -55,60 +55,60 @@ namespace CSMWorld virtual int getSize() const; - virtual std::string getId (int index) const; + virtual std::string getId(int index) const; - virtual int getIndex (const std::string& id) const; + virtual int getIndex(const std::string& id) const; virtual int getColumns() const; - virtual const ColumnBase& getColumn (int column) const; + virtual const ColumnBase& getColumn(int column) const; - virtual QVariant getData (int index, int column) const; + virtual QVariant getData(int index, int column) const; - virtual void setData (int index, int column, const QVariant& data); + virtual void setData(int index, int column, const QVariant& data); - virtual void removeRows (int index, int count); + virtual void removeRows(int index, int count); - virtual void appendBlankRecord (const std::string& id, UniversalId::Type type); + virtual void appendBlankRecord(const std::string& id, UniversalId::Type type); ///< \param type Will be ignored, unless the collection supports multiple record types - virtual int searchId (const std::string& id) const; + virtual int searchId(const std::string& id) const; ////< Search record with \a id. /// \return index of record (if found) or -1 (not found) - virtual void replace (int index, const RecordBase& record); + virtual void replace(int index, const RecordBase& record); ///< If the record type does not match, an exception is thrown. /// /// \attention \a record must not change the ID. - virtual void appendRecord (const RecordBase& record, UniversalId::Type type); + virtual void appendRecord(const RecordBase& record, UniversalId::Type type); ///< If the record type does not match, an exception is thrown. /// ///< \param type Will be ignored, unless the collection supports multiple record types - virtual const RecordBase& getRecord (const std::string& id) const; + virtual const RecordBase& getRecord(const std::string& id) const; - virtual const RecordBase& getRecord (int index) const; + virtual const RecordBase& getRecord(int index) const; - void load (ESM::ESMReader& reader, bool base, UniversalId::Type type); + void load(ESM::ESMReader& reader, bool base, UniversalId::Type type); - virtual int getAppendIndex (const std::string& id, UniversalId::Type type) const; + virtual int getAppendIndex(const std::string& id, UniversalId::Type type) const; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual std::vector getIds (bool listDeleted) const; + virtual std::vector getIds(bool listDeleted) const; ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list - virtual bool reorderRows (int baseIndex, const std::vector& newOrder); + virtual bool reorderRows(int baseIndex, const std::vector& newOrder); ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). /// /// \return Success? - void save (int index, ESM::ESMWriter& writer) const; - - const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( + void save(int index, ESM::ESMWriter& writer) const; + + const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( }; } diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 8aa3c25222..719b4b9224 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -41,19 +41,19 @@ namespace CSMWorld virtual int getSize() const = 0; - virtual const RecordBase& getRecord (int index) const = 0; + virtual const RecordBase& getRecord(int index) const = 0; - virtual RecordBase& getRecord (int index)= 0; + virtual RecordBase& getRecord(int index) = 0; - virtual void appendRecord (const std::string& id) = 0; + virtual void appendRecord(const std::string& id) = 0; - virtual void load (int index, ESM::ESMReader& reader, bool base) = 0; + virtual void load(int index, ESM::ESMReader& reader, bool base) = 0; - virtual void erase (int index, int count) = 0; + virtual void erase(int index, int count) = 0; - virtual std::string getId (int index) const = 0; + virtual std::string getId(int index) const = 0; - virtual void save (int index, ESM::ESMWriter& writer) const = 0; + virtual void save(int index, ESM::ESMWriter& writer) const = 0; }; template @@ -63,90 +63,91 @@ namespace CSMWorld virtual int getSize() const; - virtual const RecordBase& getRecord (int index) const; + virtual const RecordBase& getRecord(int index) const; - virtual RecordBase& getRecord (int index); + virtual RecordBase& getRecord(int index); - virtual void appendRecord (const std::string& id); + virtual void appendRecord(const std::string& id); - virtual void load (int index, ESM::ESMReader& reader, bool base); + virtual void load(int index, ESM::ESMReader& reader, bool base); - virtual void erase (int index, int count); + virtual void erase(int index, int count); - virtual std::string getId (int index) const; + virtual std::string getId(int index) const; - virtual void save (int index, ESM::ESMWriter& writer) const; + virtual void save(int index, ESM::ESMWriter& writer) const; }; template int RefIdDataContainer::getSize() const { - return static_cast (mContainer.size()); + return static_cast(mContainer.size()); } template - const RecordBase& RefIdDataContainer::getRecord (int index) const + const RecordBase& RefIdDataContainer::getRecord(int index) const { - return mContainer.at (index); + return mContainer.at(index); } template - RecordBase& RefIdDataContainer::getRecord (int index) + RecordBase& RefIdDataContainer::getRecord(int index) { - return mContainer.at (index); + return mContainer.at(index); } template - void RefIdDataContainer::appendRecord (const std::string& id) + void RefIdDataContainer::appendRecord(const std::string& id) { Record record; record.mModified.mId = id; record.mModified.blank(); record.mState = RecordBase::State_ModifiedOnly; - mContainer.push_back (record); + mContainer.push_back(record); } template - void RefIdDataContainer::load (int index, ESM::ESMReader& reader, bool base) + void RefIdDataContainer::load(int index, ESM::ESMReader& reader, bool base) { - (base ? mContainer.at (index).mBase : mContainer.at (index).mModified).load (reader); + (base ? mContainer.at(index).mBase : mContainer.at(index).mModified).load(reader); } template - void RefIdDataContainer::erase (int index, int count) + void RefIdDataContainer::erase(int index, int count) { - if (index<0 || index+count>=getSize()) - throw std::runtime_error ("invalid RefIdDataContainer index"); + if (index < 0 || index + count >= getSize()) + throw std::runtime_error("invalid RefIdDataContainer index"); - mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); + mContainer.erase(mContainer.begin() + index, mContainer.begin() + index + count); } template - std::string RefIdDataContainer::getId (int index) const + std::string RefIdDataContainer::getId(int index) const { - return mContainer.at (index).get().mId; + return mContainer.at(index).get().mId; } template - void RefIdDataContainer::save (int index, ESM::ESMWriter& writer) const + void RefIdDataContainer::save(int index, ESM::ESMWriter& writer) const { - CSMWorld::RecordBase::State state = mContainer.at (index).mState; + CSMWorld::RecordBase::State state = mContainer.at(index).mState; - if (state==CSMWorld::RecordBase::State_Modified || - state==CSMWorld::RecordBase::State_ModifiedOnly) + if (state == CSMWorld::RecordBase::State_Modified || + state == CSMWorld::RecordBase::State_ModifiedOnly) { std::string type; - for (int i=0; i<4; ++i) - /// \todo make endianess agnostic (change ESMWriter interface?) - type += reinterpret_cast (&mContainer.at (index).mModified.sRecordId)[i]; - writer.startRecord (type); - writer.writeHNCString ("NAME", getId (index)); - mContainer.at (index).mModified.save (writer); - writer.endRecord (type); + for (int i = 0; i < 4; ++i) + /// \todo make endianess agnostic (change ESMWriter interface?) + type += reinterpret_cast(&mContainer.at(index).mModified.sRecordId)[i]; + + writer.startRecord(type); + writer.writeHNCString("NAME", getId(index)); + mContainer.at(index).mModified.save(writer); + writer.endRecord(type); } - else if (state==CSMWorld::RecordBase::State_Deleted) + else if (state == CSMWorld::RecordBase::State_Deleted) { /// \todo write record with delete flag } @@ -184,61 +185,63 @@ namespace CSMWorld std::map mIndex; - std::map mRecordContainers; + std::map mRecordContainers; - void erase (const LocalIndex& index, int count); + void erase(const LocalIndex& index, int count); ///< Must not spill over into another type. public: RefIdData(); - LocalIndex globalToLocalIndex (int index) const; + LocalIndex globalToLocalIndex(int index) const; - int localToGlobalIndex (const LocalIndex& index) const; + int localToGlobalIndex(const LocalIndex& index) const; - LocalIndex searchId (const std::string& id) const; + LocalIndex searchId(const std::string& id) const; - void erase (int index, int count); + void erase(int index, int count); - const RecordBase& getRecord (const LocalIndex& index) const; + const RecordBase& getRecord(const LocalIndex& index) const; - RecordBase& getRecord (const LocalIndex& index); + RecordBase& getRecord(const LocalIndex& index); - void appendRecord (UniversalId::Type type, const std::string& id); + void appendRecord(UniversalId::Type type, const std::string& id); - int getAppendIndex (UniversalId::Type type) const; + int getAppendIndex(UniversalId::Type type) const; - void load (const LocalIndex& index, ESM::ESMReader& reader, bool base); + void load(const LocalIndex& index, ESM::ESMReader& reader, bool base); int getSize() const; - std::vector getIds (bool listDeleted = true) const; + std::vector getIds(bool listDeleted = true) const; ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list - void save (int index, ESM::ESMWriter& writer) const; - - //RECORD CONTAINERS ACCESS METHODS - const RefIdDataContainer& getBooks() const; - const RefIdDataContainer& getActivators() const; - const RefIdDataContainer& getPotions() const; - const RefIdDataContainer& getApparati() const; - const RefIdDataContainer& getArmors() const; - const RefIdDataContainer& getClothing() const; - const RefIdDataContainer& getContainers() const; - const RefIdDataContainer& getCreatures() const; - const RefIdDataContainer& getDoors() const; - const RefIdDataContainer& getIngredients() const; - const RefIdDataContainer& getCreatureLevelledLists() const; - const RefIdDataContainer& getItemLevelledList() const; - const RefIdDataContainer& getLights() const; - const RefIdDataContainer& getLocpicks() const; - const RefIdDataContainer& getMiscellaneous() const; - const RefIdDataContainer& getNPCs() const; + void save(int index, ESM::ESMWriter& writer) const; + + //RECORD CONTAINERS ACCESS METHODS + const RefIdDataContainer& getBooks() const; + const RefIdDataContainer& getActivators() const; + const RefIdDataContainer& getPotions() const; + const RefIdDataContainer& getApparati() const; + const RefIdDataContainer& getArmors() const; + const RefIdDataContainer& getClothing() const; + const RefIdDataContainer& getContainers() const; + const RefIdDataContainer& getCreatures() const; + const RefIdDataContainer& getDoors() const; + const RefIdDataContainer& getIngredients() const; + const RefIdDataContainer& getCreatureLevelledLists() const; + const RefIdDataContainer& getItemLevelledList() const; + const RefIdDataContainer& getLights() const; + const RefIdDataContainer& getLocpicks() const; + const RefIdDataContainer& getMiscellaneous() const; + const RefIdDataContainer& getNPCs() const; }; } #endif + + From 4a1987ddecb6385db2b26402e066d9d79f851f7b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Dec 2013 18:41:16 +0100 Subject: [PATCH 038/168] correcting --- .../opencs/model/tools/referenceablecheck.cpp | 28 +----- apps/opencs/model/tools/tools.cpp | 93 ++++++++++--------- apps/opencs/model/world/refidcollection.hpp | 47 +++++----- 3 files changed, 74 insertions(+), 94 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index ad52c59621..3ca203bdf5 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -945,18 +945,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI } else //checking if there is such class { - bool nosuchclass(true); - - for (int i = 0; i < mClasses.getSize(); ++i) - { - if (dynamic_cast(mClasses.getRecord(i).get()).mId == NPC.mClass) - { - nosuchclass = false; - break; - } - } - - if (nosuchclass) + if (mClasses.searchId(NPC.mClass)) { messages.push_back(id.toString() + "|" + NPC.mId + " has invalid class"); } @@ -1002,18 +991,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI messages.push_back(id.toString() + "|" + NPC.mId + " has negative rank"); } - bool nosuchfaction(true); - - for (int i = 0; i < mFactions.getSize(); ++i) - { - if (dynamic_cast(mFactions.getRecord(i).get()).mId == NPC.mFaction) - { - nosuchfaction = false; - break; - } - } - - if (nosuchfaction) + if (mFactions.searchId(NPC.mFaction) == -1) { messages.push_back(id.toString() + "|" + NPC.mId + " has invalid faction"); } @@ -1026,7 +1004,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI if (NPC.mHair.empty()) { - messages.push_back(id.toString() + "|" + NPC.mId + " has no har"); + messages.push_back(id.toString() + "|" + NPC.mId + " has no hair"); } //TODO: reputation, Disposition, rank, everything else diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index c25811ea4c..64e39ad2f6 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -21,7 +21,7 @@ #include "spellcheck.hpp" #include "referenceablecheck.hpp" -CSMDoc::Operation* CSMTools::Tools::get(int type) +CSMDoc::Operation *CSMTools::Tools::get (int type) { switch (type) { @@ -31,60 +31,60 @@ CSMDoc::Operation* CSMTools::Tools::get(int type) return 0; } -const CSMDoc::Operation* CSMTools::Tools::get(int type) const +const CSMDoc::Operation *CSMTools::Tools::get (int type) const { - return const_cast(this)->get(type); + return const_cast (this)->get (type); } -CSMDoc::Operation* CSMTools::Tools::getVerifier() +CSMDoc::Operation *CSMTools::Tools::getVerifier() { if (!mVerifier) { - mVerifier = new CSMDoc::Operation(CSMDoc::State_Verifying, false); + mVerifier = new CSMDoc::Operation (CSMDoc::State_Verifying, false); - connect(mVerifier, SIGNAL(progress(int, int, int)), this, SIGNAL(progress(int, int, int))); - connect(mVerifier, SIGNAL(done(int)), this, SIGNAL(done(int))); - connect(mVerifier, SIGNAL(reportMessage(const QString&, int)), - this, SLOT(verifierMessage(const QString&, int))); + connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); + connect (mVerifier, SIGNAL (done (int)), this, SIGNAL (done (int))); + connect (mVerifier, SIGNAL (reportMessage (const QString&, int)), + this, SLOT (verifierMessage (const QString&, int))); std::vector mandatoryIds; // I want C++11, damn it! - mandatoryIds.push_back("Day"); - mandatoryIds.push_back("DaysPassed"); - mandatoryIds.push_back("GameHour"); - mandatoryIds.push_back("Month"); - mandatoryIds.push_back("PCRace"); - mandatoryIds.push_back("PCVampire"); - mandatoryIds.push_back("PCWerewolf"); - mandatoryIds.push_back("PCYear"); + mandatoryIds.push_back ("Day"); + mandatoryIds.push_back ("DaysPassed"); + mandatoryIds.push_back ("GameHour"); + mandatoryIds.push_back ("Month"); + mandatoryIds.push_back ("PCRace"); + mandatoryIds.push_back ("PCVampire"); + mandatoryIds.push_back ("PCWerewolf"); + mandatoryIds.push_back ("PCYear"); - mVerifier->appendStage(new MandatoryIdStage(mData.getGlobals(), - CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Globals), mandatoryIds)); + mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(), + CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds)); - mVerifier->appendStage(new SkillCheckStage(mData.getSkills())); + mVerifier->appendStage (new SkillCheckStage (mData.getSkills())); - mVerifier->appendStage(new ClassCheckStage(mData.getClasses())); + mVerifier->appendStage (new ClassCheckStage (mData.getClasses())); - mVerifier->appendStage(new FactionCheckStage(mData.getFactions())); + mVerifier->appendStage (new FactionCheckStage (mData.getFactions())); - mVerifier->appendStage(new RaceCheckStage(mData.getRaces())); + mVerifier->appendStage (new RaceCheckStage (mData.getRaces())); - mVerifier->appendStage(new SoundCheckStage(mData.getSounds())); + mVerifier->appendStage (new SoundCheckStage (mData.getSounds())); - mVerifier->appendStage(new RegionCheckStage(mData.getRegions())); + mVerifier->appendStage (new RegionCheckStage (mData.getRegions())); - mVerifier->appendStage(new BirthsignCheckStage(mData.getBirthsigns())); + mVerifier->appendStage (new BirthsignCheckStage (mData.getBirthsigns())); - mVerifier->appendStage(new SpellCheckStage(mData.getSpells())); + mVerifier->appendStage (new SpellCheckStage (mData.getSpells())); - mVerifier->appendStage(new ReferenceableCheckStage(mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions())); + mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions())); } return mVerifier; } -CSMTools::Tools::Tools(CSMWorld::Data& data) : mData(data), mVerifier(0), mNextReportNumber(0) +CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0) { - for (std::map::iterator iter(mReports.begin()); iter != mReports.end(); ++iter) + for (std::map::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter) delete iter->second; } @@ -95,17 +95,17 @@ CSMTools::Tools::~Tools() CSMWorld::UniversalId CSMTools::Tools::runVerifier() { - mReports.insert(std::make_pair(mNextReportNumber++, new ReportModel)); - mActiveReports[CSMDoc::State_Verifying] = mNextReportNumber - 1; + mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); + mActiveReports[CSMDoc::State_Verifying] = mNextReportNumber-1; getVerifier()->start(); - return CSMWorld::UniversalId(CSMWorld::UniversalId::Type_VerificationResults, mNextReportNumber - 1); + return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, mNextReportNumber-1); } -void CSMTools::Tools::abortOperation(int type) +void CSMTools::Tools::abortOperation (int type) { - if (CSMDoc::Operation* operation = get(type)) + if (CSMDoc::Operation *operation = get (type)) operation->abort(); } @@ -113,32 +113,33 @@ int CSMTools::Tools::getRunningOperations() const { static const int sOperations[] = { - CSMDoc::State_Verifying, + CSMDoc::State_Verifying, -1 }; int result = 0; - for (int i = 0; sOperations[i] != -1; ++i) - if (const CSMDoc::Operation* operation = get(sOperations[i])) + for (int i=0; sOperations[i]!=-1; ++i) + if (const CSMDoc::Operation *operation = get (sOperations[i])) if (operation->isRunning()) result |= sOperations[i]; return result; } -CSMTools::ReportModel* CSMTools::Tools::getReport(const CSMWorld::UniversalId& id) +CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id) { - if (id.getType() != CSMWorld::UniversalId::Type_VerificationResults) - throw std::logic_error("invalid request for report model: " + id.toString()); + if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults) + throw std::logic_error ("invalid request for report model: " + id.toString()); - return mReports.at(id.getIndex()); + return mReports.at (id.getIndex()); } -void CSMTools::Tools::verifierMessage(const QString& message, int type) +void CSMTools::Tools::verifierMessage (const QString& message, int type) { - std::map::iterator iter = mActiveReports.find(type); + std::map::iterator iter = mActiveReports.find (type); - if (iter != mActiveReports.end()) - mReports[iter->second]->add(message.toStdString()); + if (iter!=mActiveReports.end()) + mReports[iter->second]->add (message.toStdString()); } + diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 1a21de8f4f..328680d85a 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -25,9 +25,9 @@ namespace CSMWorld public: - RefIdColumn(int columnId, Display displayType, - int flag = Flag_Table | Flag_Dialogue, bool editable = true, - bool userEditable = true); + RefIdColumn (int columnId, Display displayType, + int flag = Flag_Table | Flag_Dialogue, bool editable = true, + bool userEditable = true); virtual bool isEditable() const; @@ -40,11 +40,11 @@ namespace CSMWorld RefIdData mData; std::deque mColumns; - std::map mAdapters; + std::map mAdapters; private: - const RefIdAdapter& findAdaptor(UniversalId::Type) const; + const RefIdAdapter& findAdaptor (UniversalId::Type) const; ///< Throws an exception if no adaptor for \a Type can be found. public: @@ -55,61 +55,62 @@ namespace CSMWorld virtual int getSize() const; - virtual std::string getId(int index) const; + virtual std::string getId (int index) const; - virtual int getIndex(const std::string& id) const; + virtual int getIndex (const std::string& id) const; virtual int getColumns() const; - virtual const ColumnBase& getColumn(int column) const; + virtual const ColumnBase& getColumn (int column) const; - virtual QVariant getData(int index, int column) const; + virtual QVariant getData (int index, int column) const; - virtual void setData(int index, int column, const QVariant& data); + virtual void setData (int index, int column, const QVariant& data); - virtual void removeRows(int index, int count); + virtual void removeRows (int index, int count); - virtual void appendBlankRecord(const std::string& id, UniversalId::Type type); + virtual void appendBlankRecord (const std::string& id, UniversalId::Type type); ///< \param type Will be ignored, unless the collection supports multiple record types - virtual int searchId(const std::string& id) const; + virtual int searchId (const std::string& id) const; ////< Search record with \a id. /// \return index of record (if found) or -1 (not found) - virtual void replace(int index, const RecordBase& record); + virtual void replace (int index, const RecordBase& record); ///< If the record type does not match, an exception is thrown. /// /// \attention \a record must not change the ID. - virtual void appendRecord(const RecordBase& record, UniversalId::Type type); + virtual void appendRecord (const RecordBase& record, UniversalId::Type type); ///< If the record type does not match, an exception is thrown. /// ///< \param type Will be ignored, unless the collection supports multiple record types - virtual const RecordBase& getRecord(const std::string& id) const; + virtual const RecordBase& getRecord (const std::string& id) const; - virtual const RecordBase& getRecord(int index) const; + virtual const RecordBase& getRecord (int index) const; - void load(ESM::ESMReader& reader, bool base, UniversalId::Type type); + void load (ESM::ESMReader& reader, bool base, UniversalId::Type type); - virtual int getAppendIndex(const std::string& id, UniversalId::Type type) const; + virtual int getAppendIndex (const std::string& id, UniversalId::Type type) const; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual std::vector getIds(bool listDeleted) const; + virtual std::vector getIds (bool listDeleted) const; ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list - virtual bool reorderRows(int baseIndex, const std::vector& newOrder); + virtual bool reorderRows (int baseIndex, const std::vector& newOrder); ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). /// /// \return Success? - void save(int index, ESM::ESMWriter& writer) const; + void save (int index, ESM::ESMWriter& writer) const; - const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( + const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( }; } #endif + From a7de04d0a4acd27555ebeebc84a3ffd4182896fc Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Dec 2013 18:46:18 +0100 Subject: [PATCH 039/168] reverting refiddata.cpp --- apps/opencs/model/world/refiddata.cpp | 214 +++++++++++++------------- 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 9c0a857a5b..5af215989d 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -9,187 +9,187 @@ CSMWorld::RefIdDataContainerBase::~RefIdDataContainerBase() {} CSMWorld::RefIdData::RefIdData() { - mRecordContainers.insert(std::make_pair(UniversalId::Type_Activator, &mActivators)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Potion, &mPotions)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Apparatus, &mApparati)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Armor, &mArmors)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Book, &mBooks)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Clothing, &mClothing)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Container, &mContainers)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Creature, &mCreatures)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Door, &mDoors)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Ingredient, &mIngredients)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, - &mCreatureLevelledLists)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_ItemLevelledList, &mItemLevelledLists)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Light, &mLights)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Lockpick, &mLockpicks)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Miscellaneous, &mMiscellaneous)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Npc, &mNpcs)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Probe, &mProbes)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Repair, &mRepairs)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Static, &mStatics)); - mRecordContainers.insert(std::make_pair(UniversalId::Type_Weapon, &mWeapons)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Activator, &mActivators)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Potion, &mPotions)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Apparatus, &mApparati)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Armor, &mArmors)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Book, &mBooks)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Clothing, &mClothing)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Container, &mContainers)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Creature, &mCreatures)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Door, &mDoors)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Ingredient, &mIngredients)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, + &mCreatureLevelledLists)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_ItemLevelledList, &mItemLevelledLists)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Light, &mLights)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Lockpick, &mLockpicks)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Miscellaneous, &mMiscellaneous)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Npc, &mNpcs)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Probe, &mProbes)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Repair, &mRepairs)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Static, &mStatics)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Weapon, &mWeapons)); } -CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::globalToLocalIndex(int index) const +CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::globalToLocalIndex (int index) const { - for (std::map::const_iterator iter( - mRecordContainers.begin()); iter != mRecordContainers.end(); ++iter) + for (std::map::const_iterator iter ( + mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) { - if (index < iter->second->getSize()) - return LocalIndex(index, iter->first); + if (indexsecond->getSize()) + return LocalIndex (index, iter->first); index -= iter->second->getSize(); } - throw std::runtime_error("RefIdData index out of range"); + throw std::runtime_error ("RefIdData index out of range"); } -int CSMWorld::RefIdData::localToGlobalIndex(const LocalIndex& index) -const +int CSMWorld::RefIdData::localToGlobalIndex (const LocalIndex& index) + const { - std::map::const_iterator end = - mRecordContainers.find(index.second); + std::map::const_iterator end = + mRecordContainers.find (index.second); - if (end == mRecordContainers.end()) - throw std::logic_error("invalid local index type"); + if (end==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); int globalIndex = index.first; - for (std::map::const_iterator iter( - mRecordContainers.begin()); iter != end; ++iter) + for (std::map::const_iterator iter ( + mRecordContainers.begin()); iter!=end; ++iter) globalIndex += iter->second->getSize(); return globalIndex; } -CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId( +CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId ( const std::string& id) const { - std::string id2 = Misc::StringUtils::lowerCase(id); + std::string id2 = Misc::StringUtils::lowerCase (id); - std::map >::const_iterator iter = mIndex.find(id2); + std::map >::const_iterator iter = mIndex.find (id2); - if (iter == mIndex.end()) - return std::make_pair(-1, CSMWorld::UniversalId::Type_None); + if (iter==mIndex.end()) + return std::make_pair (-1, CSMWorld::UniversalId::Type_None); return iter->second; } -void CSMWorld::RefIdData::erase(int index, int count) +void CSMWorld::RefIdData::erase (int index, int count) { - LocalIndex localIndex = globalToLocalIndex(index); + LocalIndex localIndex = globalToLocalIndex (index); - std::map::const_iterator iter = - mRecordContainers.find(localIndex.second); + std::map::const_iterator iter = + mRecordContainers.find (localIndex.second); - while (count > 0 && iter != mRecordContainers.end()) + while (count>0 && iter!=mRecordContainers.end()) { int size = iter->second->getSize(); - if (localIndex.first + count > size) + if (localIndex.first+count>size) { - erase(localIndex, size - localIndex.first); - count -= size - localIndex.first; + erase (localIndex, size-localIndex.first); + count -= size-localIndex.first; ++iter; - if (iter == mRecordContainers.end()) - throw std::runtime_error("invalid count value for erase operation"); + if (iter==mRecordContainers.end()) + throw std::runtime_error ("invalid count value for erase operation"); localIndex.first = 0; localIndex.second = iter->first; } else { - erase(localIndex, count); + erase (localIndex, count); count = 0; } } } -const CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord(const LocalIndex& index) const +const CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) const { - std::map::const_iterator iter = - mRecordContainers.find(index.second); + std::map::const_iterator iter = + mRecordContainers.find (index.second); - if (iter == mRecordContainers.end()) - throw std::logic_error("invalid local index type"); + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); - return iter->second->getRecord(index.first); + return iter->second->getRecord (index.first); } -CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord(const LocalIndex& index) +CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) { - std::map::iterator iter = - mRecordContainers.find(index.second); + std::map::iterator iter = + mRecordContainers.find (index.second); - if (iter == mRecordContainers.end()) - throw std::logic_error("invalid local index type"); + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); - return iter->second->getRecord(index.first); + return iter->second->getRecord (index.first); } -void CSMWorld::RefIdData::appendRecord(UniversalId::Type type, const std::string& id) +void CSMWorld::RefIdData::appendRecord (UniversalId::Type type, const std::string& id) { - std::map::iterator iter = - mRecordContainers.find(type); + std::map::iterator iter = + mRecordContainers.find (type); - if (iter == mRecordContainers.end()) - throw std::logic_error("invalid local index type"); + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); - iter->second->appendRecord(id); + iter->second->appendRecord (id); - mIndex.insert(std::make_pair(Misc::StringUtils::lowerCase(id), - LocalIndex(iter->second->getSize() - 1, type))); + mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id), + LocalIndex (iter->second->getSize()-1, type))); } -int CSMWorld::RefIdData::getAppendIndex(UniversalId::Type type) const +int CSMWorld::RefIdData::getAppendIndex (UniversalId::Type type) const { int index = 0; - for (std::map::const_iterator iter( - mRecordContainers.begin()); iter != mRecordContainers.end(); ++iter) + for (std::map::const_iterator iter ( + mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) { index += iter->second->getSize(); - if (type == iter->first) + if (type==iter->first) break; } return index; } -void CSMWorld::RefIdData::load(const LocalIndex& index, ESM::ESMReader& reader, bool base) +void CSMWorld::RefIdData::load (const LocalIndex& index, ESM::ESMReader& reader, bool base) { - std::map::iterator iter = - mRecordContainers.find(index.second); + std::map::iterator iter = + mRecordContainers.find (index.second); - if (iter == mRecordContainers.end()) - throw std::logic_error("invalid local index type"); + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); - iter->second->load(index.first, reader, base); + iter->second->load (index.first, reader, base); } -void CSMWorld::RefIdData::erase(const LocalIndex& index, int count) +void CSMWorld::RefIdData::erase (const LocalIndex& index, int count) { - std::map::iterator iter = - mRecordContainers.find(index.second); + std::map::iterator iter = + mRecordContainers.find (index.second); - if (iter == mRecordContainers.end()) - throw std::logic_error("invalid local index type"); + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); - for (int i = index.first; i < index.first + count; ++i) + for (int i=index.first; i::iterator result = - mIndex.find(Misc::StringUtils::lowerCase(iter->second->getId(i))); + mIndex.find (Misc::StringUtils::lowerCase (iter->second->getId (i))); - if (result != mIndex.end()) - mIndex.erase(result); + if (result!=mIndex.end()) + mIndex.erase (result); } - iter->second->erase(index.first, count); + iter->second->erase (index.first, count); } int CSMWorld::RefIdData::getSize() const @@ -197,39 +197,39 @@ int CSMWorld::RefIdData::getSize() const return mIndex.size(); } -std::vector CSMWorld::RefIdData::getIds(bool listDeleted) const +std::vector CSMWorld::RefIdData::getIds (bool listDeleted) const { std::vector ids; - for (std::map::const_iterator iter(mIndex.begin()); iter != mIndex.end(); - ++iter) + for (std::map::const_iterator iter (mIndex.begin()); iter!=mIndex.end(); + ++iter) { - if (listDeleted || !getRecord(iter->second).isDeleted()) + if (listDeleted || !getRecord (iter->second).isDeleted()) { - std::map::const_iterator container = - mRecordContainers.find(iter->second.second); + std::map::const_iterator container = + mRecordContainers.find (iter->second.second); - if (container == mRecordContainers.end()) - throw std::logic_error("Invalid referenceable ID type"); + if (container==mRecordContainers.end()) + throw std::logic_error ("Invalid referenceable ID type"); - ids.push_back(container->second->getId(iter->second.first)); + ids.push_back (container->second->getId (iter->second.first)); } } return ids; } -void CSMWorld::RefIdData::save(int index, ESM::ESMWriter& writer) const +void CSMWorld::RefIdData::save (int index, ESM::ESMWriter& writer) const { - LocalIndex localIndex = globalToLocalIndex(index); + LocalIndex localIndex = globalToLocalIndex (index); - std::map::const_iterator iter = - mRecordContainers.find(localIndex.second); + std::map::const_iterator iter = + mRecordContainers.find (localIndex.second); - if (iter == mRecordContainers.end()) - throw std::logic_error("invalid local index type"); + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); - iter->second->save(localIndex.first, writer); + iter->second->save (localIndex.first, writer); } const CSMWorld::RefIdDataContainer< ESM::Book >& CSMWorld::RefIdData::getBooks() const From 79bc149c73f529a80f02b829a57da2581382d839 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Dec 2013 18:47:19 +0100 Subject: [PATCH 040/168] reverting refidata.hpp --- apps/opencs/model/world/refiddata.hpp | 142 +++++++++++++------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 719b4b9224..51f5484996 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -41,19 +41,19 @@ namespace CSMWorld virtual int getSize() const = 0; - virtual const RecordBase& getRecord(int index) const = 0; + virtual const RecordBase& getRecord (int index) const = 0; - virtual RecordBase& getRecord(int index) = 0; + virtual RecordBase& getRecord (int index)= 0; - virtual void appendRecord(const std::string& id) = 0; + virtual void appendRecord (const std::string& id) = 0; - virtual void load(int index, ESM::ESMReader& reader, bool base) = 0; + virtual void load (int index, ESM::ESMReader& reader, bool base) = 0; - virtual void erase(int index, int count) = 0; + virtual void erase (int index, int count) = 0; - virtual std::string getId(int index) const = 0; + virtual std::string getId (int index) const = 0; - virtual void save(int index, ESM::ESMWriter& writer) const = 0; + virtual void save (int index, ESM::ESMWriter& writer) const = 0; }; template @@ -63,91 +63,90 @@ namespace CSMWorld virtual int getSize() const; - virtual const RecordBase& getRecord(int index) const; + virtual const RecordBase& getRecord (int index) const; - virtual RecordBase& getRecord(int index); + virtual RecordBase& getRecord (int index); - virtual void appendRecord(const std::string& id); + virtual void appendRecord (const std::string& id); - virtual void load(int index, ESM::ESMReader& reader, bool base); + virtual void load (int index, ESM::ESMReader& reader, bool base); - virtual void erase(int index, int count); + virtual void erase (int index, int count); - virtual std::string getId(int index) const; + virtual std::string getId (int index) const; - virtual void save(int index, ESM::ESMWriter& writer) const; + virtual void save (int index, ESM::ESMWriter& writer) const; }; template int RefIdDataContainer::getSize() const { - return static_cast(mContainer.size()); + return static_cast (mContainer.size()); } template - const RecordBase& RefIdDataContainer::getRecord(int index) const + const RecordBase& RefIdDataContainer::getRecord (int index) const { - return mContainer.at(index); + return mContainer.at (index); } template - RecordBase& RefIdDataContainer::getRecord(int index) + RecordBase& RefIdDataContainer::getRecord (int index) { - return mContainer.at(index); + return mContainer.at (index); } template - void RefIdDataContainer::appendRecord(const std::string& id) + void RefIdDataContainer::appendRecord (const std::string& id) { Record record; record.mModified.mId = id; record.mModified.blank(); record.mState = RecordBase::State_ModifiedOnly; - mContainer.push_back(record); + mContainer.push_back (record); } template - void RefIdDataContainer::load(int index, ESM::ESMReader& reader, bool base) + void RefIdDataContainer::load (int index, ESM::ESMReader& reader, bool base) { - (base ? mContainer.at(index).mBase : mContainer.at(index).mModified).load(reader); + (base ? mContainer.at (index).mBase : mContainer.at (index).mModified).load (reader); } template - void RefIdDataContainer::erase(int index, int count) + void RefIdDataContainer::erase (int index, int count) { - if (index < 0 || index + count >= getSize()) - throw std::runtime_error("invalid RefIdDataContainer index"); + if (index<0 || index+count>=getSize()) + throw std::runtime_error ("invalid RefIdDataContainer index"); - mContainer.erase(mContainer.begin() + index, mContainer.begin() + index + count); + mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); } template - std::string RefIdDataContainer::getId(int index) const + std::string RefIdDataContainer::getId (int index) const { - return mContainer.at(index).get().mId; + return mContainer.at (index).get().mId; } template - void RefIdDataContainer::save(int index, ESM::ESMWriter& writer) const + void RefIdDataContainer::save (int index, ESM::ESMWriter& writer) const { - CSMWorld::RecordBase::State state = mContainer.at(index).mState; + CSMWorld::RecordBase::State state = mContainer.at (index).mState; - if (state == CSMWorld::RecordBase::State_Modified || - state == CSMWorld::RecordBase::State_ModifiedOnly) + if (state==CSMWorld::RecordBase::State_Modified || + state==CSMWorld::RecordBase::State_ModifiedOnly) { std::string type; - - for (int i = 0; i < 4; ++i) + for (int i=0; i<4; ++i) /// \todo make endianess agnostic (change ESMWriter interface?) - type += reinterpret_cast(&mContainer.at(index).mModified.sRecordId)[i]; + type += reinterpret_cast (&mContainer.at (index).mModified.sRecordId)[i]; - writer.startRecord(type); - writer.writeHNCString("NAME", getId(index)); - mContainer.at(index).mModified.save(writer); - writer.endRecord(type); + writer.startRecord (type); + writer.writeHNCString ("NAME", getId (index)); + mContainer.at (index).mModified.save (writer); + writer.endRecord (type); } - else if (state == CSMWorld::RecordBase::State_Deleted) + else if (state==CSMWorld::RecordBase::State_Deleted) { /// \todo write record with delete flag } @@ -185,59 +184,59 @@ namespace CSMWorld std::map mIndex; - std::map mRecordContainers; + std::map mRecordContainers; - void erase(const LocalIndex& index, int count); + void erase (const LocalIndex& index, int count); ///< Must not spill over into another type. public: RefIdData(); - LocalIndex globalToLocalIndex(int index) const; + LocalIndex globalToLocalIndex (int index) const; - int localToGlobalIndex(const LocalIndex& index) const; + int localToGlobalIndex (const LocalIndex& index) const; - LocalIndex searchId(const std::string& id) const; + LocalIndex searchId (const std::string& id) const; - void erase(int index, int count); + void erase (int index, int count); - const RecordBase& getRecord(const LocalIndex& index) const; + const RecordBase& getRecord (const LocalIndex& index) const; - RecordBase& getRecord(const LocalIndex& index); + RecordBase& getRecord (const LocalIndex& index); - void appendRecord(UniversalId::Type type, const std::string& id); + void appendRecord (UniversalId::Type type, const std::string& id); - int getAppendIndex(UniversalId::Type type) const; + int getAppendIndex (UniversalId::Type type) const; - void load(const LocalIndex& index, ESM::ESMReader& reader, bool base); + void load (const LocalIndex& index, ESM::ESMReader& reader, bool base); int getSize() const; - std::vector getIds(bool listDeleted = true) const; + std::vector getIds (bool listDeleted = true) const; ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list - void save(int index, ESM::ESMWriter& writer) const; + void save (int index, ESM::ESMWriter& writer) const; - //RECORD CONTAINERS ACCESS METHODS - const RefIdDataContainer& getBooks() const; - const RefIdDataContainer& getActivators() const; - const RefIdDataContainer& getPotions() const; - const RefIdDataContainer& getApparati() const; - const RefIdDataContainer& getArmors() const; - const RefIdDataContainer& getClothing() const; - const RefIdDataContainer& getContainers() const; - const RefIdDataContainer& getCreatures() const; - const RefIdDataContainer& getDoors() const; - const RefIdDataContainer& getIngredients() const; - const RefIdDataContainer& getCreatureLevelledLists() const; - const RefIdDataContainer& getItemLevelledList() const; - const RefIdDataContainer& getLights() const; - const RefIdDataContainer& getLocpicks() const; - const RefIdDataContainer& getMiscellaneous() const; - const RefIdDataContainer& getNPCs() const; + //RECORD CONTAINERS ACCESS METHODS + const RefIdDataContainer& getBooks() const; + const RefIdDataContainer& getActivators() const; + const RefIdDataContainer& getPotions() const; + const RefIdDataContainer& getApparati() const; + const RefIdDataContainer& getArmors() const; + const RefIdDataContainer& getClothing() const; + const RefIdDataContainer& getContainers() const; + const RefIdDataContainer& getCreatures() const; + const RefIdDataContainer& getDoors() const; + const RefIdDataContainer& getIngredients() const; + const RefIdDataContainer& getCreatureLevelledLists() const; + const RefIdDataContainer& getItemLevelledList() const; + const RefIdDataContainer& getLights() const; + const RefIdDataContainer& getLocpicks() const; + const RefIdDataContainer& getMiscellaneous() const; + const RefIdDataContainer& getNPCs() const; }; } @@ -245,3 +244,4 @@ namespace CSMWorld + From cb723710fefd35f8b4b83550ecc06878c37812e5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Dec 2013 19:24:53 +0100 Subject: [PATCH 041/168] Corrected stupid typo. --- apps/opencs/model/tools/referenceablecheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 3ca203bdf5..2b796ccc04 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -945,7 +945,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI } else //checking if there is such class { - if (mClasses.searchId(NPC.mClass)) + if (mClasses.searchId(NPC.mClass) == -1) { messages.push_back(id.toString() + "|" + NPC.mId + " has invalid class"); } From 8201c97abf3a62f662790e556c44877541ad587b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 2 Jan 2014 20:20:18 +0100 Subject: [PATCH 042/168] Inventory item template. --- .../opencs/model/tools/referenceablecheck.cpp | 64 ++++++++++--------- .../opencs/model/tools/referenceablecheck.hpp | 3 + 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 2b796ccc04..0b09f1f5d3 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -186,35 +186,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::Ref const ESM::Book& Book = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, Book.mId); - //Checking for name - if (Book.mName.empty()) - { - messages.push_back(id.toString() + "|" + Book.mId + " has an empty name"); - } - - //Checking for weight - if (Book.mData.mWeight < 0) - { - messages.push_back(id.toString() + "|" + Book.mId + " has negative weight"); - } - - //Checking for value - if (Book.mData.mValue < 0) - { - messages.push_back(id.toString() + "|" + Book.mId + " has negative value"); - } - -//checking for model - if (Book.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Book.mId + " has no model"); - } - - //checking for icon - if (Book.mIcon.empty()) - { - messages.push_back(id.toString() + "|" + Book.mId + " has no icon"); - } + inventoryItemCheck(Book, messages); //checking for enchantment points if (Book.mData.mEnchant < 0) @@ -1009,3 +981,37 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI //TODO: reputation, Disposition, rank, everything else } + +//Templates begins here + +void CSMTools::ReferenceableCheckStage::inventoryItemCheck(const item& item, std::vector< std::string >& messages) +{ + if (item.mName.empty()) + { + messages.push_back(id.toString() + "|" + item.mId + " has an empty name"); + } + + //Checking for weight + if (item.mData.mWeight < 0) + { + messages.push_back(id.toString() + "|" + item.mId + " has negative weight"); + } + + //Checking for value + if (item.mData.mValue < 0) + { + messages.push_back(id.toString() + "|" + item.mId + " has negative value"); + } + +//checking for model + if (item.mModel.empty()) + { + messages.push_back(id.toString() + "|" + item.mId + " has no model"); + } + + //checking for icon + if (item.mIcon.empty()) + { + messages.push_back(id.toString() + "|" + item.mId + " has no icon"); + } +} diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index fcf774f148..43bb54fa79 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -34,6 +34,9 @@ namespace CSMTools void miscCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + //TEMPLATE CHECKS + template void inventoryItemCheck(const item& item, std::vector& messages); //for all inventory items. + const CSMWorld::RefIdData& mReferencables; const CSMWorld::IdCollection& mRaces; const CSMWorld::IdCollection& mClasses; From 24f090ca985643f488f49457b3e45e22ce726b67 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 3 Jan 2014 11:31:54 +0100 Subject: [PATCH 043/168] Finishing stuff. --- .../opencs/model/tools/referenceablecheck.cpp | 565 +++++++++--------- .../opencs/model/tools/referenceablecheck.hpp | 10 +- apps/opencs/model/world/refiddata.cpp | 20 + apps/opencs/model/world/refiddata.hpp | 4 + 4 files changed, 301 insertions(+), 298 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 0b09f1f5d3..65bee314c6 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -167,6 +167,46 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str npcCheck(stage, mReferencables.getNPCs(), messages); return; } + + stage -= NPCSize; + + const int WeaponSize(mReferencables.getWeapons().getSize()); + + if (stage < WeaponSize) + { + weaponCheck(stage, mReferencables.getWeapons(), messages); + return; + } + + stage -= WeaponSize; + + const int ProbeSize(mReferencables.getProbes().getSize()); + + if (stage < ProbeSize) + { + probeCheck(stage, mReferencables.getProbes(), messages); + return; + } + + stage -= ProbeSize; + + const int RepairSize(mReferencables.getRepairs().getSize()); + + if (stage < RepairSize) + { + repairCheck(stage, mReferencables.getRepairs(), messages); + return; + } + + stage -= RepairSize; + + const int StaticSize(mReferencables.getStatics().getSize()); + + if (stage < StaticSize) + { + staticCheck(stage, mReferencables.getStatics(), messages); + return; + } } int CSMTools::ReferenceableCheckStage::setup() @@ -186,13 +226,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::Ref const ESM::Book& Book = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, Book.mId); - inventoryItemCheck(Book, messages); - - //checking for enchantment points - if (Book.mData.mEnchant < 0) - { - messages.push_back(id.toString() + "|" + Book.mId + " has negative enchantment"); - } + inventoryItemCheck(Book, messages, id.toString(), true); } void CSMTools::ReferenceableCheckStage::activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages) @@ -226,36 +260,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck(int stage, const CSMWorld::R const ESM::Potion& Potion = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, Potion.mId); - //Checking for name - if (Potion.mName.empty()) - { - messages.push_back(id.toString() + "|" + Potion.mId + " has an empty name"); - } - - //Checking for weight - if (Potion.mData.mWeight < 0) - { - messages.push_back(id.toString() + "|" + Potion.mId + " has negative weight"); - } - - //Checking for value - if (Potion.mData.mValue < 0) - { - messages.push_back(id.toString() + "|" + Potion.mId + " has negative value"); - } - -//checking for model - if (Potion.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Potion.mId + " has no model"); - } - - //checking for icon - if (Potion.mIcon.empty()) - { - messages.push_back(id.toString() + "|" + Potion.mId + " has no icon"); - } - + inventoryItemCheck(Potion, messages, id.toString()); //IIRC potion can have empty effects list just fine. } @@ -272,41 +277,10 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(int stage, const CSMWorld const ESM::Apparatus& Apparatus = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Apparatus, Apparatus.mId); - //Checking for name - if (Apparatus.mName.empty()) - { - messages.push_back(id.toString() + "|" + Apparatus.mId + " has an empty name"); - } - - //Checking for weight - if (Apparatus.mData.mWeight < 0) - { - messages.push_back(id.toString() + "|" + Apparatus.mId + " has negative weight"); - } - - //Checking for value - if (Apparatus.mData.mValue < 0) - { - messages.push_back(id.toString() + "|" + Apparatus.mId + " has negative value"); - } - -//checking for model - if (Apparatus.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Apparatus.mId + " has no model"); - } - - //checking for icon - if (Apparatus.mIcon.empty()) - { - messages.push_back(id.toString() + "|" + Apparatus.mId + " has no icon"); - } + inventoryItemCheck(Apparatus, messages, id.toString()); //checking for quality, 0 → apparatus is basicly useless, any negative → apparatus is harmfull instead of helpfull - if (Apparatus.mData.mQuality <= 0) - { - messages.push_back(id.toString() + "|" + Apparatus.mId + " has non-positive quality"); - } + toolCheck(Apparatus, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::armorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Armor >& records, std::vector< std::string >& messages) @@ -321,41 +295,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck(int stage, const CSMWorld::Re const ESM::Armor& Armor = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Armor, Armor.mId); - //Checking for name - if (Armor.mName.empty()) - { - messages.push_back(id.toString() + "|" + Armor.mId + " has an empty name"); - } - - //Checking for weight - if (Armor.mData.mWeight < 0) - { - messages.push_back(id.toString() + "|" + Armor.mId + " has negative weight"); - } - - //Checking for value - if (Armor.mData.mValue < 0) - { - messages.push_back(id.toString() + "|" + Armor.mId + " has negative value"); - } - -//checking for model - if (Armor.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Armor.mId + " has no model"); - } - - //checking for icon - if (Armor.mIcon.empty()) - { - messages.push_back(id.toString() + "|" + Armor.mId + " has no icon"); - } - - //checking for enchantment points - if (Armor.mData.mEnchant < 0) - { - messages.push_back(id.toString() + "|" + Armor.mId + " has negative enchantment"); - } + inventoryItemCheck(Armor, messages, id.toString(), true); //checking for armor class, armor should have poistive armor class, but 0 is considered legal if (Armor.mData.mArmor < 0) @@ -363,7 +303,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck(int stage, const CSMWorld::Re messages.push_back(id.toString() + "|" + Armor.mId + " has negative armor class"); } - //checking for health. Only positive numbers are allowed, and 0 is illegal + //checking for health. Only positive numbers are allowed, or 0 is illegal if (Armor.mData.mHealth <= 0) { messages.push_back(id.toString() + "|" + Armor.mId + " has non positive health"); @@ -381,42 +321,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(int stage, const CSMWorld: const ESM::Clothing& Clothing = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, Clothing.mId); - - //Checking for name - if (Clothing.mName.empty()) - { - messages.push_back(id.toString() + "|" + Clothing.mId + " has an empty name"); - } - - //Checking for weight - if (Clothing.mData.mWeight < 0) - { - messages.push_back(id.toString() + "|" + Clothing.mId + " has negative weight"); - } - - //Checking for value - if (Clothing.mData.mValue < 0) - { - messages.push_back(id.toString() + "|" + Clothing.mId + " has negative value"); - } - -//checking for model - if (Clothing.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Clothing.mId + " has no model"); - } - - //checking for icon - if (Clothing.mIcon.empty()) - { - messages.push_back(id.toString() + "|" + Clothing.mId + " has no icon"); - } - - //checking for enchantment points - if (Clothing.mData.mEnchant < 0) - { - messages.push_back(id.toString() + "|" + Clothing.mId + " has negative enchantment"); - } + inventoryItemCheck(Clothing, messages, id.toString(), true); } void CSMTools::ReferenceableCheckStage::containerCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Container >& records, std::vector< std::string >& messages) @@ -556,7 +461,7 @@ void CSMTools::ReferenceableCheckStage::doorCheck(int stage, const CSMWorld::Ref const ESM::Door& Door = (dynamic_cast&>(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Door, Door.mId); - //usual, name and model + //usual, name or model if (Door.mName.empty()) { messages.push_back(id.toString() + "|" + Door.mId + " has an empty name"); @@ -582,35 +487,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(int stage, const CSMWorl const ESM::Ingredient& Ingredient = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Ingredient, Ingredient.mId); - //Checking for name - if (Ingredient.mName.empty()) - { - messages.push_back(id.toString() + "|" + Ingredient.mId + " has an empty name"); - } - - //Checking for weight - if (Ingredient.mData.mWeight < 0) - { - messages.push_back(id.toString() + "|" + Ingredient.mId + " has negative weight"); - } - - //Checking for value - if (Ingredient.mData.mValue < 0) - { - messages.push_back(id.toString() + "|" + Ingredient.mId + " has negative value"); - } - -//checking for model - if (Ingredient.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Ingredient.mId + " has no model"); - } - - //checking for icon - if (Ingredient.mIcon.empty()) - { - messages.push_back(id.toString() + "|" + Ingredient.mId + " has no icon"); - } + inventoryItemCheck(Ingredient, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records, std::vector< std::string >& messages) @@ -625,18 +502,8 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const C const ESM::CreatureLevList& CreatureLevList = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, CreatureLevList.mId); //CreatureLevList but Type_CreatureLevelledList :/ - for (unsigned i = 0; i < CreatureLevList.mList.size(); ++i) - { - if (CreatureLevList.mList[i].mId.empty()) - { - messages.push_back(id.toString() + "|" + CreatureLevList.mId + " contains item with empty Id"); - } - if (CreatureLevList.mList[i].mLevel < 1) - { - messages.push_back(id.toString() + "|" + CreatureLevList.mId + " contains item with non-positive level"); - } - } + listCheck(CreatureLevList, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, std::vector< std::string >& messages) @@ -651,18 +518,7 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(int stage, const C const ESM::ItemLevList& ItemLevList = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, ItemLevList.mId); - for (unsigned i = 0; i < ItemLevList.mList.size(); ++i) - { - if (ItemLevList.mList[i].mId.empty()) - { - messages.push_back(id.toString() + "|" + ItemLevList.mId + " contains item with empty Id"); - } - - if (ItemLevList.mList[i].mLevel < 1) - { - messages.push_back(id.toString() + "|" + ItemLevList.mId + " contains item with non-positive level"); - } - } + listCheck(ItemLevList, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::lightCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records, std::vector< std::string >& messages) @@ -686,31 +542,15 @@ void CSMTools::ReferenceableCheckStage::lightCheck(int stage, const CSMWorld::Re { if (Light.mIcon.empty()) //Needs to be checked with carrable flag { - messages.push_back(id.toString() + "|" + Light.mId + " has no icon"); - } + inventoryItemCheck(Light, messages, id.toString()); - if (Light.mData.mWeight < 0) - { - messages.push_back(id.toString() + "|" + Light.mId + " has negative weight"); - } - - if (Light.mData.mValue < 0) - { - messages.push_back(id.toString() + "|" + Light.mId + " has negative value"); - } - - if (Light.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Light.mId + " has no model"); - } - - if (Light.mData.mTime == 0) - { - messages.push_back(id.toString() + "|" + Light.mId + " has zero duration"); + if (Light.mData.mTime == 0) + { + messages.push_back(id.toString() + "|" + Light.mId + " has zero duration"); + } } } } - void CSMTools::ReferenceableCheckStage::lockpickCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records, std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -723,45 +563,9 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(int stage, const CSMWorld: const ESM::Lockpick& Lockpick = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Lockpick, Lockpick.mId); - //Checking for name - if (Lockpick.mName.empty()) - { - messages.push_back(id.toString() + "|" + Lockpick.mId + " has an empty name"); - } + inventoryItemCheck(Lockpick, messages, id.toString()); - //Checking for weight - if (Lockpick.mData.mWeight < 0) - { - messages.push_back(id.toString() + "|" + Lockpick.mId + " has negative weight"); - } - - //Checking for value - if (Lockpick.mData.mValue < 0) - { - messages.push_back(id.toString() + "|" + Lockpick.mId + " has negative value"); - } - -//checking for model - if (Lockpick.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Lockpick.mId + " has no model"); - } - - //checking for icon - if (Lockpick.mIcon.empty()) - { - messages.push_back(id.toString() + "|" + Lockpick.mId + " has no icon"); - } - - if (Lockpick.mData.mQuality <= 0) - { - messages.push_back(id.toString() + "|" + Lockpick.mId + " has non-positive quality"); - } - - if (Lockpick.mData.mUses <= 0) - { - messages.push_back(id.toString() + "|" + Lockpick.mId + " has no uses left"); - } + toolCheck(Lockpick, messages, id.toString(), true); } void CSMTools::ReferenceableCheckStage::miscCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records, std::vector< std::string >& messages) @@ -776,35 +580,7 @@ void CSMTools::ReferenceableCheckStage::miscCheck(int stage, const CSMWorld::Ref const ESM::Miscellaneous& Miscellaneous = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, Miscellaneous.mId); - //Checking for name - if (Miscellaneous.mName.empty()) - { - messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has an empty name"); - } - - //Checking for weight - if (Miscellaneous.mData.mWeight < 0) - { - messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has negative weight"); - } - - //Checking for value - if (Miscellaneous.mData.mValue < 0) - { - messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has negative value"); - } - -//checking for model - if (Miscellaneous.mModel.empty()) - { - messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has no model"); - } - - //checking for icon - if (Miscellaneous.mIcon.empty()) - { - messages.push_back(id.toString() + "|" + Miscellaneous.mId + " has no icon"); - } + inventoryItemCheck(Miscellaneous, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records, std::vector< std::string >& messages) @@ -819,8 +595,6 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI const ESM::NPC& NPC = (dynamic_cast& >(baserecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc, NPC.mId); - - short level(NPC.mNpdt52.mLevel); char Disposition(NPC.mNpdt52.mDisposition); char Reputation(NPC.mNpdt52.mReputation); @@ -832,7 +606,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI { if ((NPC.mFlags & 0x0008) == 0) //0x0008 = autocalculated flag { - messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType and flags mismatch!"); //should not happend? + messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType or flags mismatch!"); //should not happend? return; } @@ -982,36 +756,233 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI //TODO: reputation, Disposition, rank, everything else } +void CSMTools::ReferenceableCheckStage::weaponCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Weapon >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Weapon& Weapon = (dynamic_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Weapon, Weapon.mId); + + //TODO, It seems that this stuff for spellcasting is obligatory and In fact We should check if records are present + if + ( + Weapon.mId.find("VFX_") == std::string::npos + and Weapon.mId != "magic_bolt" + and Weapon.mId != "shield_bolt" + and Weapon.mId != "shock_bolt" + ) + { + inventoryItemCheck(Weapon, messages, id.toString(), true); + + if (Weapon.mData.mType == ESM::Weapon::MarksmanBow or Weapon.mData.mType == ESM::Weapon::MarksmanCrossbow or Weapon.mData.mType == ESM::Weapon::MarksmanThrown or Weapon.mData.mType == ESM::Weapon::Arrow or Weapon.mData.mType == ESM::Weapon::Bolt) + { + if (Weapon.mData.mChop[0] > Weapon.mData.mChop[1]) + { + messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum chop damage higher than maximum"); + } + } + else + { + if (Weapon.mData.mSlash[0] > Weapon.mData.mSlash[1]) + { + messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum slash damage higher than maximum"); + } + + if (Weapon.mData.mChop[0] > Weapon.mData.mChop[1]) + { + messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum chop damage higher than maximum"); + } + + if (Weapon.mData.mThrust[0] > Weapon.mData.mThrust[1]) + { + messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum thrust damage higher than maximum"); + } + } + + if (!(Weapon.mData.mType == ESM::Weapon::Arrow or Weapon.mData.mType == ESM::Weapon::Bolt or Weapon.mData.mType == ESM::Weapon::MarksmanThrown)) + { + //checking of health + if (Weapon.mData.mHealth <= 0) + { + messages.push_back(id.toString() + "|" + Weapon.mId + " has non-positivie health"); + } + + if (Weapon.mData.mReach < 0) + { + messages.push_back(id.toString() + "|" + Weapon.mId + " has negative reach"); + } + } + } +} + +void CSMTools::ReferenceableCheckStage::probeCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Probe >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Probe& Probe = (dynamic_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Probe, Probe.mId); + + inventoryItemCheck(Probe, messages, id.toString()); + toolCheck(Probe, messages, id.toString(), true); +} + +void CSMTools::ReferenceableCheckStage::repairCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Repair >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Repair& Repair = (dynamic_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Repair, Repair.mId); + + inventoryItemCheck(Repair, messages, id.toString()); + toolCheck(Repair, messages, id.toString(), true); +} + +void CSMTools::ReferenceableCheckStage::staticCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Static >& records, std::vector< std::string >& messages) +{ + const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + + if (baserecord.isDeleted()) + { + return; + } + + const ESM::Static& Static = (dynamic_cast& >(baserecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Static, Static.mId); + + if (Static.mModel.empty()) + { + messages.push_back(id.toString() + "|" + Static.mId + " has no model"); + } +} + + //Templates begins here -void CSMTools::ReferenceableCheckStage::inventoryItemCheck(const item& item, std::vector< std::string >& messages) +template void CSMTools::ReferenceableCheckStage::inventoryItemCheck(const ITEM& someitem, std::vector< std::string >& messages, const std::string& someid, bool enchantable) { - if (item.mName.empty()) + if (someitem.mName.empty()) { - messages.push_back(id.toString() + "|" + item.mId + " has an empty name"); + messages.push_back(someid + "|" + someitem.mId + " has an empty name"); } //Checking for weight - if (item.mData.mWeight < 0) + if (someitem.mData.mWeight < 0) { - messages.push_back(id.toString() + "|" + item.mId + " has negative weight"); + messages.push_back(someid + "|" + someitem.mId + " has negative weight"); } //Checking for value - if (item.mData.mValue < 0) + if (someitem.mData.mValue < 0) { - messages.push_back(id.toString() + "|" + item.mId + " has negative value"); + messages.push_back(someid + "|" + someitem.mId + " has negative value"); } //checking for model - if (item.mModel.empty()) + if (someitem.mModel.empty()) { - messages.push_back(id.toString() + "|" + item.mId + " has no model"); + messages.push_back(someid + "|" + someitem.mId + " has no model"); } //checking for icon - if (item.mIcon.empty()) + if (someitem.mIcon.empty()) { - messages.push_back(id.toString() + "|" + item.mId + " has no icon"); + messages.push_back(someid + "|" + someitem.mId + " has no icon"); + } + + if (enchantable) + { + if (someitem.mData.mEnchant < 0) + { + messages.push_back(someid + "|" + someitem.mId + " has negative enchantment"); + } } } + +template void CSMTools::ReferenceableCheckStage::inventoryItemCheck(const ITEM& someitem, std::vector< std::string >& messages, const std::string& someid) +{ + if (someitem.mName.empty()) + { + messages.push_back(someid + "|" + someitem.mId + " has an empty name"); + } + + //Checking for weight + if (someitem.mData.mWeight < 0) + { + messages.push_back(someid + "|" + someitem.mId + " has negative weight"); + } + + //Checking for value + if (someitem.mData.mValue < 0) + { + messages.push_back(someid + "|" + someitem.mId + " has negative value"); + } + +//checking for model + if (someitem.mModel.empty()) + { + messages.push_back(someid + "|" + someitem.mId + " has no model"); + } + + //checking for icon + if (someitem.mIcon.empty()) + { + messages.push_back(someid + "|" + someitem.mId + " has no icon"); + } +} + +template void CSMTools::ReferenceableCheckStage::toolCheck(const TOOL& sometool, std::vector< std::string >& messages, const std::string& someid, bool canbebroken) +{ + if (sometool.mData.mQuality <= 0) + { + messages.push_back(someid + "|" + sometool.mId + " has non-positive quality"); + } + + if (canbebroken) + { + if (sometool.mData.mUses <= 0) + { + messages.push_back(someid + "|" + sometool.mId + " has non-positive uses count"); + } + } +} + +template void CSMTools::ReferenceableCheckStage::toolCheck(const TOOL& sometool, std::vector< std::string >& messages, const std::string& someid) +{ + if (sometool.mData.mQuality <= 0) + { + messages.push_back(someid + "|" + sometool.mId + " has non-positive quality"); + } + +} + +template void CSMTools::ReferenceableCheckStage::listCheck(const LIST& somelist, std::vector< std::string >& messages, const std::string& someid) +{ + for (unsigned i = 0; i < somelist.mList.size(); ++i) + { + if (somelist.mList[i].mId.empty()) + { + messages.push_back(someid + "|" + somelist.mId + " contains item with empty Id"); + } + + if (somelist.mList[i].mLevel < 1) + { + messages.push_back(someid + "|" + somelist.mId + " contains item with non-positive level"); + } + } +} + diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 43bb54fa79..feeb32e6ad 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -33,9 +33,17 @@ namespace CSMTools void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void miscCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void weaponCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void probeCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void repairCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); + void staticCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); //TEMPLATE CHECKS - template void inventoryItemCheck(const item& item, std::vector& messages); //for all inventory items. + template void inventoryItemCheck(const ITEM& someitem, std::vector& messages, const std::string& someid, bool enchantable); //for all enchantable items. + template void inventoryItemCheck(const ITEM& someitem, std::vector& messages, const std::string& someid); //for non-enchantable items. + template void toolCheck(const TOOL& sometool, std::vector& messages, const std::string& someid, bool canbebroken); //for tools with uses. + template void toolCheck(const TOOL& sometool, std::vector& messages, const std::string& someid); //for tools without uses. + template void listCheck(const LIST& some, std::vector< std::string >& messages, const std::string& someid); const CSMWorld::RefIdData& mReferencables; const CSMWorld::IdCollection& mRaces; diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 5af215989d..65990c1d45 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -311,3 +311,23 @@ const CSMWorld::RefIdDataContainer< ESM::NPC >& CSMWorld::RefIdData::getNPCs() c { return mNpcs; } + +const CSMWorld::RefIdDataContainer< ESM::Weapon >& CSMWorld::RefIdData::getWeapons() const +{ + return mWeapons; +} + +const CSMWorld::RefIdDataContainer< ESM::Probe >& CSMWorld::RefIdData::getProbes() const +{ + return mProbes; +} + +const CSMWorld::RefIdDataContainer< ESM::Repair >& CSMWorld::RefIdData::getRepairs() const +{ + return mRepairs; +} + +const CSMWorld::RefIdDataContainer< ESM::Static >& CSMWorld::RefIdData::getStatics() const +{ + return mStatics; +} \ No newline at end of file diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 51f5484996..f82d151b47 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -237,6 +237,10 @@ namespace CSMWorld const RefIdDataContainer& getLocpicks() const; const RefIdDataContainer& getMiscellaneous() const; const RefIdDataContainer& getNPCs() const; + const RefIdDataContainer< ESM::Weapon >& getWeapons() const; + const RefIdDataContainer< ESM::Probe >& getProbes() const; + const RefIdDataContainer< ESM::Repair>& getRepairs() const; + const RefIdDataContainer< ESM::Static>& getStatics() const; }; } From 7b63e1942c3cae9e4bcf6b5b0a522d49a9728ee7 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 3 Jan 2014 11:42:49 +0100 Subject: [PATCH 044/168] style corrections --- .../opencs/model/tools/referenceablecheck.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 65bee314c6..3f4d80db88 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -779,31 +779,24 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(int stage, const CSMWorld::R { inventoryItemCheck(Weapon, messages, id.toString(), true); - if (Weapon.mData.mType == ESM::Weapon::MarksmanBow or Weapon.mData.mType == ESM::Weapon::MarksmanCrossbow or Weapon.mData.mType == ESM::Weapon::MarksmanThrown or Weapon.mData.mType == ESM::Weapon::Arrow or Weapon.mData.mType == ESM::Weapon::Bolt) - { - if (Weapon.mData.mChop[0] > Weapon.mData.mChop[1]) - { - messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum chop damage higher than maximum"); - } - } - else + if (!(Weapon.mData.mType == ESM::Weapon::MarksmanBow or Weapon.mData.mType == ESM::Weapon::MarksmanCrossbow or Weapon.mData.mType == ESM::Weapon::MarksmanThrown or Weapon.mData.mType == ESM::Weapon::Arrow or Weapon.mData.mType == ESM::Weapon::Bolt)) { if (Weapon.mData.mSlash[0] > Weapon.mData.mSlash[1]) { messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum slash damage higher than maximum"); } - if (Weapon.mData.mChop[0] > Weapon.mData.mChop[1]) - { - messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum chop damage higher than maximum"); - } - if (Weapon.mData.mThrust[0] > Weapon.mData.mThrust[1]) { messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum thrust damage higher than maximum"); } } + if (Weapon.mData.mChop[0] > Weapon.mData.mChop[1]) + { + messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum chop damage higher than maximum"); + } + if (!(Weapon.mData.mType == ESM::Weapon::Arrow or Weapon.mData.mType == ESM::Weapon::Bolt or Weapon.mData.mType == ESM::Weapon::MarksmanThrown)) { //checking of health From 1c3296fb64e4dd792681a9d8756be9451930f079 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 3 Jan 2014 18:23:11 +0100 Subject: [PATCH 045/168] Some changes in weapons check. --- apps/opencs/model/tools/referenceablecheck.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 3f4d80db88..73f3166778 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -8,6 +8,7 @@ #include "../world/record.hpp" #include "../world/universalid.hpp" +#include CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes, const CSMWorld::IdCollection& faction) : mReferencables(referenceable), @@ -551,6 +552,7 @@ void CSMTools::ReferenceableCheckStage::lightCheck(int stage, const CSMWorld::Re } } } + void CSMTools::ReferenceableCheckStage::lockpickCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records, std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -667,7 +669,6 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI { messages.push_back(id.toString() + "|" + NPC.mId + " willpower has zero value"); } - } if (level < 1) @@ -771,10 +772,13 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(int stage, const CSMWorld::R //TODO, It seems that this stuff for spellcasting is obligatory and In fact We should check if records are present if ( - Weapon.mId.find("VFX_") == std::string::npos - and Weapon.mId != "magic_bolt" - and Weapon.mId != "shield_bolt" - and Weapon.mId != "shock_bolt" + //THOSE ARE HARDCODED! + Weapon.mId != "VFX_Hands" + and Weapon.mId != "VFX_Absorb" + and Weapon.mId != "VFX_Reflect" + and Weapon.mId != "VFX_DefaultBolt" + //THIS ONE IS NOT, but it thas to be ignored as well + //TODO I don't know how to get full list of effects :/ ) { inventoryItemCheck(Weapon, messages, id.toString(), true); @@ -977,5 +981,4 @@ template void CSMTools::ReferenceableCheckStage::listCheck(const messages.push_back(someid + "|" + somelist.mId + " contains item with non-positive level"); } } -} - +} \ No newline at end of file From aa05ffcf60831c2bd020502b8433820d75e982e4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 4 Jan 2014 13:05:19 +0100 Subject: [PATCH 046/168] Splited some long argument lists to the multiple lines. --- .../opencs/model/tools/referenceablecheck.cpp | 136 +++++++++++++----- apps/opencs/model/world/refiddata.hpp | 8 +- 2 files changed, 108 insertions(+), 36 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 73f3166778..4b610d5d25 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -10,7 +10,11 @@ #include "../world/universalid.hpp" #include -CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes, const CSMWorld::IdCollection& faction) : +CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( + const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, + const CSMWorld::IdCollection& classes, + const CSMWorld::IdCollection& faction) + : mReferencables(referenceable), mClasses(classes), mRaces(races), @@ -215,7 +219,10 @@ int CSMTools::ReferenceableCheckStage::setup() return mReferencables.getSize(); } -void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::bookCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Book >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -230,7 +237,10 @@ void CSMTools::ReferenceableCheckStage::bookCheck(int stage, const CSMWorld::Ref inventoryItemCheck(Book, messages, id.toString(), true); } -void CSMTools::ReferenceableCheckStage::activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::activatorCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Activator >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -249,7 +259,10 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(int stage, const CSMWorld } } -void CSMTools::ReferenceableCheckStage::potionCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Potion >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::potionCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Potion >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -266,7 +279,10 @@ void CSMTools::ReferenceableCheckStage::potionCheck(int stage, const CSMWorld::R } -void CSMTools::ReferenceableCheckStage::apparatusCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::apparatusCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -284,7 +300,10 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(int stage, const CSMWorld toolCheck(Apparatus, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::armorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Armor >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::armorCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Armor >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -311,7 +330,10 @@ void CSMTools::ReferenceableCheckStage::armorCheck(int stage, const CSMWorld::Re } } -void CSMTools::ReferenceableCheckStage::clothingCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Clothing >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::clothingCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Clothing >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -325,7 +347,10 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(int stage, const CSMWorld: inventoryItemCheck(Clothing, messages, id.toString(), true); } -void CSMTools::ReferenceableCheckStage::containerCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Container >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::containerCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Container >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -356,7 +381,10 @@ void CSMTools::ReferenceableCheckStage::containerCheck(int stage, const CSMWorld } } -void CSMTools::ReferenceableCheckStage::creatureCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Creature >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::creatureCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Creature >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -450,7 +478,10 @@ void CSMTools::ReferenceableCheckStage::creatureCheck(int stage, const CSMWorld: } } -void CSMTools::ReferenceableCheckStage::doorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Door >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::doorCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Door >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -476,7 +507,10 @@ void CSMTools::ReferenceableCheckStage::doorCheck(int stage, const CSMWorld::Ref //TODO, check what static unsigned int sRecordId; is for } -void CSMTools::ReferenceableCheckStage::ingredientCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::ingredientCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -491,7 +525,10 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(int stage, const CSMWorl inventoryItemCheck(Ingredient, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -507,7 +544,10 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(int stage, const C listCheck(CreatureLevList, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::itemLevelledListCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -522,7 +562,10 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(int stage, const C listCheck(ItemLevList, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::lightCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::lightCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Light >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -553,7 +596,10 @@ void CSMTools::ReferenceableCheckStage::lightCheck(int stage, const CSMWorld::Re } } -void CSMTools::ReferenceableCheckStage::lockpickCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::lockpickCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -570,7 +616,10 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(int stage, const CSMWorld: toolCheck(Lockpick, messages, id.toString(), true); } -void CSMTools::ReferenceableCheckStage::miscCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::miscCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -585,7 +634,10 @@ void CSMTools::ReferenceableCheckStage::miscCheck(int stage, const CSMWorld::Ref inventoryItemCheck(Miscellaneous, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::npcCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::NPC >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -757,7 +809,10 @@ void CSMTools::ReferenceableCheckStage::npcCheck(int stage, const CSMWorld::RefI //TODO: reputation, Disposition, rank, everything else } -void CSMTools::ReferenceableCheckStage::weaponCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Weapon >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::weaponCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Weapon >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -772,13 +827,12 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(int stage, const CSMWorld::R //TODO, It seems that this stuff for spellcasting is obligatory and In fact We should check if records are present if ( - //THOSE ARE HARDCODED! + //THOSE ARE HARDCODED! Weapon.mId != "VFX_Hands" - and Weapon.mId != "VFX_Absorb" - and Weapon.mId != "VFX_Reflect" - and Weapon.mId != "VFX_DefaultBolt" - //THIS ONE IS NOT, but it thas to be ignored as well - //TODO I don't know how to get full list of effects :/ + && Weapon.mId != "VFX_Absorb" + && Weapon.mId != "VFX_Reflect" + && Weapon.mId != "VFX_DefaultBolt" + //TODO I don't know how to get full list of effects :/ ) { inventoryItemCheck(Weapon, messages, id.toString(), true); @@ -817,7 +871,10 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(int stage, const CSMWorld::R } } -void CSMTools::ReferenceableCheckStage::probeCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Probe >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::probeCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Probe >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -870,7 +927,10 @@ void CSMTools::ReferenceableCheckStage::staticCheck(int stage, const CSMWorld::R //Templates begins here -template void CSMTools::ReferenceableCheckStage::inventoryItemCheck(const ITEM& someitem, std::vector< std::string >& messages, const std::string& someid, bool enchantable) +template void CSMTools::ReferenceableCheckStage::inventoryItemCheck( + const ITEM& someitem, + std::vector< std::string >& messages, + const std::string& someid, bool enchantable) { if (someitem.mName.empty()) { @@ -910,7 +970,10 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe } } -template void CSMTools::ReferenceableCheckStage::inventoryItemCheck(const ITEM& someitem, std::vector< std::string >& messages, const std::string& someid) +template void CSMTools::ReferenceableCheckStage::inventoryItemCheck( + const ITEM& someitem, + std::vector< std::string >& messages, + const std::string& someid) { if (someitem.mName.empty()) { @@ -942,7 +1005,10 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe } } -template void CSMTools::ReferenceableCheckStage::toolCheck(const TOOL& sometool, std::vector< std::string >& messages, const std::string& someid, bool canbebroken) +template void CSMTools::ReferenceableCheckStage::toolCheck( + const TOOL& sometool, + std::vector< std::string >& messages, + const std::string& someid, bool canbebroken) { if (sometool.mData.mQuality <= 0) { @@ -958,16 +1024,21 @@ template void CSMTools::ReferenceableCheckStage::toolCheck(const } } -template void CSMTools::ReferenceableCheckStage::toolCheck(const TOOL& sometool, std::vector< std::string >& messages, const std::string& someid) +template void CSMTools::ReferenceableCheckStage::toolCheck( + const TOOL& sometool, + std::vector< std::string >& messages, + const std::string& someid) { if (sometool.mData.mQuality <= 0) { messages.push_back(someid + "|" + sometool.mId + " has non-positive quality"); } - } -template void CSMTools::ReferenceableCheckStage::listCheck(const LIST& somelist, std::vector< std::string >& messages, const std::string& someid) +template void CSMTools::ReferenceableCheckStage::listCheck( + const LIST& somelist, + std::vector< std::string >& messages, + const std::string& someid) { for (unsigned i = 0; i < somelist.mList.size(); ++i) { @@ -981,4 +1052,5 @@ template void CSMTools::ReferenceableCheckStage::listCheck(const messages.push_back(someid + "|" + somelist.mId + " contains item with non-positive level"); } } -} \ No newline at end of file +} +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index f82d151b47..a204334b37 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -237,10 +237,10 @@ namespace CSMWorld const RefIdDataContainer& getLocpicks() const; const RefIdDataContainer& getMiscellaneous() const; const RefIdDataContainer& getNPCs() const; - const RefIdDataContainer< ESM::Weapon >& getWeapons() const; - const RefIdDataContainer< ESM::Probe >& getProbes() const; - const RefIdDataContainer< ESM::Repair>& getRepairs() const; - const RefIdDataContainer< ESM::Static>& getStatics() const; + const RefIdDataContainer& getWeapons() const; + const RefIdDataContainer& getProbes() const; + const RefIdDataContainer& getRepairs() const; + const RefIdDataContainer& getStatics() const; }; } From dfd1058551ecfdaf34bf621670904f1029ad55e1 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 4 Jan 2014 13:09:53 +0100 Subject: [PATCH 047/168] Various style corrections. --- apps/opencs/model/tools/referenceablecheck.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 4b610d5d25..6c90af694d 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -837,7 +837,11 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( { inventoryItemCheck(Weapon, messages, id.toString(), true); - if (!(Weapon.mData.mType == ESM::Weapon::MarksmanBow or Weapon.mData.mType == ESM::Weapon::MarksmanCrossbow or Weapon.mData.mType == ESM::Weapon::MarksmanThrown or Weapon.mData.mType == ESM::Weapon::Arrow or Weapon.mData.mType == ESM::Weapon::Bolt)) + if ( !(Weapon.mData.mType == ESM::Weapon::MarksmanBow || + Weapon.mData.mType == ESM::Weapon::MarksmanCrossbow || + Weapon.mData.mType == ESM::Weapon::MarksmanThrown || + Weapon.mData.mType == ESM::Weapon::Arrow || + Weapon.mData.mType == ESM::Weapon::Bolt) ) { if (Weapon.mData.mSlash[0] > Weapon.mData.mSlash[1]) { From 558690b571f22b02df849046cb5401d5b2f009c2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 4 Jan 2014 15:19:17 +0100 Subject: [PATCH 048/168] implemented list of magical bolts for skipping. --- .../opencs/model/tools/referenceablecheck.cpp | 58 ++++++++++++++----- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 6c90af694d..b9adf81ea0 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -826,22 +826,40 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( //TODO, It seems that this stuff for spellcasting is obligatory and In fact We should check if records are present if - ( - //THOSE ARE HARDCODED! - Weapon.mId != "VFX_Hands" - && Weapon.mId != "VFX_Absorb" - && Weapon.mId != "VFX_Reflect" - && Weapon.mId != "VFX_DefaultBolt" - //TODO I don't know how to get full list of effects :/ - ) + ( //THOSE ARE HARDCODED! + !(Weapon.mId == "VFX_Hands" || + Weapon.mId == "VFX_Absorb" || + Weapon.mId == "VFX_Reflect" || + Weapon.mId == "VFX_DefaultBolt" || + //TODO I don't know how to get full list of effects :/ + //DANGER!, ACHTUNG! FIXME! The following is the list of the magical bolts, valid for Morrowind.esm. However those are not hardcoded. + Weapon.mId == "magic_bolt" || + Weapon.mId == "shock_bolt" || + Weapon.mId == "shield_bolt" || + Weapon.mId == "VFX_DestructBolt" || + Weapon.mId == "VFX_PoisonBolt" || + Weapon.mId == "VFX_RestoreBolt" || + Weapon.mId == "VFX_AlterationBolt" || + Weapon.mId == "VFX_ConjureBolt" || + Weapon.mId == "VFX_FrostBolt" || + Weapon.mId == "VFX_MysticismBolt" || + Weapon.mId == "VFX_IllusionBolt" || + Weapon.mId == "VFX_Multiple2" || + Weapon.mId == "VFX_Multiple3" || + Weapon.mId == "VFX_Multiple4" || + Weapon.mId == "VFX_Multiple5" || + Weapon.mId == "VFX_Multiple6" || + Weapon.mId == "VFX_Multiple7" || + Weapon.mId == "VFX_Multiple8" || + Weapon.mId == "VFX_Multiple9")) { inventoryItemCheck(Weapon, messages, id.toString(), true); - if ( !(Weapon.mData.mType == ESM::Weapon::MarksmanBow || - Weapon.mData.mType == ESM::Weapon::MarksmanCrossbow || - Weapon.mData.mType == ESM::Weapon::MarksmanThrown || - Weapon.mData.mType == ESM::Weapon::Arrow || - Weapon.mData.mType == ESM::Weapon::Bolt) ) + if (!(Weapon.mData.mType == ESM::Weapon::MarksmanBow || + Weapon.mData.mType == ESM::Weapon::MarksmanCrossbow || + Weapon.mData.mType == ESM::Weapon::MarksmanThrown || + Weapon.mData.mType == ESM::Weapon::Arrow || + Weapon.mData.mType == ESM::Weapon::Bolt)) { if (Weapon.mData.mSlash[0] > Weapon.mData.mSlash[1]) { @@ -859,7 +877,9 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum chop damage higher than maximum"); } - if (!(Weapon.mData.mType == ESM::Weapon::Arrow or Weapon.mData.mType == ESM::Weapon::Bolt or Weapon.mData.mType == ESM::Weapon::MarksmanThrown)) + if (!(Weapon.mData.mType == ESM::Weapon::Arrow || + Weapon.mData.mType == ESM::Weapon::Bolt || + Weapon.mData.mType == ESM::Weapon::MarksmanThrown)) { //checking of health if (Weapon.mData.mHealth <= 0) @@ -894,7 +914,10 @@ void CSMTools::ReferenceableCheckStage::probeCheck( toolCheck(Probe, messages, id.toString(), true); } -void CSMTools::ReferenceableCheckStage::repairCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Repair >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::repairCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Repair >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); @@ -910,7 +933,10 @@ void CSMTools::ReferenceableCheckStage::repairCheck(int stage, const CSMWorld::R toolCheck(Repair, messages, id.toString(), true); } -void CSMTools::ReferenceableCheckStage::staticCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Static >& records, std::vector< std::string >& messages) +void CSMTools::ReferenceableCheckStage::staticCheck( + int stage, + const CSMWorld::RefIdDataContainer< ESM::Static >& records, + std::vector< std::string >& messages) { const CSMWorld::RecordBase& baserecord = records.getRecord(stage); From e8607171058e3f026b6b89fe0b30164bc58b7451 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 4 Jan 2014 15:28:08 +0100 Subject: [PATCH 049/168] replaced raw values with enums. --- apps/opencs/model/tools/referenceablecheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index b9adf81ea0..e94f0a401b 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -656,9 +656,9 @@ void CSMTools::ReferenceableCheckStage::npcCheck( //Don't know what unknown is for int Gold(NPC.mNpdt52.mGold); - if (NPC.mNpdtType == 12) //12 = autocalculated + if (NPC.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated { - if ((NPC.mFlags & 0x0008) == 0) //0x0008 = autocalculated flag + if ((NPC.mFlags & ESM::NPC::Autocalc) == 0) //0x0008 = autocalculated flag { messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType or flags mismatch!"); //should not happend? return; From 220d92f865fdf094616d60e3edeb1aa993132e88 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 5 Jan 2014 11:30:03 +0100 Subject: [PATCH 050/168] changed ID check in leveled list to name. --- apps/opencs/model/tools/referenceablecheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index e94f0a401b..0460444c59 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1072,9 +1072,9 @@ template void CSMTools::ReferenceableCheckStage::listCheck( { for (unsigned i = 0; i < somelist.mList.size(); ++i) { - if (somelist.mList[i].mId.empty()) + if (somelist.mList[i].mName.empty()) { - messages.push_back(someid + "|" + somelist.mId + " contains item with empty Id"); + messages.push_back(someid + "|" + somelist.mId + " contains item with empty name"); } if (somelist.mList[i].mLevel < 1) From 89d8ee62fac1eb01ceb3a4401eb06826b7dfda8a Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 5 Jan 2014 12:12:36 +0100 Subject: [PATCH 051/168] Removing name check from listCheck. Id can't be empty to be sure. --- apps/opencs/model/tools/referenceablecheck.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 0460444c59..187a746279 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1072,11 +1072,6 @@ template void CSMTools::ReferenceableCheckStage::listCheck( { for (unsigned i = 0; i < somelist.mList.size(); ++i) { - if (somelist.mList[i].mName.empty()) - { - messages.push_back(someid + "|" + somelist.mId + " contains item with empty name"); - } - if (somelist.mList[i].mLevel < 1) { messages.push_back(someid + "|" + somelist.mId + " contains item with non-positive level"); From c1f4a9cb0e45ce8fb6adf55ad43a9c947884d119 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 5 Jan 2014 12:16:25 +0100 Subject: [PATCH 052/168] Added proper id check. --- apps/opencs/model/tools/referenceablecheck.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 187a746279..424f298206 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1072,6 +1072,11 @@ template void CSMTools::ReferenceableCheckStage::listCheck( { for (unsigned i = 0; i < somelist.mList.size(); ++i) { + if (mReferencables.searchId(somelist.mList[i].mId).first == -1) + { + messages.push_back(someid + "|" + somelist.mId + " contains item without referencable"); + } + if (somelist.mList[i].mLevel < 1) { messages.push_back(someid + "|" + somelist.mId + " contains item with non-positive level"); From 873870c7cefee09a36693a0e2f8c18d78eda1084 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 5 Jan 2014 16:52:11 +0100 Subject: [PATCH 053/168] Chainging names to comply our policy. --- .../opencs/model/tools/referenceablecheck.cpp | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 424f298206..74a7dbb7f7 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -25,145 +25,145 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. - const int BookSize(mReferencables.getBooks().getSize()); + const int bookSize(mReferencables.getBooks().getSize()); - if (stage < BookSize) + if (stage < bookSize) { bookCheck(stage, mReferencables.getBooks(), messages); return; } - stage -= BookSize; + stage -= bookSize; - const int ActivatorSize(mReferencables.getActivators().getSize()); + const int activatorSize(mReferencables.getActivators().getSize()); - if (stage < ActivatorSize) + if (stage < activatorSize) { activatorCheck(stage, mReferencables.getActivators(), messages); return; } - stage -= ActivatorSize; + stage -= activatorSize; - const int PotionSize(mReferencables.getActivators().getSize()); + const int potionSize(mReferencables.getActivators().getSize()); - if (stage < PotionSize) + if (stage < potionSize) { potionCheck(stage, mReferencables.getPotions(), messages); return; } - stage -= PotionSize; + stage -= potionSize; - const int ApparatusSize(mReferencables.getApparati().getSize()); + const int apparatusSize(mReferencables.getApparati().getSize()); - if (stage < ApparatusSize) + if (stage < apparatusSize) { apparatusCheck(stage, mReferencables.getApparati(), messages); return; } - stage -= ApparatusSize; + stage -= apparatusSize; - const int ArmorSize(mReferencables.getArmors().getSize()); + const int armorSize(mReferencables.getArmors().getSize()); - if (stage < ArmorSize) + if (stage < armorSize) { armorCheck(stage, mReferencables.getArmors(), messages); return; } - stage -= ArmorSize; + stage -= armorSize; - const int ClothingSize(mReferencables.getClothing().getSize()); + const int clothingSize(mReferencables.getClothing().getSize()); - if (stage < ClothingSize) + if (stage < clothingSize) { clothingCheck(stage, mReferencables.getClothing(), messages); return; } - stage -= ClothingSize; + stage -= clothingSize; - const int ContainerSize(mReferencables.getContainers().getSize()); + const int containerSize(mReferencables.getContainers().getSize()); - if (stage < ContainerSize) + if (stage < containerSize) { containerCheck(stage, mReferencables.getContainers(), messages); return; } - stage -= ContainerSize; + stage -= containerSize; - const int DoorSize(mReferencables.getDoors().getSize()); + const int doorSize(mReferencables.getDoors().getSize()); - if (stage < DoorSize) + if (stage < doorSize) { doorCheck(stage, mReferencables.getDoors(), messages); return; } - stage -= DoorSize; + stage -= doorSize; - const int IngredientSize(mReferencables.getIngredients().getSize()); + const int ingredientSize(mReferencables.getIngredients().getSize()); - if (stage < IngredientSize) + if (stage < ingredientSize) { ingredientCheck(stage, mReferencables.getIngredients(), messages); return; } - stage -= IngredientSize; + stage -= ingredientSize; - const int CreatureLevListSize(mReferencables.getCreatureLevelledLists().getSize()); + const int creatureLevListSize(mReferencables.getCreatureLevelledLists().getSize()); - if (stage < CreatureLevListSize) + if (stage < creatureLevListSize) { creaturesLevListCheck(stage, mReferencables.getCreatureLevelledLists(), messages); return; } - stage -= CreatureLevListSize; + stage -= creatureLevListSize; - const int ItemLevelledListSize(mReferencables.getItemLevelledList().getSize()); + const int itemLevelledListSize(mReferencables.getItemLevelledList().getSize()); - if (stage < ItemLevelledListSize) + if (stage < itemLevelledListSize) { itemLevelledListCheck(stage, mReferencables.getItemLevelledList(), messages); return; } - stage -= ItemLevelledListSize; + stage -= itemLevelledListSize; - const int LightSize(mReferencables.getLights().getSize()); + const int lightSize(mReferencables.getLights().getSize()); - if (stage < LightSize) + if (stage < lightSize) { lightCheck(stage, mReferencables.getLights(), messages); return; } - stage -= LightSize; + stage -= lightSize; - const int LockpickSize(mReferencables.getLocpicks().getSize()); + const int lockpickSize(mReferencables.getLocpicks().getSize()); - if (stage < LockpickSize) + if (stage < lockpickSize) { lockpickCheck(stage, mReferencables.getLocpicks(), messages); return; } - stage -= LockpickSize; + stage -= lockpickSize; - const int MiscSize(mReferencables.getMiscellaneous().getSize()); + const int miscSize(mReferencables.getMiscellaneous().getSize()); - if (stage < MiscSize) + if (stage < miscSize) { miscCheck(stage, mReferencables.getMiscellaneous(), messages); return; } - stage -= MiscSize; + stage -= miscSize; const int NPCSize(mReferencables.getNPCs().getSize()); @@ -175,39 +175,39 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str stage -= NPCSize; - const int WeaponSize(mReferencables.getWeapons().getSize()); + const int weaponSize(mReferencables.getWeapons().getSize()); - if (stage < WeaponSize) + if (stage < weaponSize) { weaponCheck(stage, mReferencables.getWeapons(), messages); return; } - stage -= WeaponSize; + stage -= weaponSize; - const int ProbeSize(mReferencables.getProbes().getSize()); + const int probeSize(mReferencables.getProbes().getSize()); - if (stage < ProbeSize) + if (stage < probeSize) { probeCheck(stage, mReferencables.getProbes(), messages); return; } - stage -= ProbeSize; + stage -= probeSize; - const int RepairSize(mReferencables.getRepairs().getSize()); + const int repairSize(mReferencables.getRepairs().getSize()); - if (stage < RepairSize) + if (stage < repairSize) { repairCheck(stage, mReferencables.getRepairs(), messages); return; } - stage -= RepairSize; + stage -= repairSize; - const int StaticSize(mReferencables.getStatics().getSize()); + const int staticSize(mReferencables.getStatics().getSize()); - if (stage < StaticSize) + if (stage < staticSize) { staticCheck(stage, mReferencables.getStatics(), messages); return; From 693c39820472ce5b9320f82f645bb2e632a2034d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 5 Jan 2014 17:05:57 +0100 Subject: [PATCH 054/168] forgot to save the file before comit -_-' --- .../opencs/model/tools/referenceablecheck.cpp | 474 +++++++++--------- 1 file changed, 237 insertions(+), 237 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 74a7dbb7f7..7d9210593b 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -224,17 +224,17 @@ void CSMTools::ReferenceableCheckStage::bookCheck( const CSMWorld::RefIdDataContainer< ESM::Book >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Book& Book = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, Book.mId); + const ESM::Book& book = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, book.mId); - inventoryItemCheck(Book, messages, id.toString(), true); + inventoryItemCheck(book, messages, id.toString(), true); } void CSMTools::ReferenceableCheckStage::activatorCheck( @@ -242,20 +242,20 @@ void CSMTools::ReferenceableCheckStage::activatorCheck( const CSMWorld::RefIdDataContainer< ESM::Activator >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Activator& Activator = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Activator, Activator.mId); + const ESM::Activator& activator = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Activator, activator.mId); //Checking for model, IIRC all activators should have a model - if (Activator.mModel.empty()) + if (activator.mModel.empty()) { - messages.push_back(id.toString() + "|" + Activator.mId + " has no model"); + messages.push_back(id.toString() + "|" + activator.mId + " has no model"); } } @@ -264,17 +264,17 @@ void CSMTools::ReferenceableCheckStage::potionCheck( const CSMWorld::RefIdDataContainer< ESM::Potion >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Potion& Potion = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, Potion.mId); + const ESM::Potion& potion = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId); - inventoryItemCheck(Potion, messages, id.toString()); + inventoryItemCheck(potion, messages, id.toString()); //IIRC potion can have empty effects list just fine. } @@ -284,20 +284,20 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck( const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Apparatus& Apparatus = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Apparatus, Apparatus.mId); + const ESM::Apparatus& apparatus = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Apparatus, apparatus.mId); - inventoryItemCheck(Apparatus, messages, id.toString()); + inventoryItemCheck(apparatus, messages, id.toString()); //checking for quality, 0 → apparatus is basicly useless, any negative → apparatus is harmfull instead of helpfull - toolCheck(Apparatus, messages, id.toString()); + toolCheck(apparatus, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::armorCheck( @@ -305,28 +305,28 @@ void CSMTools::ReferenceableCheckStage::armorCheck( const CSMWorld::RefIdDataContainer< ESM::Armor >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Armor& Armor = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Armor, Armor.mId); + const ESM::Armor& armor = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Armor, armor.mId); - inventoryItemCheck(Armor, messages, id.toString(), true); + inventoryItemCheck(armor, messages, id.toString(), true); //checking for armor class, armor should have poistive armor class, but 0 is considered legal - if (Armor.mData.mArmor < 0) + if (armor.mData.mArmor < 0) { - messages.push_back(id.toString() + "|" + Armor.mId + " has negative armor class"); + messages.push_back(id.toString() + "|" + armor.mId + " has negative armor class"); } //checking for health. Only positive numbers are allowed, or 0 is illegal - if (Armor.mData.mHealth <= 0) + if (armor.mData.mHealth <= 0) { - messages.push_back(id.toString() + "|" + Armor.mId + " has non positive health"); + messages.push_back(id.toString() + "|" + armor.mId + " has non positive health"); } } @@ -335,16 +335,16 @@ void CSMTools::ReferenceableCheckStage::clothingCheck( const CSMWorld::RefIdDataContainer< ESM::Clothing >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Clothing& Clothing = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, Clothing.mId); - inventoryItemCheck(Clothing, messages, id.toString(), true); + const ESM::Clothing& clothing = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, clothing.mId); + inventoryItemCheck(clothing, messages, id.toString(), true); } void CSMTools::ReferenceableCheckStage::containerCheck( @@ -352,32 +352,32 @@ void CSMTools::ReferenceableCheckStage::containerCheck( const CSMWorld::RefIdDataContainer< ESM::Container >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Container& Container = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, Container.mId); + const ESM::Container& container = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, container.mId); //Checking for model, IIRC all containers should have a model - if (Container.mModel.empty()) + if (container.mModel.empty()) { - messages.push_back(id.toString() + "|" + Container.mId + " has no model"); + messages.push_back(id.toString() + "|" + container.mId + " has no model"); } //Checking for capacity (weight) - if (Container.mWeight < 0) //0 is allowed + if (container.mWeight < 0) //0 is allowed { - messages.push_back(id.toString() + "|" + Container.mId + " has negative weight (capacity)"); + messages.push_back(id.toString() + "|" + container.mId + " has negative weight (capacity)"); } //checking for name - if (Container.mName.empty()) + if (container.mName.empty()) { - messages.push_back(id.toString() + "|" + Container.mId + " has an empty name"); + messages.push_back(id.toString() + "|" + container.mId + " has an empty name"); } } @@ -386,95 +386,95 @@ void CSMTools::ReferenceableCheckStage::creatureCheck( const CSMWorld::RefIdDataContainer< ESM::Creature >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Creature& Creature = (dynamic_cast&>(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Creature, Creature.mId); + const ESM::Creature& creature = (dynamic_cast&>(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Creature, creature.mId); - if (Creature.mModel.empty()) + if (creature.mModel.empty()) { - messages.push_back(id.toString() + "|" + Creature.mId + " has no model"); + messages.push_back(id.toString() + "|" + creature.mId + " has no model"); } - if (Creature.mName.empty()) + if (creature.mName.empty()) { - messages.push_back(id.toString() + "|" + Creature.mId + " has an empty name"); + messages.push_back(id.toString() + "|" + creature.mId + " has an empty name"); } //stats checks - if (Creature.mData.mLevel < 1) + if (creature.mData.mLevel < 1) { - messages.push_back(id.toString() + "|" + Creature.mId + " has non-postive level"); + messages.push_back(id.toString() + "|" + creature.mId + " has non-postive level"); } - if (Creature.mData.mStrength < 0) + if (creature.mData.mStrength < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative strength"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative strength"); } - if (Creature.mData.mIntelligence < 0) + if (creature.mData.mIntelligence < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative intelligence"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative intelligence"); } - if (Creature.mData.mWillpower < 0) + if (creature.mData.mWillpower < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative willpower"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative willpower"); } - if (Creature.mData.mAgility < 0) + if (creature.mData.mAgility < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative agility"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative agility"); } - if (Creature.mData.mSpeed < 0) + if (creature.mData.mSpeed < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative speed"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative speed"); } - if (Creature.mData.mEndurance < 0) + if (creature.mData.mEndurance < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative endurance"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative endurance"); } - if (Creature.mData.mPersonality < 0) + if (creature.mData.mPersonality < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative personality"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative personality"); } - if (Creature.mData.mLuck < 0) + if (creature.mData.mLuck < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative luck"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative luck"); } - if (Creature.mData.mHealth < 0) + if (creature.mData.mHealth < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative health"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative health"); } - if (Creature.mData.mSoul < 0) + if (creature.mData.mSoul < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative soul value"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative soul value"); } for (int i = 0; i < 6; ++i) { - if (Creature.mData.mAttack[i] < 0) + if (creature.mData.mAttack[i] < 0) { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative attack strength"); + messages.push_back(id.toString() + "|" + creature.mId + " has negative attack strength"); break; } } //TODO, find meaning of other values - if (Creature.mData.mGold < 0) //It seems that this is for gold in merchant creatures + if (creature.mData.mGold < 0) //It seems that this is for gold in merchant creatures { - messages.push_back(id.toString() + "|" + Creature.mId + " has negative gold "); + messages.push_back(id.toString() + "|" + creature.mId + " has negative gold "); } } @@ -483,14 +483,14 @@ void CSMTools::ReferenceableCheckStage::doorCheck( const CSMWorld::RefIdDataContainer< ESM::Door >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Door& Door = (dynamic_cast&>(baserecord)).get(); + const ESM::Door& Door = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Door, Door.mId); //usual, name or model @@ -512,14 +512,14 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck( const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Ingredient& Ingredient = (dynamic_cast& >(baserecord)).get(); + const ESM::Ingredient& Ingredient = (dynamic_cast& >(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Ingredient, Ingredient.mId); inventoryItemCheck(Ingredient, messages, id.toString()); @@ -530,14 +530,14 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::CreatureLevList& CreatureLevList = (dynamic_cast& >(baserecord)).get(); + const ESM::CreatureLevList& CreatureLevList = (dynamic_cast& >(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, CreatureLevList.mId); //CreatureLevList but Type_CreatureLevelledList :/ @@ -549,14 +549,14 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck( const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::ItemLevList& ItemLevList = (dynamic_cast& >(baserecord)).get(); + const ESM::ItemLevList& ItemLevList = (dynamic_cast& >(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, ItemLevList.mId); listCheck(ItemLevList, messages, id.toString()); @@ -567,30 +567,30 @@ void CSMTools::ReferenceableCheckStage::lightCheck( const CSMWorld::RefIdDataContainer< ESM::Light >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Light& Light = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Light, Light.mId); + const ESM::Light& light = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Light, light.mId); - if (Light.mData.mRadius < 0) + if (light.mData.mRadius < 0) { - messages.push_back(id.toString() + "|" + Light.mId + " has negative light radius"); + messages.push_back(id.toString() + "|" + light.mId + " has negative light radius"); } - if (Light.mData.mFlags & ESM::Light::Carry) + if (light.mData.mFlags & ESM::Light::Carry) { - if (Light.mIcon.empty()) //Needs to be checked with carrable flag + if (light.mIcon.empty()) //Needs to be checked with carrable flag { - inventoryItemCheck(Light, messages, id.toString()); + inventoryItemCheck(light, messages, id.toString()); - if (Light.mData.mTime == 0) + if (light.mData.mTime == 0) { - messages.push_back(id.toString() + "|" + Light.mId + " has zero duration"); + messages.push_back(id.toString() + "|" + light.mId + " has zero duration"); } } } @@ -601,19 +601,19 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck( const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Lockpick& Lockpick = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Lockpick, Lockpick.mId); + const ESM::Lockpick& lockpick = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Lockpick, lockpick.mId); - inventoryItemCheck(Lockpick, messages, id.toString()); + inventoryItemCheck(lockpick, messages, id.toString()); - toolCheck(Lockpick, messages, id.toString(), true); + toolCheck(lockpick, messages, id.toString(), true); } void CSMTools::ReferenceableCheckStage::miscCheck( @@ -621,17 +621,17 @@ void CSMTools::ReferenceableCheckStage::miscCheck( const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Miscellaneous& Miscellaneous = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, Miscellaneous.mId); + const ESM::Miscellaneous& miscellaneous = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, miscellaneous.mId); - inventoryItemCheck(Miscellaneous, messages, id.toString()); + inventoryItemCheck(miscellaneous, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::npcCheck( @@ -639,22 +639,22 @@ void CSMTools::ReferenceableCheckStage::npcCheck( const CSMWorld::RefIdDataContainer< ESM::NPC >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::NPC& NPC = (dynamic_cast& >(baserecord)).get(); + const ESM::NPC& NPC = (dynamic_cast& >(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc, NPC.mId); short level(NPC.mNpdt52.mLevel); - char Disposition(NPC.mNpdt52.mDisposition); - char Reputation(NPC.mNpdt52.mReputation); - char Rank(NPC.mNpdt52.mRank); + char disposition(NPC.mNpdt52.mDisposition); + char reputation(NPC.mNpdt52.mReputation); + char rank(NPC.mNpdt52.mRank); //Don't know what unknown is for - int Gold(NPC.mNpdt52.mGold); + int gold(NPC.mNpdt52.mGold); if (NPC.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated { @@ -665,10 +665,10 @@ void CSMTools::ReferenceableCheckStage::npcCheck( } level = NPC.mNpdt12.mLevel; - Disposition = NPC.mNpdt12.mDisposition; - Reputation = NPC.mNpdt12.mReputation; - Rank = NPC.mNpdt12.mRank; - Gold = NPC.mNpdt12.mGold; + disposition = NPC.mNpdt12.mDisposition; + reputation = NPC.mNpdt12.mReputation; + rank = NPC.mNpdt12.mRank; + gold = NPC.mNpdt12.mGold; } else { @@ -728,7 +728,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( messages.push_back(id.toString() + "|" + NPC.mId + " level is non positive"); } - if (Gold < 0) + if (gold < 0) { messages.push_back(id.toString() + "|" + NPC.mId + " gold has negative value"); } @@ -773,19 +773,19 @@ void CSMTools::ReferenceableCheckStage::npcCheck( } } - if (Disposition < 0) + if (disposition < 0) { messages.push_back(id.toString() + "|" + NPC.mId + " has negative disposition"); } - if (Reputation < 0) //It seems that no character in Morrowind.esm have negative reputation. I'm assuming that negative reputation is invalid + if (reputation < 0) //It seems that no character in Morrowind.esm have negative reputation. I'm assuming that negative reputation is invalid { messages.push_back(id.toString() + "|" + NPC.mId + " has negative reputation"); } if (NPC.mFaction.empty() == false) { - if (Rank < 0) + if (rank < 0) { messages.push_back(id.toString() + "|" + NPC.mId + " has negative rank"); } @@ -814,82 +814,82 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( const CSMWorld::RefIdDataContainer< ESM::Weapon >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Weapon& Weapon = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Weapon, Weapon.mId); + const ESM::Weapon& weapon = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Weapon, weapon.mId); //TODO, It seems that this stuff for spellcasting is obligatory and In fact We should check if records are present if ( //THOSE ARE HARDCODED! - !(Weapon.mId == "VFX_Hands" || - Weapon.mId == "VFX_Absorb" || - Weapon.mId == "VFX_Reflect" || - Weapon.mId == "VFX_DefaultBolt" || + !(weapon.mId == "VFX_Hands" || + weapon.mId == "VFX_Absorb" || + weapon.mId == "VFX_Reflect" || + weapon.mId == "VFX_DefaultBolt" || //TODO I don't know how to get full list of effects :/ //DANGER!, ACHTUNG! FIXME! The following is the list of the magical bolts, valid for Morrowind.esm. However those are not hardcoded. - Weapon.mId == "magic_bolt" || - Weapon.mId == "shock_bolt" || - Weapon.mId == "shield_bolt" || - Weapon.mId == "VFX_DestructBolt" || - Weapon.mId == "VFX_PoisonBolt" || - Weapon.mId == "VFX_RestoreBolt" || - Weapon.mId == "VFX_AlterationBolt" || - Weapon.mId == "VFX_ConjureBolt" || - Weapon.mId == "VFX_FrostBolt" || - Weapon.mId == "VFX_MysticismBolt" || - Weapon.mId == "VFX_IllusionBolt" || - Weapon.mId == "VFX_Multiple2" || - Weapon.mId == "VFX_Multiple3" || - Weapon.mId == "VFX_Multiple4" || - Weapon.mId == "VFX_Multiple5" || - Weapon.mId == "VFX_Multiple6" || - Weapon.mId == "VFX_Multiple7" || - Weapon.mId == "VFX_Multiple8" || - Weapon.mId == "VFX_Multiple9")) + weapon.mId == "magic_bolt" || + weapon.mId == "shock_bolt" || + weapon.mId == "shield_bolt" || + weapon.mId == "VFX_DestructBolt" || + weapon.mId == "VFX_PoisonBolt" || + weapon.mId == "VFX_RestoreBolt" || + weapon.mId == "VFX_AlterationBolt" || + weapon.mId == "VFX_ConjureBolt" || + weapon.mId == "VFX_FrostBolt" || + weapon.mId == "VFX_MysticismBolt" || + weapon.mId == "VFX_IllusionBolt" || + weapon.mId == "VFX_Multiple2" || + weapon.mId == "VFX_Multiple3" || + weapon.mId == "VFX_Multiple4" || + weapon.mId == "VFX_Multiple5" || + weapon.mId == "VFX_Multiple6" || + weapon.mId == "VFX_Multiple7" || + weapon.mId == "VFX_Multiple8" || + weapon.mId == "VFX_Multiple9")) { - inventoryItemCheck(Weapon, messages, id.toString(), true); + inventoryItemCheck(weapon, messages, id.toString(), true); - if (!(Weapon.mData.mType == ESM::Weapon::MarksmanBow || - Weapon.mData.mType == ESM::Weapon::MarksmanCrossbow || - Weapon.mData.mType == ESM::Weapon::MarksmanThrown || - Weapon.mData.mType == ESM::Weapon::Arrow || - Weapon.mData.mType == ESM::Weapon::Bolt)) + if (!(weapon.mData.mType == ESM::Weapon::MarksmanBow || + weapon.mData.mType == ESM::Weapon::MarksmanCrossbow || + weapon.mData.mType == ESM::Weapon::MarksmanThrown || + weapon.mData.mType == ESM::Weapon::Arrow || + weapon.mData.mType == ESM::Weapon::Bolt)) { - if (Weapon.mData.mSlash[0] > Weapon.mData.mSlash[1]) + if (weapon.mData.mSlash[0] > weapon.mData.mSlash[1]) { - messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum slash damage higher than maximum"); + messages.push_back(id.toString() + "|" + weapon.mId + " has minimum slash damage higher than maximum"); } - if (Weapon.mData.mThrust[0] > Weapon.mData.mThrust[1]) + if (weapon.mData.mThrust[0] > weapon.mData.mThrust[1]) { - messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum thrust damage higher than maximum"); + messages.push_back(id.toString() + "|" + weapon.mId + " has minimum thrust damage higher than maximum"); } } - if (Weapon.mData.mChop[0] > Weapon.mData.mChop[1]) + if (weapon.mData.mChop[0] > weapon.mData.mChop[1]) { - messages.push_back(id.toString() + "|" + Weapon.mId + " has minimum chop damage higher than maximum"); + messages.push_back(id.toString() + "|" + weapon.mId + " has minimum chop damage higher than maximum"); } - if (!(Weapon.mData.mType == ESM::Weapon::Arrow || - Weapon.mData.mType == ESM::Weapon::Bolt || - Weapon.mData.mType == ESM::Weapon::MarksmanThrown)) + if (!(weapon.mData.mType == ESM::Weapon::Arrow || + weapon.mData.mType == ESM::Weapon::Bolt || + weapon.mData.mType == ESM::Weapon::MarksmanThrown)) { //checking of health - if (Weapon.mData.mHealth <= 0) + if (weapon.mData.mHealth <= 0) { - messages.push_back(id.toString() + "|" + Weapon.mId + " has non-positivie health"); + messages.push_back(id.toString() + "|" + weapon.mId + " has non-positivie health"); } - if (Weapon.mData.mReach < 0) + if (weapon.mData.mReach < 0) { - messages.push_back(id.toString() + "|" + Weapon.mId + " has negative reach"); + messages.push_back(id.toString() + "|" + weapon.mId + " has negative reach"); } } } @@ -900,18 +900,18 @@ void CSMTools::ReferenceableCheckStage::probeCheck( const CSMWorld::RefIdDataContainer< ESM::Probe >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Probe& Probe = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Probe, Probe.mId); + const ESM::Probe& probe = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Probe, probe.mId); - inventoryItemCheck(Probe, messages, id.toString()); - toolCheck(Probe, messages, id.toString(), true); + inventoryItemCheck(probe, messages, id.toString()); + toolCheck(probe, messages, id.toString(), true); } void CSMTools::ReferenceableCheckStage::repairCheck( @@ -919,18 +919,18 @@ void CSMTools::ReferenceableCheckStage::repairCheck( const CSMWorld::RefIdDataContainer< ESM::Repair >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Repair& Repair = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Repair, Repair.mId); + const ESM::Repair& repair = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Repair, repair.mId); - inventoryItemCheck(Repair, messages, id.toString()); - toolCheck(Repair, messages, id.toString(), true); + inventoryItemCheck(repair, messages, id.toString()); + toolCheck(repair, messages, id.toString(), true); } void CSMTools::ReferenceableCheckStage::staticCheck( @@ -938,19 +938,19 @@ void CSMTools::ReferenceableCheckStage::staticCheck( const CSMWorld::RefIdDataContainer< ESM::Static >& records, std::vector< std::string >& messages) { - const CSMWorld::RecordBase& baserecord = records.getRecord(stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); - if (baserecord.isDeleted()) + if (baseRecord.isDeleted()) { return; } - const ESM::Static& Static = (dynamic_cast& >(baserecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Static, Static.mId); + const ESM::Static& static = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Static, static.mId); - if (Static.mModel.empty()) + if (static.mModel.empty()) { - messages.push_back(id.toString() + "|" + Static.mId + " has no model"); + messages.push_back(id.toString() + "|" + static.mId + " has no model"); } } @@ -958,128 +958,128 @@ void CSMTools::ReferenceableCheckStage::staticCheck( //Templates begins here template void CSMTools::ReferenceableCheckStage::inventoryItemCheck( - const ITEM& someitem, + const ITEM& someItem, std::vector< std::string >& messages, - const std::string& someid, bool enchantable) + const std::string& someID, bool enchantable) { - if (someitem.mName.empty()) + if (someItem.mName.empty()) { - messages.push_back(someid + "|" + someitem.mId + " has an empty name"); + messages.push_back(someID + "|" + someItem.mId + " has an empty name"); } //Checking for weight - if (someitem.mData.mWeight < 0) + if (someItem.mData.mWeight < 0) { - messages.push_back(someid + "|" + someitem.mId + " has negative weight"); + messages.push_back(someID + "|" + someItem.mId + " has negative weight"); } //Checking for value - if (someitem.mData.mValue < 0) + if (someItem.mData.mValue < 0) { - messages.push_back(someid + "|" + someitem.mId + " has negative value"); + messages.push_back(someID + "|" + someItem.mId + " has negative value"); } //checking for model - if (someitem.mModel.empty()) + if (someItem.mModel.empty()) { - messages.push_back(someid + "|" + someitem.mId + " has no model"); + messages.push_back(someID + "|" + someItem.mId + " has no model"); } //checking for icon - if (someitem.mIcon.empty()) + if (someItem.mIcon.empty()) { - messages.push_back(someid + "|" + someitem.mId + " has no icon"); + messages.push_back(someID + "|" + someItem.mId + " has no icon"); } if (enchantable) { - if (someitem.mData.mEnchant < 0) + if (someItem.mData.mEnchant < 0) { - messages.push_back(someid + "|" + someitem.mId + " has negative enchantment"); + messages.push_back(someID + "|" + someItem.mId + " has negative enchantment"); } } } template void CSMTools::ReferenceableCheckStage::inventoryItemCheck( - const ITEM& someitem, + const ITEM& someItem, std::vector< std::string >& messages, - const std::string& someid) + const std::string& someID) { - if (someitem.mName.empty()) + if (someItem.mName.empty()) { - messages.push_back(someid + "|" + someitem.mId + " has an empty name"); + messages.push_back(someID + "|" + someItem.mId + " has an empty name"); } //Checking for weight - if (someitem.mData.mWeight < 0) + if (someItem.mData.mWeight < 0) { - messages.push_back(someid + "|" + someitem.mId + " has negative weight"); + messages.push_back(someID + "|" + someItem.mId + " has negative weight"); } //Checking for value - if (someitem.mData.mValue < 0) + if (someItem.mData.mValue < 0) { - messages.push_back(someid + "|" + someitem.mId + " has negative value"); + messages.push_back(someID + "|" + someItem.mId + " has negative value"); } //checking for model - if (someitem.mModel.empty()) + if (someItem.mModel.empty()) { - messages.push_back(someid + "|" + someitem.mId + " has no model"); + messages.push_back(someID + "|" + someItem.mId + " has no model"); } //checking for icon - if (someitem.mIcon.empty()) + if (someItem.mIcon.empty()) { - messages.push_back(someid + "|" + someitem.mId + " has no icon"); + messages.push_back(someID + "|" + someItem.mId + " has no icon"); } } template void CSMTools::ReferenceableCheckStage::toolCheck( - const TOOL& sometool, + const TOOL& someTool, std::vector< std::string >& messages, - const std::string& someid, bool canbebroken) + const std::string& someID, bool canBeBroken) { - if (sometool.mData.mQuality <= 0) + if (someTool.mData.mQuality <= 0) { - messages.push_back(someid + "|" + sometool.mId + " has non-positive quality"); + messages.push_back(someID + "|" + someTool.mId + " has non-positive quality"); } - if (canbebroken) + if (canBeBroken) { - if (sometool.mData.mUses <= 0) + if (someTool.mData.mUses <= 0) { - messages.push_back(someid + "|" + sometool.mId + " has non-positive uses count"); + messages.push_back(someID + "|" + someTool.mId + " has non-positive uses count"); } } } template void CSMTools::ReferenceableCheckStage::toolCheck( - const TOOL& sometool, + const TOOL& someTool, std::vector< std::string >& messages, - const std::string& someid) + const std::string& someID) { - if (sometool.mData.mQuality <= 0) + if (someTool.mData.mQuality <= 0) { - messages.push_back(someid + "|" + sometool.mId + " has non-positive quality"); + messages.push_back(someID + "|" + someTool.mId + " has non-positive quality"); } } template void CSMTools::ReferenceableCheckStage::listCheck( - const LIST& somelist, + const LIST& someList, std::vector< std::string >& messages, - const std::string& someid) + const std::string& someID) { - for (unsigned i = 0; i < somelist.mList.size(); ++i) + for (unsigned i = 0; i < someList.mList.size(); ++i) { - if (mReferencables.searchId(somelist.mList[i].mId).first == -1) + if (mReferencables.searchId(someList.mList[i].mId).first == -1) { - messages.push_back(someid + "|" + somelist.mId + " contains item without referencable"); + messages.push_back(someid + "|" + someList.mId + " contains item without referencable"); } - if (somelist.mList[i].mLevel < 1) + if (someList.mList[i].mLevel < 1) { - messages.push_back(someid + "|" + somelist.mId + " contains item with non-positive level"); + messages.push_back(someid + "|" + someList.mId + " contains item with non-positive level"); } } } From 80d424591f2ba3b0093d02a631285878eb0655e7 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 5 Jan 2014 17:28:47 +0100 Subject: [PATCH 055/168] npc instead of NPC. --- .../opencs/model/tools/referenceablecheck.cpp | 120 +++++++++--------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 7d9210593b..64260e0a27 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -165,15 +165,15 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str stage -= miscSize; - const int NPCSize(mReferencables.getNPCs().getSize()); + const int npcSize(mReferencables.getNPCs().getSize()); - if (stage < NPCSize) + if (stage < npcSize) { npcCheck(stage, mReferencables.getNPCs(), messages); return; } - stage -= NPCSize; + stage -= npcSize; const int weaponSize(mReferencables.getWeapons().getSize()); @@ -646,113 +646,113 @@ void CSMTools::ReferenceableCheckStage::npcCheck( return; } - const ESM::NPC& NPC = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc, NPC.mId); + const ESM::NPC& npc = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc, npc.mId); - short level(NPC.mNpdt52.mLevel); - char disposition(NPC.mNpdt52.mDisposition); - char reputation(NPC.mNpdt52.mReputation); - char rank(NPC.mNpdt52.mRank); + short level(npc.mNpdt52.mLevel); + char disposition(npc.mNpdt52.mDisposition); + char reputation(npc.mNpdt52.mReputation); + char rank(npc.mNpdt52.mRank); //Don't know what unknown is for - int gold(NPC.mNpdt52.mGold); + int gold(npc.mNpdt52.mGold); - if (NPC.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated + if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated { - if ((NPC.mFlags & ESM::NPC::Autocalc) == 0) //0x0008 = autocalculated flag + if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0008 = autocalculated flag { - messages.push_back(id.toString() + "|" + NPC.mId + " mNpdtType or flags mismatch!"); //should not happend? + messages.push_back(id.toString() + "|" + npc.mId + " mNpdtType or flags mismatch!"); //should not happend? return; } - level = NPC.mNpdt12.mLevel; - disposition = NPC.mNpdt12.mDisposition; - reputation = NPC.mNpdt12.mReputation; - rank = NPC.mNpdt12.mRank; - gold = NPC.mNpdt12.mGold; + level = npc.mNpdt12.mLevel; + disposition = npc.mNpdt12.mDisposition; + reputation = npc.mNpdt12.mReputation; + rank = npc.mNpdt12.mRank; + gold = npc.mNpdt12.mGold; } else { - if (NPC.mNpdt52.mMana < 0) + if (npc.mNpdt52.mMana < 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " mana has negative value"); + messages.push_back(id.toString() + "|" + npc.mId + " mana has negative value"); } - if (NPC.mNpdt52.mFatigue < 0) + if (npc.mNpdt52.mFatigue < 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " fatigue has negative value"); + messages.push_back(id.toString() + "|" + npc.mId + " fatigue has negative value"); } - if (NPC.mNpdt52.mAgility == 0) + if (npc.mNpdt52.mAgility == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " agility has zero value"); + messages.push_back(id.toString() + "|" + npc.mId + " agility has zero value"); } - if (NPC.mNpdt52.mEndurance == 0) + if (npc.mNpdt52.mEndurance == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " endurance has zero value"); + messages.push_back(id.toString() + "|" + npc.mId + " endurance has zero value"); } - if (NPC.mNpdt52.mIntelligence == 0) + if (npc.mNpdt52.mIntelligence == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " intelligence has zero value"); + messages.push_back(id.toString() + "|" + npc.mId + " intelligence has zero value"); } - if (NPC.mNpdt52.mLuck == 0) + if (npc.mNpdt52.mLuck == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " luck has zero value"); + messages.push_back(id.toString() + "|" + npc.mId + " luck has zero value"); } - if (NPC.mNpdt52.mPersonality == 0) + if (npc.mNpdt52.mPersonality == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " personality has zero value"); + messages.push_back(id.toString() + "|" + npc.mId + " personality has zero value"); } - if (NPC.mNpdt52.mStrength == 0) + if (npc.mNpdt52.mStrength == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " strength has zero value"); + messages.push_back(id.toString() + "|" + npc.mId + " strength has zero value"); } - if (NPC.mNpdt52.mSpeed == 0) + if (npc.mNpdt52.mSpeed == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " speed has zero value"); + messages.push_back(id.toString() + "|" + npc.mId + " speed has zero value"); } - if (NPC.mNpdt52.mWillpower == 0) + if (npc.mNpdt52.mWillpower == 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " willpower has zero value"); + messages.push_back(id.toString() + "|" + npc.mId + " willpower has zero value"); } } if (level < 1) { - messages.push_back(id.toString() + "|" + NPC.mId + " level is non positive"); + messages.push_back(id.toString() + "|" + npc.mId + " level is non positive"); } if (gold < 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " gold has negative value"); + messages.push_back(id.toString() + "|" + npc.mId + " gold has negative value"); } - if (NPC.mName.empty()) + if (npc.mName.empty()) { - messages.push_back(id.toString() + "|" + NPC.mId + " has any empty name"); + messages.push_back(id.toString() + "|" + npc.mId + " has any empty name"); } - if (NPC.mClass.empty()) + if (npc.mClass.empty()) { - messages.push_back(id.toString() + "|" + NPC.mId + " has any empty class"); + messages.push_back(id.toString() + "|" + npc.mId + " has any empty class"); } else //checking if there is such class { - if (mClasses.searchId(NPC.mClass) == -1) + if (mClasses.searchId(npc.mClass) == -1) { - messages.push_back(id.toString() + "|" + NPC.mId + " has invalid class"); + messages.push_back(id.toString() + "|" + npc.mId + " has invalid class"); } } - if (NPC.mRace.empty()) + if (npc.mRace.empty()) { - messages.push_back(id.toString() + "|" + NPC.mId + " has any empty race"); + messages.push_back(id.toString() + "|" + npc.mId + " has any empty race"); } else //checking if there is a such race { @@ -760,7 +760,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( for (int i = 0; i < mRaces.getSize(); ++i) { - if (dynamic_cast(mRaces.getRecord(i).get()).mName == NPC.mRace) //mId in class, mName for race. Stupid. + if (dynamic_cast(mRaces.getRecord(i).get()).mName == npc.mRace) //mId in class, mName for race. Stupid. { nosuchrace = false; break; @@ -769,41 +769,41 @@ void CSMTools::ReferenceableCheckStage::npcCheck( if (nosuchrace) { - messages.push_back(id.toString() + "|" + NPC.mId + " has invalid race"); + messages.push_back(id.toString() + "|" + npc.mId + " has invalid race"); } } if (disposition < 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " has negative disposition"); + messages.push_back(id.toString() + "|" + npc.mId + " has negative disposition"); } if (reputation < 0) //It seems that no character in Morrowind.esm have negative reputation. I'm assuming that negative reputation is invalid { - messages.push_back(id.toString() + "|" + NPC.mId + " has negative reputation"); + messages.push_back(id.toString() + "|" + npc.mId + " has negative reputation"); } - if (NPC.mFaction.empty() == false) + if (npc.mFaction.empty() == false) { if (rank < 0) { - messages.push_back(id.toString() + "|" + NPC.mId + " has negative rank"); + messages.push_back(id.toString() + "|" + npc.mId + " has negative rank"); } - if (mFactions.searchId(NPC.mFaction) == -1) + if (mFactions.searchId(npc.mFaction) == -1) { - messages.push_back(id.toString() + "|" + NPC.mId + " has invalid faction"); + messages.push_back(id.toString() + "|" + npc.mId + " has invalid faction"); } } - if (NPC.mHead.empty()) + if (npc.mHead.empty()) { - messages.push_back(id.toString() + "|" + NPC.mId + " has no head"); + messages.push_back(id.toString() + "|" + npc.mId + " has no head"); } - if (NPC.mHair.empty()) + if (npc.mHair.empty()) { - messages.push_back(id.toString() + "|" + NPC.mId + " has no hair"); + messages.push_back(id.toString() + "|" + npc.mId + " has no hair"); } //TODO: reputation, Disposition, rank, everything else From 43387063079d446429e916260b4fc70559e7ae0d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 5 Jan 2014 17:31:54 +0100 Subject: [PATCH 056/168] static is a keyword. renamed static to staticElement --- apps/opencs/model/tools/referenceablecheck.cpp | 12 ++++++------ apps/opencs/model/tools/referenceablecheck.hpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 64260e0a27..73c88a5071 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -945,12 +945,12 @@ void CSMTools::ReferenceableCheckStage::staticCheck( return; } - const ESM::Static& static = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Static, static.mId); + const ESM::Static& staticElement = (dynamic_cast& >(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Static, staticElement.mId); - if (static.mModel.empty()) + if (staticElement.mModel.empty()) { - messages.push_back(id.toString() + "|" + static.mId + " has no model"); + messages.push_back(id.toString() + "|" + staticElement.mId + " has no model"); } } @@ -1074,12 +1074,12 @@ template void CSMTools::ReferenceableCheckStage::listCheck( { if (mReferencables.searchId(someList.mList[i].mId).first == -1) { - messages.push_back(someid + "|" + someList.mId + " contains item without referencable"); + messages.push_back(someID + "|" + someList.mId + " contains item without referencable"); } if (someList.mList[i].mLevel < 1) { - messages.push_back(someid + "|" + someList.mId + " contains item with non-positive level"); + messages.push_back(someID + "|" + someList.mId + " contains item with non-positive level"); } } } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index feeb32e6ad..217e77a059 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -43,7 +43,7 @@ namespace CSMTools template void inventoryItemCheck(const ITEM& someitem, std::vector& messages, const std::string& someid); //for non-enchantable items. template void toolCheck(const TOOL& sometool, std::vector& messages, const std::string& someid, bool canbebroken); //for tools with uses. template void toolCheck(const TOOL& sometool, std::vector& messages, const std::string& someid); //for tools without uses. - template void listCheck(const LIST& some, std::vector< std::string >& messages, const std::string& someid); + template void listCheck(const LIST& somelist, std::vector< std::string >& messages, const std::string& Som); const CSMWorld::RefIdData& mReferencables; const CSMWorld::IdCollection& mRaces; From c69814ed14f0fa386847c28f012e728d34063bfb Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 5 Jan 2014 18:00:49 +0100 Subject: [PATCH 057/168] corrected one, additional name to follow policy --- apps/opencs/model/tools/referenceablecheck.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 73c88a5071..92d1162440 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -756,18 +756,18 @@ void CSMTools::ReferenceableCheckStage::npcCheck( } else //checking if there is a such race { - bool nosuchrace(true); + bool noSuchRace(true); for (int i = 0; i < mRaces.getSize(); ++i) { if (dynamic_cast(mRaces.getRecord(i).get()).mName == npc.mRace) //mId in class, mName for race. Stupid. { - nosuchrace = false; + noSuchRace = false; break; } } - if (nosuchrace) + if (noSuchRace) { messages.push_back(id.toString() + "|" + npc.mId + " has invalid race"); } From 06f85370878c8876cec2a1e93d87eae55a395cf6 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 6 Jan 2014 18:43:44 +0100 Subject: [PATCH 058/168] added final check for player npc. Removed useless includes. However, this code spams exceptions and I can't figure out why. --- .../opencs/model/tools/referenceablecheck.cpp | 41 +++++++++++++------ .../opencs/model/tools/referenceablecheck.hpp | 6 ++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 92d1162440..12f347afb6 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1,14 +1,6 @@ #include "referenceablecheck.hpp" - -#include -#include -#include -#include - #include "../world/record.hpp" - #include "../world/universalid.hpp" -#include CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, @@ -18,12 +10,18 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( mReferencables(referenceable), mClasses(classes), mRaces(races), - mFactions(faction) + mFactions(faction), + mPlayerPresent(false) { } void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) { + if (stage == mReferencables.getSize() - 1) + { + finalCheck(messages); + } + //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. const int bookSize(mReferencables.getBooks().getSize()); @@ -104,7 +102,6 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= doorSize; - const int ingredientSize(mReferencables.getIngredients().getSize()); if (stage < ingredientSize) @@ -296,7 +293,6 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck( inventoryItemCheck(apparatus, messages, id.toString()); - //checking for quality, 0 → apparatus is basicly useless, any negative → apparatus is harmfull instead of helpfull toolCheck(apparatus, messages, id.toString()); } @@ -656,6 +652,12 @@ void CSMTools::ReferenceableCheckStage::npcCheck( //Don't know what unknown is for int gold(npc.mNpdt52.mGold); + //Detect if player is present + if (npc.mId == "player") + { + mPlayerPresent = true; + } + if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated { if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0008 = autocalculated flag @@ -954,6 +956,19 @@ void CSMTools::ReferenceableCheckStage::staticCheck( } } +//final check + +void CSMTools::ReferenceableCheckStage::finalCheck(std::vector< std::string >& messages) +{ + if (!mPlayerPresent) + { + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc); + messages.push_back(id.toString() + "| There is no player record"); + } + + mPlayerPresent = false; +} + //Templates begins here @@ -1022,7 +1037,7 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe messages.push_back(someID + "|" + someItem.mId + " has negative value"); } -//checking for model + //checking for model if (someItem.mModel.empty()) { messages.push_back(someID + "|" + someItem.mId + " has no model"); @@ -1076,7 +1091,7 @@ template void CSMTools::ReferenceableCheckStage::listCheck( { messages.push_back(someID + "|" + someList.mId + " contains item without referencable"); } - + if (someList.mList[i].mLevel < 1) { messages.push_back(someID + "|" + someList.mId + " contains item with non-positive level"); diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 217e77a059..bc31ad537f 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -37,7 +37,10 @@ namespace CSMTools void probeCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void repairCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); void staticCheck(int stage, const CSMWorld::RefIdDataContainer& records, std::vector& messages); - + + //FINAL CHECK + void finalCheck(std::vector& messages); + //TEMPLATE CHECKS template void inventoryItemCheck(const ITEM& someitem, std::vector& messages, const std::string& someid, bool enchantable); //for all enchantable items. template void inventoryItemCheck(const ITEM& someitem, std::vector& messages, const std::string& someid); //for non-enchantable items. @@ -49,6 +52,7 @@ namespace CSMTools const CSMWorld::IdCollection& mRaces; const CSMWorld::IdCollection& mClasses; const CSMWorld::IdCollection& mFactions; + bool mPlayerPresent; }; } #endif // REFERENCEABLECHECKSTAGE_H From b85fe2becf57f7c377a0ea66438bfe4bb2c9693c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 6 Jan 2014 23:37:18 +0100 Subject: [PATCH 059/168] Changes according to the comment. --- apps/opencs/model/tools/referenceablecheck.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 12f347afb6..6132b34076 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1,6 +1,7 @@ #include "referenceablecheck.hpp" #include "../world/record.hpp" #include "../world/universalid.hpp" +#include CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, @@ -17,11 +18,6 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::string >& messages) { - if (stage == mReferencables.getSize() - 1) - { - finalCheck(messages); - } - //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. const int bookSize(mReferencables.getBooks().getSize()); @@ -102,6 +98,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str } stage -= doorSize; + const int ingredientSize(mReferencables.getIngredients().getSize()); if (stage < ingredientSize) @@ -209,11 +206,15 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str staticCheck(stage, mReferencables.getStatics(), messages); return; } +// if we come that far, we are about to perform our last, final check. + finalCheck(messages); + return; } int CSMTools::ReferenceableCheckStage::setup() { - return mReferencables.getSize(); + mPlayerPresent = false; + return mReferencables.getSize() + 1; } void CSMTools::ReferenceableCheckStage::bookCheck( @@ -965,8 +966,6 @@ void CSMTools::ReferenceableCheckStage::finalCheck(std::vector< std::string >& m CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc); messages.push_back(id.toString() + "| There is no player record"); } - - mPlayerPresent = false; } From 5c7e39a92f0a59c108d87141b1715c741f9f98e3 Mon Sep 17 00:00:00 2001 From: Sergey Shambir Date: Tue, 7 Jan 2014 04:12:37 +0400 Subject: [PATCH 060/168] Implemented script commands StartCombat, StopCombat, GetTarget. Also renamed one field of AIWander class because it's not longer unknown. --- apps/esmtool/record.cpp | 4 +- apps/openmw/mwmechanics/aiactivate.cpp | 38 ++++++++--------- apps/openmw/mwmechanics/aicombat.cpp | 7 ++- apps/openmw/mwmechanics/aicombat.hpp | 4 +- apps/openmw/mwmechanics/aiescort.cpp | 2 +- apps/openmw/mwmechanics/aifollow.cpp | 34 +++++++-------- apps/openmw/mwmechanics/aipackage.hpp | 13 +++++- apps/openmw/mwmechanics/aisequence.cpp | 17 +++++++- apps/openmw/mwmechanics/aisequence.hpp | 9 +++- apps/openmw/mwmechanics/aitravel.cpp | 2 +- apps/openmw/mwmechanics/aiwander.cpp | 2 +- apps/openmw/mwscript/aiextensions.cpp | 59 ++++++++++++++++++++++++++ components/compiler/extensions0.cpp | 3 ++ components/compiler/opcodes.hpp | 6 +++ components/esm/aipackage.hpp | 2 +- 15 files changed, 154 insertions(+), 48 deletions(-) diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index cc09452c91..a041bb2de1 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -13,8 +13,8 @@ void printAIPackage(ESM::AIPackage p) std::cout << " Distance: " << p.mWander.mDistance << std::endl; std::cout << " Duration: " << p.mWander.mDuration << std::endl; std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; - if (p.mWander.mUnk != 1) - std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; + if (p.mWander.mShouldRepeat != 1) + std::cout << " Unknown: " << (int)p.mWander.mShouldRepeat << std::endl; std::cout << " Idle: "; for (int i = 0; i != 8; i++) diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index ee0dcf96e5..531ba55686 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -1,21 +1,21 @@ #include "aiactivate.hpp" -#include +#include -MWMechanics::AiActivate::AiActivate(const std::string &objectId) -: mObjectId(objectId) -{ -} -MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const -{ - return new AiActivate(*this); -} -bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) -{ - std::cout << "AiActivate completed.\n"; - return true; -} - -int MWMechanics::AiActivate::getTypeId() const -{ - return 4; -} +MWMechanics::AiActivate::AiActivate(const std::string &objectId) +: mObjectId(objectId) +{ +} +MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const +{ + return new AiActivate(*this); +} +bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) +{ + std::cout << "AiActivate completed.\n"; + return true; +} + +int MWMechanics::AiActivate::getTypeId() const +{ + return TypeIdActivate; +} diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 6f643aa68c..3ce3665805 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -135,7 +135,7 @@ namespace MWMechanics int AiCombat::getTypeId() const { - return 5; + return TypeIdCombat; } unsigned int AiCombat::getPriority() const @@ -143,6 +143,11 @@ namespace MWMechanics return 1; } + const std::string &AiCombat::getTargetId() const + { + return mTargetId; + } + AiCombat *MWMechanics::AiCombat::clone() const { return new AiCombat(*this); diff --git a/apps/openmw/mwmechanics/aicombat.hpp b/apps/openmw/mwmechanics/aicombat.hpp index fa71e261fc..82efc043b9 100644 --- a/apps/openmw/mwmechanics/aicombat.hpp +++ b/apps/openmw/mwmechanics/aicombat.hpp @@ -23,6 +23,8 @@ namespace MWMechanics virtual unsigned int getPriority() const; + const std::string &getTargetId() const; + private: std::string mTargetId; @@ -33,4 +35,4 @@ namespace MWMechanics }; } -#endif \ No newline at end of file +#endif diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 5099625c06..d91e02be2b 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -179,7 +179,7 @@ namespace MWMechanics int AiEscort::getTypeId() const { - return 2; + return TypeIdEscort; } } diff --git a/apps/openmw/mwmechanics/aifollow.cpp b/apps/openmw/mwmechanics/aifollow.cpp index 73bf9259af..c5b1f1bf3c 100644 --- a/apps/openmw/mwmechanics/aifollow.cpp +++ b/apps/openmw/mwmechanics/aifollow.cpp @@ -1,7 +1,7 @@ #include "aifollow.hpp" -#include +#include -MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z) +MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z) : mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId) { } @@ -10,18 +10,18 @@ MWMechanics::AiFollow::AiFollow(const std::string &actorId,const std::string &ce { } -MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const -{ - return new AiFollow(*this); -} - - bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration) -{ - std::cout << "AiFollow completed.\n"; - return true; -} - - int MWMechanics::AiFollow::getTypeId() const -{ - return 3; -} +MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const +{ + return new AiFollow(*this); +} + + bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration) +{ + std::cout << "AiFollow completed.\n"; + return true; +} + + int MWMechanics::AiFollow::getTypeId() const +{ + return TypeIdFollow; +} diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 5832198dad..74c77bf978 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -12,7 +12,16 @@ namespace MWMechanics class AiPackage { public: - + enum TypeId { + TypeIdNone = -1, + TypeIdWander = 0, + TypeIdTravel = 1, + TypeIdEscort = 2, + TypeIdFollow = 3, + TypeIdActivate = 4, + TypeIdCombat = 5 + }; + virtual ~AiPackage(); virtual AiPackage *clone() const = 0; @@ -21,7 +30,7 @@ namespace MWMechanics ///< \return Package completed? virtual int getTypeId() const = 0; - ///< 0: Wanter, 1 Travel, 2 Escort, 3 Follow, 4 Activate + ///< @see enum TypeId virtual unsigned int getPriority() const {return 0;} ///< higher number is higher priority (0 beeing the lowest) diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index 6d461e5f63..5d0686084b 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -56,6 +56,21 @@ int MWMechanics::AiSequence::getTypeId() const return mPackages.front()->getTypeId(); } +bool MWMechanics::AiSequence::getCombatTarget(std::string &targetActorId) const +{ + if (getTypeId() != AiPackage::TypeIdCombat) + return false; + const AiCombat *combat = static_cast(mPackages.front()); + targetActorId = combat->getTargetId(); + return true; +} + +void MWMechanics::AiSequence::stopCombat() +{ + while (getTypeId() == AiPackage::TypeIdCombat) + mPackages.erase (mPackages.begin()); +} + bool MWMechanics::AiSequence::isPackageDone() const { return mDone; @@ -114,7 +129,7 @@ void MWMechanics::AiSequence::fill(const ESM::AIPackageList &list) std::vector idles; for (int i=0; i<8; ++i) idles.push_back(data.mIdle[i]); - package = new MWMechanics::AiWander(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mUnk); + package = new MWMechanics::AiWander(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mShouldRepeat); } else if (it->mType == ESM::AI_Escort) { diff --git a/apps/openmw/mwmechanics/aisequence.hpp b/apps/openmw/mwmechanics/aisequence.hpp index 0976ef0995..d65c316160 100644 --- a/apps/openmw/mwmechanics/aisequence.hpp +++ b/apps/openmw/mwmechanics/aisequence.hpp @@ -34,7 +34,14 @@ namespace MWMechanics virtual ~AiSequence(); int getTypeId() const; - ///< -1: None, 0: Wanter, 1 Travel, 2 Escort, 3 Follow, 4 Activate, 5 Combat + ///< @see enum AiPackage::TypeId + + bool getCombatTarget (std::string &targetActorId) const; + ///< Return true and assign target if combat package is currently + /// active, return false otherwise + + void stopCombat(); + ///< Removes all combat packages until first non-combat or stack empty. bool isPackageDone() const; ///< Has a package been completed during the last update? diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index f56c759967..db577a32fb 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -106,7 +106,7 @@ namespace MWMechanics int AiTravel::getTypeId() const { - return 1; + return TypeIdTravel; } } diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 93c94a3f49..e1f65a5092 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -254,7 +254,7 @@ namespace MWMechanics int AiWander::getTypeId() const { - return 0; + return TypeIdWander; } void AiWander::stopWalking(const MWWorld::Ptr& actor) diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 966a064c74..3c95e9ca11 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -16,6 +16,7 @@ #include "../mwmechanics/aifollow.hpp" #include "../mwmechanics/aitravel.hpp" #include "../mwmechanics/aiwander.hpp" +#include "../mwmechanics/aicombat.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -399,6 +400,58 @@ namespace MWScript } }; + template + class OpGetTarget : public Interpreter::Opcode0 + { + public: + virtual void execute (Interpreter::Runtime &runtime) + { + MWWorld::Ptr actor = R()(runtime); + std::string testedTargetId = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + const MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + std::string currentTargetId; + + bool targetsAreEqual = false; + if (creatureStats.getAiSequence().getCombatTarget (currentTargetId)) + { + if (currentTargetId == testedTargetId) + targetsAreEqual = true; + } + runtime.push(int(targetsAreEqual)); + } + }; + + template + class OpStartCombat : public Interpreter::Opcode0 + { + public: + virtual void execute (Interpreter::Runtime &runtime) + { + MWWorld::Ptr actor = R()(runtime); + std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + creatureStats.getAiSequence().stack(MWMechanics::AiCombat(actorID)); + if (actorID == "player") + creatureStats.setHostile(true); + } + }; + + template + class OpStopCombat : public Interpreter::Opcode0 + { + public: + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr actor = R()(runtime); + MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + creatureStats.getAiSequence().stopCombat(); + } + }; + template class OpToggleAI : public Interpreter::Opcode0 { @@ -436,6 +489,12 @@ namespace MWScript interpreter.installSegment3 (Compiler::Ai::opcodeGetDetectedExplicit, new OpGetDetected); interpreter.installSegment5 (Compiler::Ai::opcodeGetLineOfSight, new OpGetLineOfSight); interpreter.installSegment5 (Compiler::Ai::opcodeGetLineOfSightExplicit, new OpGetLineOfSight); + interpreter.installSegment5 (Compiler::Ai::opcodeGetTarget, new OpGetTarget); + interpreter.installSegment5 (Compiler::Ai::opcodeGetTargetExplicit, new OpGetTarget); + interpreter.installSegment5 (Compiler::Ai::opcodeStartCombat, new OpStartCombat); + interpreter.installSegment5 (Compiler::Ai::opcodeStartCombatExplicit, new OpStartCombat); + interpreter.installSegment5 (Compiler::Ai::opcodeStopCombat, new OpStopCombat); + interpreter.installSegment5 (Compiler::Ai::opcodeStopCombatExplicit, new OpStopCombat); interpreter.installSegment5 (Compiler::Ai::opcodeToggleAI, new OpToggleAI); interpreter.installSegment5 (Compiler::Ai::opcodeToggleAIExplicit, new OpToggleAI); diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index 6194be5327..4ad9dfc5e9 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -61,12 +61,15 @@ namespace Compiler extensions.registerInstruction ("modalarm", "l", opcodeModAlarm, opcodeModAlarmExplicit); extensions.registerInstruction ("toggleai", "", opcodeToggleAI, opcodeToggleAI); extensions.registerInstruction ("tai", "", opcodeToggleAI, opcodeToggleAI); + extensions.registerInstruction("startcombat", "c", opcodeStartCombat, opcodeStartCombatExplicit); + extensions.registerInstruction("stopcombat", "", opcodeStopCombat, opcodeStopCombatExplicit); extensions.registerFunction ("gethello", 'l', "", opcodeGetHello, opcodeGetHelloExplicit); extensions.registerFunction ("getfight", 'l', "", opcodeGetFight, opcodeGetFightExplicit); extensions.registerFunction ("getflee", 'l', "", opcodeGetFlee, opcodeGetFleeExplicit); extensions.registerFunction ("getalarm", 'l', "", opcodeGetAlarm, opcodeGetAlarmExplicit); extensions.registerFunction ("getlineofsight", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit); extensions.registerFunction ("getlos", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit); + extensions.registerFunction("gettarget", 'l', "c", opcodeGetTarget, opcodeGetTargetExplicit); } } diff --git a/components/compiler/opcodes.hpp b/components/compiler/opcodes.hpp index 46524c7cdd..f84614c37e 100644 --- a/components/compiler/opcodes.hpp +++ b/components/compiler/opcodes.hpp @@ -53,6 +53,12 @@ namespace Compiler const int opcodeGetLineOfSightExplicit = 0x2000223; const int opcodeToggleAI = 0x2000224; const int opcodeToggleAIExplicit = 0x2000225; + const int opcodeGetTarget = 0x2000b23; + const int opcodeGetTargetExplicit = 0x2000b24; + const int opcodeStartCombat = 0x2000b25; + const int opcodeStartCombatExplicit = 0x2000b26; + const int opcodeStopCombat = 0x2000b27; + const int opcodeStopCombatExplicit = 0x2000b28; } namespace Animation diff --git a/components/esm/aipackage.hpp b/components/esm/aipackage.hpp index b06cb529a7..8a31aadf55 100644 --- a/components/esm/aipackage.hpp +++ b/components/esm/aipackage.hpp @@ -30,7 +30,7 @@ namespace ESM short mDuration; unsigned char mTimeOfDay; unsigned char mIdle[8]; - unsigned char mUnk; + unsigned char mShouldRepeat; }; struct AITravel From d536ff3cdcca8d203bdc0575962f0dd582805a77 Mon Sep 17 00:00:00 2001 From: Sergey Shambir Date: Tue, 7 Jan 2014 04:58:59 +0400 Subject: [PATCH 061/168] printAIPackage: changed field name from Unknown to ShouldRepeat too. --- apps/esmtool/record.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index a041bb2de1..a5664c1c86 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -14,7 +14,7 @@ void printAIPackage(ESM::AIPackage p) std::cout << " Duration: " << p.mWander.mDuration << std::endl; std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; if (p.mWander.mShouldRepeat != 1) - std::cout << " Unknown: " << (int)p.mWander.mShouldRepeat << std::endl; + std::cout << " Should repeat: " << (bool)p.mWander.mShouldRepeat << std::endl; std::cout << " Idle: "; for (int i = 0; i != 8; i++) From d5a0ff17fde7204c6ac1ec3021a79ccb02237b1a Mon Sep 17 00:00:00 2001 From: Sergey Shambir Date: Tue, 7 Jan 2014 05:06:20 +0400 Subject: [PATCH 062/168] MWScript: updated vmformat.txt, changed opcodes to fix sequence. Opcodes for StartCombat, StopCombat, GetTarget now follow the last previous opcode. --- apps/openmw/mwscript/docs/vmformat.txt | 8 +++++++- components/compiler/opcodes.hpp | 12 ++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 504a8638bf..3dc5492bf5 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -371,4 +371,10 @@ op 0x2000230: Resurrect, explicit op 0x2000231: GetSpellReadied op 0x2000232: GetSpellReadied, explicit op 0x2000233: GetPcJumping -opcodes 0x2000234-0x3ffffff unused +op 0x2000234: GetTarget +op 0x2000235: GetTargetExplicit +op 0x2000236: StartCombat +op 0x2000237: StartCombatExplicit +op 0x2000238: StopCombat +op 0x2000239: StopCombatExplicit +opcodes 0x2000239-0x3ffffff unused diff --git a/components/compiler/opcodes.hpp b/components/compiler/opcodes.hpp index f84614c37e..6f8f26e97b 100644 --- a/components/compiler/opcodes.hpp +++ b/components/compiler/opcodes.hpp @@ -53,12 +53,12 @@ namespace Compiler const int opcodeGetLineOfSightExplicit = 0x2000223; const int opcodeToggleAI = 0x2000224; const int opcodeToggleAIExplicit = 0x2000225; - const int opcodeGetTarget = 0x2000b23; - const int opcodeGetTargetExplicit = 0x2000b24; - const int opcodeStartCombat = 0x2000b25; - const int opcodeStartCombatExplicit = 0x2000b26; - const int opcodeStopCombat = 0x2000b27; - const int opcodeStopCombatExplicit = 0x2000b28; + const int opcodeGetTarget = 0x2000234; + const int opcodeGetTargetExplicit = 0x2000235; + const int opcodeStartCombat = 0x2000236; + const int opcodeStartCombatExplicit = 0x2000237; + const int opcodeStopCombat = 0x2000238; + const int opcodeStopCombatExplicit = 0x2000239; } namespace Animation From aa855e9524115d27c0dda59c69a7d0166f95e396 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 20:56:24 +0100 Subject: [PATCH 063/168] Include some required Ogre headers explicitely --- apps/opencs/view/render/scenewidget.cpp | 1 + apps/openmw/mwrender/characterpreview.cpp | 1 + apps/openmw/mwrender/occlusionquery.cpp | 1 + apps/openmw/mwrender/shadows.cpp | 1 + apps/openmw/mwrender/water.cpp | 1 + components/nifogre/ogrenifloader.cpp | 4 +++- libs/openengine/ogre/renderer.cpp | 1 + 7 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index c8b37e9bb0..620586bd2d 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace CSVRender { diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index f7333db35c..2dbc72e264 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index a69511acd7..2461034717 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "renderconst.hpp" diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index 21bbe51b63..9ebb0ab087 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 0a4db30e9c..9e3105168b 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "sky.hpp" #include "renderingmanager.hpp" diff --git a/components/nifogre/ogrenifloader.cpp b/components/nifogre/ogrenifloader.cpp index 0c1fdfbee8..5a76b702eb 100644 --- a/components/nifogre/ogrenifloader.cpp +++ b/components/nifogre/ogrenifloader.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -36,6 +35,9 @@ #include #include #include +#include +#include +#include #include diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 9e5ec5414d..c86697497f 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include From 546b0cee76477aff7409d90a6059d1591cad46e7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 22:17:51 +0100 Subject: [PATCH 064/168] Closes #1077: Replace tags before trying to get the message length --- apps/openmw/mwgui/messagebox.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 8e518668bd..72a5bd0b07 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -63,7 +63,8 @@ namespace MWGui { MessageBox *box = new MessageBox(*this, message); box->mCurrentTime = 0; - box->mMaxTime = message.length()*mMessageBoxSpeed; + std::string realMessage = MyGUI::LanguageManager::getInstance().replaceTags(message); + box->mMaxTime = realMessage.length()*mMessageBoxSpeed; if(stat) mStaticMessageBox = box; From bfdca3b73816831d45e86c2e806462c04fab5be2 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 23:13:31 +0100 Subject: [PATCH 065/168] Fix needTangents not being set for cached/shared materials --- components/nifogre/material.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/nifogre/material.cpp b/components/nifogre/material.cpp index be6ccbed64..e2cc3712b6 100644 --- a/components/nifogre/material.cpp +++ b/components/nifogre/material.cpp @@ -277,6 +277,8 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata, if (itr != sMaterialMap.end()) { // a suitable material exists already - use it + sh::MaterialInstance* instance = sh::Factory::getInstance().getMaterialInstance(itr->second); + needTangents = !sh::retrieveValue(instance->getProperty("normalMap"), instance).get().empty(); return itr->second; } // not found, create a new one From b98cdabe899e15b731ad4cad022d93cb7e2def1a Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 10 Jan 2014 09:42:36 +0100 Subject: [PATCH 066/168] Shameful bug fixed. --- apps/opencs/model/tools/referenceablecheck.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 6132b34076..940a251e37 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -206,6 +206,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str staticCheck(stage, mReferencables.getStatics(), messages); return; } + // if we come that far, we are about to perform our last, final check. finalCheck(messages); return; @@ -581,14 +582,11 @@ void CSMTools::ReferenceableCheckStage::lightCheck( if (light.mData.mFlags & ESM::Light::Carry) { - if (light.mIcon.empty()) //Needs to be checked with carrable flag - { - inventoryItemCheck(light, messages, id.toString()); + inventoryItemCheck(light, messages, id.toString()); - if (light.mData.mTime == 0) - { - messages.push_back(id.toString() + "|" + light.mId + " has zero duration"); - } + if (light.mData.mTime == 0) + { + messages.push_back(id.toString() + "|" + light.mId + " has zero duration"); } } } From e4d637fd6404c8b6c9a9282f3812df2ebda58289 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 10 Jan 2014 09:49:05 +0100 Subject: [PATCH 067/168] splited long lines in the header. --- .../opencs/model/tools/referenceablecheck.cpp | 1 - .../opencs/model/tools/referenceablecheck.hpp | 26 +++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 940a251e37..44bb7d302b 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -538,7 +538,6 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( const ESM::CreatureLevList& CreatureLevList = (dynamic_cast& >(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, CreatureLevList.mId); //CreatureLevList but Type_CreatureLevelledList :/ - listCheck(CreatureLevList, messages, id.toString()); } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index bc31ad537f..56a85c8fd7 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -42,11 +42,27 @@ namespace CSMTools void finalCheck(std::vector& messages); //TEMPLATE CHECKS - template void inventoryItemCheck(const ITEM& someitem, std::vector& messages, const std::string& someid, bool enchantable); //for all enchantable items. - template void inventoryItemCheck(const ITEM& someitem, std::vector& messages, const std::string& someid); //for non-enchantable items. - template void toolCheck(const TOOL& sometool, std::vector& messages, const std::string& someid, bool canbebroken); //for tools with uses. - template void toolCheck(const TOOL& sometool, std::vector& messages, const std::string& someid); //for tools without uses. - template void listCheck(const LIST& somelist, std::vector< std::string >& messages, const std::string& Som); + template void inventoryItemCheck(const ITEM& someitem, + std::vector& messages, + const std::string& someID, + bool enchantable); //for all enchantable items. + + template void inventoryItemCheck(const ITEM& someitem, + std::vector& messages, + const std::string& someID); //for non-enchantable items. + + template void toolCheck(const TOOL& sometool, + std::vector& messages, + const std::string& someID, + bool canbebroken); //for tools with uses. + + template void toolCheck(const TOOL& sometool, + std::vector& messages, + const std::string& someID); //for tools without uses. + + template void listCheck(const LIST& somelist, + std::vector< std::string >& messages, + const std::string& someID); const CSMWorld::RefIdData& mReferencables; const CSMWorld::IdCollection& mRaces; From 468b9d734030fb63415559c8eb4ccd556a953bee Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 10 Jan 2014 09:50:56 +0100 Subject: [PATCH 068/168] camel case in the header --- apps/opencs/model/tools/referenceablecheck.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 56a85c8fd7..dbfcd7574f 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -42,25 +42,25 @@ namespace CSMTools void finalCheck(std::vector& messages); //TEMPLATE CHECKS - template void inventoryItemCheck(const ITEM& someitem, + template void inventoryItemCheck(const ITEM& someItem, std::vector& messages, const std::string& someID, bool enchantable); //for all enchantable items. - template void inventoryItemCheck(const ITEM& someitem, + template void inventoryItemCheck(const ITEM& someItem, std::vector& messages, const std::string& someID); //for non-enchantable items. - template void toolCheck(const TOOL& sometool, + template void toolCheck(const TOOL& someTool, std::vector& messages, const std::string& someID, bool canbebroken); //for tools with uses. - template void toolCheck(const TOOL& sometool, + template void toolCheck(const TOOL& someTool, std::vector& messages, const std::string& someID); //for tools without uses. - template void listCheck(const LIST& somelist, + template void listCheck(const LIST& someList, std::vector< std::string >& messages, const std::string& someID); From 31c59db71cbc779a0f92ced726150c210b3e7b8f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 10 Jan 2014 10:22:18 +0100 Subject: [PATCH 069/168] Splited another long line in the header. --- apps/opencs/model/tools/referenceablecheck.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index dbfcd7574f..338983cc70 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -11,7 +11,11 @@ namespace CSMTools class ReferenceableCheckStage : public CSMDoc::Stage { public: - ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes, const CSMWorld::IdCollection& factions); + ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, + const CSMWorld::IdCollection& races, + const CSMWorld::IdCollection& classes, + const CSMWorld::IdCollection& factions); + virtual void perform(int stage, std::vector< std::string >& messages); virtual int setup(); From 688488de6243f0765766fc08b991b5d49b1d3214 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 10 Jan 2014 10:43:03 +0100 Subject: [PATCH 070/168] replaced == operator for string comparsion in npc check with boost algorithm to get case insensitive check. --- apps/opencs/model/tools/referenceablecheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 44bb7d302b..fccc5218b0 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1,7 +1,7 @@ #include "referenceablecheck.hpp" #include "../world/record.hpp" #include "../world/universalid.hpp" -#include +#include CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, @@ -651,7 +651,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( int gold(npc.mNpdt52.mGold); //Detect if player is present - if (npc.mId == "player") + if ( boost::algorithm::iequals(npc.mId, "player") ) { mPlayerPresent = true; } From cb0d3794f7c0247291f3b5d1db4b537cc43cd211 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 10 Jan 2014 10:57:54 +0100 Subject: [PATCH 071/168] Final check is not performed with just +1! Something is not right. --- apps/opencs/model/tools/referenceablecheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index fccc5218b0..36878d44b7 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -215,7 +215,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str int CSMTools::ReferenceableCheckStage::setup() { mPlayerPresent = false; - return mReferencables.getSize() + 1; + return mReferencables.getSize() + 2; //DANGER, final check is not performed if it is just +1 } void CSMTools::ReferenceableCheckStage::bookCheck( From 627dcddb333a2d8e881184bf1f6a1dd72d8d15b6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 10 Jan 2014 20:53:53 +0100 Subject: [PATCH 072/168] Do not allow training skills above their governing attribute --- apps/openmw/mwgui/trainingwindow.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 709bc0fb95..24be5363d6 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -130,6 +130,14 @@ namespace MWGui return; } + // You can not train a skill above its governing attribute + const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get().find(skillId); + if (pcStats.getSkill(skillId).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase()) + { + MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage17}"); + return; + } + // increase skill MWWorld::LiveCellRef *playerRef = player.get(); From f5a70dccf0f65269fa992503f9d809d8ba56f155 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 10 Jan 2014 21:13:03 +0100 Subject: [PATCH 073/168] Fix title of buttons in generate class result dialog --- apps/openmw/mwgui/class.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 6c46f21763..7965669f19 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -29,11 +29,12 @@ namespace MWGui MyGUI::Button* backButton; getWidget(backButton, "BackButton"); + backButton->setCaptionWithReplacing("#{sMessageQuestionAnswer3}"); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked); MyGUI::Button* okButton; getWidget(okButton, "OKButton"); - okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", "")); + okButton->setCaptionWithReplacing("#{sMessageQuestionAnswer2}"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked); } From 3bf36515d52dcd7cd632a37f29d603eedf662259 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 10 Jan 2014 21:26:24 +0100 Subject: [PATCH 074/168] Implement Trespassing crime --- apps/openmw/mwbase/mechanicsmanager.hpp | 2 ++ .../mwmechanics/mechanicsmanagerimp.cpp | 26 ++++++++++++------- .../mwmechanics/mechanicsmanagerimp.hpp | 2 ++ apps/openmw/mwmechanics/security.cpp | 3 +++ apps/openmw/mwmechanics/spellcasting.cpp | 12 +++++---- apps/openmw/mwmechanics/spellcasting.hpp | 2 +- apps/openmw/mwworld/inventorystore.cpp | 2 +- 7 files changed, 32 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 24e955cdf1..85fcfc75ba 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -112,6 +112,8 @@ namespace MWBase OffenseType type, int arg=0) = 0; /// Utility to check if taking this item is illegal and calling commitCrime if so virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count) = 0; + /// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so + virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0; /// Attempt sleeping in a bed. If this is illegal, call commitCrime. /// @return was it illegal, and someone saw you doing it? virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) = 0; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 511fe65447..002cd561d6 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -19,7 +19,7 @@ namespace { /// @return is \a ptr allowed to take/use \a item or is it a crime? - bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) + bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim) { const std::string& owner = item.getCellRef().mOwner; bool isOwned = !owner.empty(); @@ -33,6 +33,9 @@ namespace isFactionOwned = true; } + if (!item.getCellRef().mOwner.empty()) + victim = MWBase::Environment::get().getWorld()->getPtr(item.getCellRef().mOwner, true); + return (!isOwned && !isFactionOwned); } } @@ -752,11 +755,9 @@ namespace MWMechanics bool MechanicsManager::sleepInBed(const MWWorld::Ptr &ptr, const MWWorld::Ptr &bed) { - if (isAllowedToUse(ptr, bed)) - return false; MWWorld::Ptr victim; - if (!bed.getCellRef().mOwner.empty()) - victim = MWBase::Environment::get().getWorld()->getPtr(bed.getCellRef().mOwner, true); + if (isAllowedToUse(ptr, bed, victim)) + return false; if(commitCrime(ptr, victim, OT_SleepingInOwnedBed)) { @@ -767,14 +768,19 @@ namespace MWMechanics return false; } + void MechanicsManager::objectOpened(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item) + { + MWWorld::Ptr victim; + if (isAllowedToUse(ptr, item, victim)) + return; + commitCrime(ptr, victim, OT_Trespassing); + } + void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count) { - if (isAllowedToUse(ptr, item)) - return; MWWorld::Ptr victim; - if (!item.getCellRef().mOwner.empty()) - victim = MWBase::Environment::get().getWorld()->getPtr(item.getCellRef().mOwner, true); - + if (isAllowedToUse(ptr, item, victim)) + return; commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index cec08fa92d..569cd2fca0 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -113,6 +113,8 @@ namespace MWMechanics OffenseType type, int arg=0); /// Utility to check if taking this item is illegal and calling commitCrime if so virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count); + /// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so + virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item); /// Attempt sleeping in a bed. If this is illegal, call commitCrime. /// @return was it illegal, and someone saw you doing it? virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed); diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 0769e13df5..2e5eaecfde 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -6,6 +6,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "npcstats.hpp" #include "creaturestats.hpp" @@ -45,6 +46,7 @@ namespace MWMechanics resultMessage = "#{sLockImpossible}"; else { + MWBase::Environment::get().getMechanicsManager()->objectOpened(mActor, lock); int roll = static_cast (std::rand()) / RAND_MAX * 100; if (roll <= x) { @@ -86,6 +88,7 @@ namespace MWMechanics resultMessage = "#{sTrapImpossible}"; else { + MWBase::Environment::get().getMechanicsManager()->objectOpened(mActor, trap); int roll = static_cast (std::rand()) / RAND_MAX * 100; if (roll <= x) { diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index a1cdb8b611..8c4c4d292e 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -4,7 +4,7 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" - +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/actionteleport.hpp" @@ -167,7 +167,7 @@ namespace MWMechanics } } else - applyInstantEffect(target, EffectKey(*effectIt), magnitude); + applyInstantEffect(target, caster, EffectKey(*effectIt), magnitude); // HACK: Damage attribute/skill actually has a duration, even though the actual effect is instant and permanent. // This was probably just done to have the effect visible in the magic menu for a while @@ -177,7 +177,7 @@ namespace MWMechanics || effectIt->mEffectID == ESM::MagicEffect::RestoreAttribute || effectIt->mEffectID == ESM::MagicEffect::RestoreSkill ) - applyInstantEffect(target, EffectKey(*effectIt), magnitude); + applyInstantEffect(target, caster, EffectKey(*effectIt), magnitude); if (target.getClass().isActor() || magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration) { @@ -220,7 +220,7 @@ namespace MWMechanics mSourceName, caster.getRefData().getHandle()); } - void CastSpell::applyInstantEffect(const MWWorld::Ptr &target, MWMechanics::EffectKey effect, float magnitude) + void CastSpell::applyInstantEffect(const MWWorld::Ptr &target, const MWWorld::Ptr &caster, MWMechanics::EffectKey effect, float magnitude) { short effectId = effect.mId; if (!target.getClass().isActor()) @@ -232,11 +232,13 @@ namespace MWMechanics } else if (effectId == ESM::MagicEffect::Open) { - // TODO: This is a crime if (target.getCellRef().mLockLevel <= magnitude) { if (target.getCellRef().mLockLevel > 0) + { MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f); + MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target); + } target.getCellRef().mLockLevel = 0; } else diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index a55c45fd16..438b65575f 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -203,7 +203,7 @@ namespace MWMechanics void inflict (const MWWorld::Ptr& target, const MWWorld::Ptr& caster, const ESM::EffectList& effects, ESM::RangeType range, bool reflected=false); - void applyInstantEffect (const MWWorld::Ptr& target, MWMechanics::EffectKey effect, float magnitude); + void applyInstantEffect (const MWWorld::Ptr& target, const MWWorld::Ptr& caster, MWMechanics::EffectKey effect, float magnitude); }; } diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 2aee74eeeb..b11c22c72d 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -392,7 +392,7 @@ void MWWorld::InventoryStore::updateMagicEffects(const Ptr& actor) // Apply instant effects MWMechanics::CastSpell cast(actor, actor); if (magnitude) - cast.applyInstantEffect(actor, effectIt->mEffectID, magnitude); + cast.applyInstantEffect(actor, actor, effectIt->mEffectID, magnitude); } if (magnitude) From 2744cde40fea2ff24f009740fd64512900b752b9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 10 Jan 2014 22:27:31 +0100 Subject: [PATCH 075/168] Use a few additional GMSTs --- apps/openmw/mwgui/enchantingdialog.cpp | 2 +- apps/openmw/mwgui/messagebox.cpp | 5 ++--- apps/openmw/mwgui/messagebox.hpp | 2 +- apps/openmw/mwgui/windowmanagerimp.cpp | 3 ++- apps/openmw/mwmechanics/actors.cpp | 8 ++++++-- files/mygui/openmw_spell_buying_window.layout | 2 +- files/mygui/openmw_travel_window.layout | 4 ++-- 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 4d79875a28..d9d2a2ea8a 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -257,7 +257,7 @@ namespace MWGui { if (mEffects.size() <= 0) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage30}"); + MWBase::Environment::get().getWindowManager()->messageBox ("#{sEnchantmentMenu11}"); return; } diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 72a5bd0b07..b0abaef142 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -8,13 +8,12 @@ namespace MWGui { - MessageBoxManager::MessageBoxManager () + MessageBoxManager::MessageBoxManager (float timePerChar) { - // TODO: fMessageTimePerChar - mMessageBoxSpeed = 0.1; mInterMessageBoxe = NULL; mStaticMessageBox = NULL; mLastButtonPressed = -1; + mMessageBoxSpeed = timePerChar; } MessageBoxManager::~MessageBoxManager () diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index 0288f366ce..e82a51642d 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -22,7 +22,7 @@ namespace MWGui class MessageBoxManager { public: - MessageBoxManager (); + MessageBoxManager (float timePerChar); ~MessageBoxManager (); void onFrame (float frameDuration); void createMessageBox (const std::string& message, bool stat = false); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 3accd925f6..e4297f8fcd 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -207,7 +207,8 @@ namespace MWGui mConsole = new Console(w,h, mConsoleOnlyScripts); trackWindow(mConsole, "console"); mJournal = JournalWindow::create(JournalViewModel::create ()); - mMessageBoxManager = new MessageBoxManager(); + mMessageBoxManager = new MessageBoxManager( + MWBase::Environment::get().getWorld()->getStore().get().find("fMessageTimePerChar")->getFloat()); mInventoryWindow = new InventoryWindow(mDragAndDrop); mTradeWindow = new TradeWindow(); trackWindow(mTradeWindow, "barter"); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0a4adb6e2f..afc94255bb 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -581,7 +581,8 @@ namespace MWMechanics if(timeLeft == 0.0f) { // If drowning, apply 3 points of damage per second - ptr.getClass().setActorHealth(ptr, stats.getHealth().getCurrent() - 3.0f*duration); + static const float fSuffocationDamage = world->getStore().get().find("fSuffocationDamage")->getFloat(); + ptr.getClass().setActorHealth(ptr, stats.getHealth().getCurrent() - fSuffocationDamage*duration); // Play a drowning sound as necessary for the player if(ptr == world->getPlayerPtr()) @@ -593,7 +594,10 @@ namespace MWMechanics } } else - stats.setTimeToStartDrowning(20); + { + static const float fHoldBreathTime = world->getStore().get().find("fHoldBreathTime")->getFloat(); + stats.setTimeToStartDrowning(fHoldBreathTime); + } } void Actors::updateEquippedLight (const MWWorld::Ptr& ptr, float duration) diff --git a/files/mygui/openmw_spell_buying_window.layout b/files/mygui/openmw_spell_buying_window.layout index 1510372ddb..b24a476c4c 100644 --- a/files/mygui/openmw_spell_buying_window.layout +++ b/files/mygui/openmw_spell_buying_window.layout @@ -11,7 +11,7 @@ - + diff --git a/files/mygui/openmw_travel_window.layout b/files/mygui/openmw_travel_window.layout index db3fa24a08..683d47fe71 100644 --- a/files/mygui/openmw_travel_window.layout +++ b/files/mygui/openmw_travel_window.layout @@ -11,7 +11,7 @@ - + @@ -32,4 +32,4 @@ - \ No newline at end of file + From 15e48107f7b5ee62e47be7d6d2ab17759395065e Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 10 Jan 2014 22:39:01 +0100 Subject: [PATCH 076/168] Use i1stPersonSneakDelta + some cleanup --- apps/openmw/mwmechanics/spellcasting.hpp | 12 ++++++------ apps/openmw/mwrender/camera.cpp | 5 ++--- apps/openmw/mwrender/camera.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 4 +++- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index 438b65575f..a1ae254f61 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -19,12 +19,12 @@ namespace MWMechanics inline int spellSchoolToSkill(int school) { std::map schoolSkillMap; // maps spell school to skill id - schoolSkillMap[0] = 11; // alteration - schoolSkillMap[1] = 13; // conjuration - schoolSkillMap[3] = 12; // illusion - schoolSkillMap[2] = 10; // destruction - schoolSkillMap[4] = 14; // mysticism - schoolSkillMap[5] = 15; // restoration + schoolSkillMap[0] = ESM::Skill::Alteration; + schoolSkillMap[1] = ESM::Skill::Conjuration; + schoolSkillMap[3] = ESM::Skill::Illusion; + schoolSkillMap[2] = ESM::Skill::Destruction; + schoolSkillMap[4] = ESM::Skill::Mysticism; + schoolSkillMap[5] = ESM::Skill::Restoration; assert(schoolSkillMap.find(school) != schoolSkillMap.end()); return schoolSkillMap[school]; } diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index dda9797eff..d579c97933 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -226,11 +226,10 @@ namespace MWRender mCamera->setPosition(0.f, 0.f, offset); } - void Camera::setSneakOffset() + void Camera::setSneakOffset(float offset) { - // TODO: iFirstPersonSneakDelta if(mAnimation) - mAnimation->addFirstPersonOffset(Ogre::Vector3(0.f, 0.f, -9.8f)); + mAnimation->addFirstPersonOffset(Ogre::Vector3(0.f, 0.f, -offset)); } float Camera::getYaw() diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index d31d9e56c0..808f817cf5 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -87,7 +87,7 @@ namespace MWRender /// As animation is tied to the camera, this needs /// to be set each frame after the animation is /// applied. - void setSneakOffset(); + void setSneakOffset(float offset); bool isFirstPerson() const { return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 11d06704e2..0c5e053c9e 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -351,8 +351,10 @@ void RenderingManager::update (float duration, bool paused) bool isInAir = !world->isOnGround(player); bool isSwimming = world->isSwimming(player); + static const int i1stPersonSneakDelta = MWBase::Environment::get().getWorld()->getStore().get() + .find("i1stPersonSneakDelta")->getInt(); if(isSneaking && !(isSwimming || isInAir)) - mCamera->setSneakOffset(); + mCamera->setSneakOffset(i1stPersonSneakDelta); mOcclusionQuery->update(duration); From d9d6f376193700f51688251f354887cf07641222 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 10 Jan 2014 22:44:40 +0100 Subject: [PATCH 077/168] Use iVoiceHitOdds --- apps/openmw/mwclass/npc.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 01fe61472a..1c5c302d80 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -615,7 +615,13 @@ namespace MWClass // 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying // something, alert the character controller, scripts, etc. - MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); + const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + int chance = store.get().find("iVoiceHitOdds")->getInt(); + int roll = std::rand()/ (static_cast (RAND_MAX) + 1) * 100; // [0, 99] + if (roll < chance) + { + MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); + } getCreatureStats(ptr).setAttacked(true);//used in CharacterController if(object.isEmpty()) From 621e52f09d47758cb41b3e081e0d2b4069e3b53b Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 10 Jan 2014 22:48:42 +0100 Subject: [PATCH 078/168] Play "attack" voiced dialogue entries randomly based on iVoiceAttackOdds. --- apps/openmw/mwmechanics/aicombat.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 32b0063b63..34b7217557 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -7,6 +7,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/dialoguemanager.hpp" #include "creaturestats.hpp" #include "npcstats.hpp" @@ -118,6 +119,17 @@ namespace MWMechanics } if( mTimer > 1) { + if (actor.getClass().isNpc()) + { + const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + int chance = store.get().find("iVoiceAttackOdds")->getInt(); + int roll = std::rand()/ (static_cast (RAND_MAX) + 1) * 100; // [0, 99] + if (roll < chance) + { + MWBase::Environment::get().getDialogueManager()->say(actor, "attack"); + } + } + MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true); mTimer = 0; } From e9f63270d95b85dc2aca449e64f6ba71a0eb9628 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 10 Jan 2014 22:51:42 +0100 Subject: [PATCH 079/168] Speed fix for "on target" spells --- apps/openmw/mwworld/worldimp.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f61938f92b..738c71a7df 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2174,14 +2174,13 @@ namespace MWWorld Ogre::Vector3 rot(ptr.getRefData().getPosition().rot); - // TODO: Why -rot.z, but not -rot.x? + // TODO: Why -rot.z, but not -rot.x? (note: same issue in MovementSolver::move) Ogre::Quaternion orient = Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z); orient = orient * Ogre::Quaternion(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X); - // This is just a guess, probably wrong - static float fProjectileMinSpeed = getStore().get().find("fProjectileMinSpeed")->getFloat(); - static float fProjectileMaxSpeed = getStore().get().find("fProjectileMaxSpeed")->getFloat(); - float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * it->second.mSpeed; + + static float fTargetSpellMaxSpeed = getStore().get().find("fTargetSpellMaxSpeed")->getFloat(); + float speed = fTargetSpellMaxSpeed * it->second.mSpeed; Ogre::Vector3 direction = orient.yAxis(); direction.normalise(); From d01f89b153921ecc8729ccf9777fbb8c3e785fd7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 00:24:21 +0100 Subject: [PATCH 080/168] Rewrite some awful code --- apps/openmw/mwbase/windowmanager.hpp | 3 --- apps/openmw/mwgui/container.cpp | 11 +++++++++ apps/openmw/mwgui/container.hpp | 1 + apps/openmw/mwgui/messagebox.cpp | 20 +++++++--------- apps/openmw/mwgui/messagebox.hpp | 3 +-- apps/openmw/mwgui/windowmanagerimp.cpp | 11 --------- apps/openmw/mwgui/windowmanagerimp.hpp | 2 -- apps/openmw/mwinput/inputmanagerimp.cpp | 31 +------------------------ apps/openmw/mwinput/inputmanagerimp.hpp | 1 - 9 files changed, 22 insertions(+), 61 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 6c85be5fd2..c39de44006 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -227,9 +227,6 @@ namespace MWBase virtual void messageBox (const std::string& message, const std::vector& buttons = std::vector(), bool showInDialogueModeOnly = false) = 0; virtual void staticMessageBox(const std::string& message) = 0; virtual void removeStaticMessageBox() = 0; - - virtual void enterPressed () = 0; - virtual void activateKeyPressed () = 0; virtual int readPressedButton() = 0; ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index bccc7120fb..d22842b575 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -139,6 +139,7 @@ namespace MWGui mDisposeCorpseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked); mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked); + mCloseButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &ContainerWindow::onKeyPressed); mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked); setCoord(200,0,600,300); @@ -234,11 +235,21 @@ namespace MWGui mItemView->setModel (mSortModel); + MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton); + // Careful here. setTitle may cause size updates, causing itemview redraw, so make sure to do it last // or we end up using a possibly invalid model. setTitle(MWWorld::Class::get(container).getName(container)); } + void ContainerWindow::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char) + { + if (_key == MyGUI::KeyCode::Space) + onCloseButtonClicked(mCloseButton); + if (_key == MyGUI::KeyCode::Return || _key == MyGUI::KeyCode::NumpadEnter) + onTakeAllButtonClicked(mTakeButton); + } + void ContainerWindow::close() { WindowBase::close(); diff --git a/apps/openmw/mwgui/container.hpp b/apps/openmw/mwgui/container.hpp index f934d8828a..ce4707af6b 100644 --- a/apps/openmw/mwgui/container.hpp +++ b/apps/openmw/mwgui/container.hpp @@ -75,6 +75,7 @@ namespace MWGui void onCloseButtonClicked(MyGUI::Widget* _sender); void onTakeAllButtonClicked(MyGUI::Widget* _sender); void onDisposeCorpseButtonClicked(MyGUI::Widget* sender); + void onKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char); /// @return is taking the item allowed? bool onTakeItem(const ItemStack& item, int count); diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index b0abaef142..ae01f42931 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -127,12 +127,6 @@ namespace MWGui mMessageBoxSpeed = speed; } - void MessageBoxManager::okayPressed () - { - if(mInterMessageBoxe != NULL) - mInterMessageBoxe->okayPressed(); - } - int MessageBoxManager::readPressedButton () { int pressed = mLastButtonPressed; @@ -333,23 +327,25 @@ namespace MWGui } } - } - - void InteractiveMessageBox::okayPressed() - { + // Set key focus to "Ok" button std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}")); std::vector::const_iterator button; for(button = mButtons.begin(); button != mButtons.end(); ++button) { if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok) { - buttonActivated(*button); - MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f); + MyGUI::InputManager::getInstance().setKeyFocusWidget(*button); + (*button)->eventKeyButtonPressed += MyGUI::newDelegate(this, &InteractiveMessageBox::onKeyPressed); break; } } + } + void InteractiveMessageBox::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char) + { + if (_key == MyGUI::KeyCode::Return || _key == MyGUI::KeyCode::NumpadEnter || _key == MyGUI::KeyCode::Space) + buttonActivated(_sender); } void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed) diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index e82a51642d..caa37008ca 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -33,7 +33,6 @@ namespace MWGui bool removeMessageBox (MessageBox *msgbox); void setMessageBoxSpeed (int speed); - void okayPressed(); int readPressedButton (); typedef MyGUI::delegates::CMultiDelegate1 EventHandle_Int; @@ -74,7 +73,6 @@ namespace MWGui { public: InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector& buttons); - void okayPressed (); void mousePressed (MyGUI::Widget* _widget); int readPressedButton (); @@ -82,6 +80,7 @@ namespace MWGui private: void buttonActivated (MyGUI::Widget* _widget); + void onKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char); MessageBoxManager& mMessageBoxManager; MyGUI::EditBox* mMessageWidget; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index e4297f8fcd..cda146e8c0 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -677,17 +677,6 @@ namespace MWGui mMessageBoxManager->removeStaticMessageBox(); } - void WindowManager::enterPressed () - { - mMessageBoxManager->okayPressed(); - } - - void WindowManager::activateKeyPressed () - { - mMessageBoxManager->okayPressed(); - mCountDialog->cancel(); - } - int WindowManager::readPressedButton () { return mMessageBoxManager->readPressedButton(); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index a3b135ad4e..9838a667f9 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -222,8 +222,6 @@ namespace MWGui virtual void messageBox (const std::string& message, const std::vector& buttons = std::vector(), bool showInDialogueModeOnly = false); virtual void staticMessageBox(const std::string& message); virtual void removeStaticMessageBox(); - virtual void enterPressed (); - virtual void activateKeyPressed (); virtual int readPressedButton (); ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) virtual void onFrame (float frameDuration); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index c2efa0c331..f0feba89f8 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -195,14 +195,7 @@ namespace MWInput case A_Activate: resetIdleTime(); - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Container) - toggleContainer (); - else - MWBase::Environment::get().getWindowManager()->activateKeyPressed(); - } - else + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) activate(); break; case A_Journal: @@ -511,13 +504,6 @@ namespace MWInput mInputBinder->keyPressed (arg); - if((arg.keysym.sym == SDLK_RETURN || arg.keysym.sym == SDLK_KP_ENTER) - && MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - // Pressing enter when a messagebox is prompting for "ok" will activate the ok button - MWBase::Environment::get().getWindowManager()->enterPressed(); - } - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); if (kc != OIS::KC_UNASSIGNED) @@ -730,21 +716,6 @@ namespace MWInput // .. but don't touch any other mode, except container. } - void InputManager::toggleContainer() - { - if (MyGUI::InputManager::getInstance ().isModalAny()) - return; - - if(MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Container) - MWBase::Environment::get().getWindowManager()->popGuiMode(); - else - MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container); - } - - } - void InputManager::toggleConsole() { if (MyGUI::InputManager::getInstance ().isModalAny()) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 4eaee9b690..d41b4c3f3b 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -173,7 +173,6 @@ namespace MWInput void toggleSpell(); void toggleWeapon(); void toggleInventory(); - void toggleContainer(); void toggleConsole(); void screenshot(); void toggleJournal(); From c64dc2c8312d1177fdeb38b11adea7c776e40b9e Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 00:51:03 +0100 Subject: [PATCH 081/168] Terrain specular mapping: use a "_diffusespec" postfix to indicate specular information is present in the alpha channel. Use alpha directly instead of 1-alpha. --- components/terrain/material.cpp | 3 +++ components/terrain/storage.cpp | 9 +++++++++ components/terrain/storage.hpp | 1 + files/materials/terrain.shader | 26 +++++++++++++------------- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/components/terrain/material.cpp b/components/terrain/material.cpp index 5dcdb7fed8..be468866ba 100644 --- a/components/terrain/material.cpp +++ b/components/terrain/material.cpp @@ -281,6 +281,7 @@ namespace Terrain // normal map (optional) bool useNormalMap = mNormalMapping && !mLayerList[layerOffset+i].mNormalMap.empty() && !renderCompositeMap; bool useParallax = useNormalMap && mParallaxMapping && layer.mParallax; + bool useSpecular = layer.mSpecular; if (useNormalMap) { anyNormalMaps = true; @@ -292,6 +293,8 @@ namespace Terrain sh::makeProperty (new sh::BooleanValue(useNormalMap))); p->mShaderProperties.setProperty ("use_parallax_" + Ogre::StringConverter::toString(i), sh::makeProperty (new sh::BooleanValue(useParallax))); + p->mShaderProperties.setProperty ("use_specular_" + Ogre::StringConverter::toString(i), + sh::makeProperty (new sh::BooleanValue(useSpecular))); boost::hash_combine(normalMaps, useNormalMap); boost::hash_combine(normalMaps, useNormalMap && layer.mParallax); diff --git a/components/terrain/storage.cpp b/components/terrain/storage.cpp index 9d6b44de8d..398ebac014 100644 --- a/components/terrain/storage.cpp +++ b/components/terrain/storage.cpp @@ -475,6 +475,7 @@ namespace Terrain LayerInfo info; info.mParallax = false; + info.mSpecular = false; info.mDiffuseMap = "textures\\" + texture; std::string texture_ = texture; boost::replace_last(texture_, ".", "_nh."); @@ -491,6 +492,14 @@ namespace Terrain info.mNormalMap = "textures\\" + texture_; } + texture_ = texture; + boost::replace_last(texture_, ".", "_diffusespec."); + if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup("textures\\" + texture_)) + { + info.mDiffuseMap = "textures\\" + texture_; + info.mSpecular = true; + } + mLayerInfoMap[texture] = info; return info; diff --git a/components/terrain/storage.hpp b/components/terrain/storage.hpp index 68fae01afa..18d05b100c 100644 --- a/components/terrain/storage.hpp +++ b/components/terrain/storage.hpp @@ -16,6 +16,7 @@ namespace Terrain std::string mDiffuseMap; std::string mNormalMap; bool mParallax; // Height info in normal map alpha channel? + bool mSpecular; // Specular info in diffuse map alpha channel? }; /// We keep storage of terrain data abstract here since we need different implementations for game and editor diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 86eef36ffa..1436de0c35 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -337,6 +337,7 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5; float2 layerUV = float2(UV.x, 1.f-UV.y) * 16; // Reverse Y, required to get proper tangents float2 thisLayerUV; float4 normalTex; + float4 diffuseTex; float3 eyeDir = normalize(cameraPos.xyz - worldPos); #if PARALLAX @@ -358,19 +359,18 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5; thisLayerUV += TSeyeDir.xy * ( normalTex.a * PARALLAX_SCALE + PARALLAX_BIAS ); #endif -#if IS_FIRST_PASS - #if @shIterator == 0 - // first layer of first pass is the base layer and doesn't need a blend map - albedo = shSample(diffuseMap0, layerUV); - #else - albedo = shLerp(albedo, shSample(diffuseMap@shIterator, thisLayerUV), blendValues@shPropertyString(blendmap_component_@shIterator)); - #endif + diffuseTex = shSample(diffuseMap@shIterator, layerUV); +#if !@shPropertyBool(use_specular_@shIterator) + diffuseTex.a = 0; +#endif + +#if @shIterator == 0 +albedo = diffuseTex; #else - #if @shIterator == 0 - albedo = shSample(diffuseMap@shIterator, layerUV); - #else - albedo = shLerp(albedo, shSample(diffuseMap@shIterator, thisLayerUV), blendValues@shPropertyString(blendmap_component_@shIterator)); - #endif +albedo = shLerp(albedo, diffuseTex, blendValues@shPropertyString(blendmap_component_@shIterator)); +#endif + +#if !IS_FIRST_PASS previousAlpha *= 1.f-blendValues@shPropertyString(blendmap_component_@shIterator); #endif @@ -448,7 +448,7 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5; float3 halfVec = normalize (light0Dir + eyeDir); float3 specular = pow(max(dot(normal, halfVec), 0), 32) * lightSpec0; - shOutputColour(0).xyz += specular * (1.f-albedo.a) * shadow; + shOutputColour(0).xyz += specular * (albedo.a) * shadow; #endif #if FOG From 727aa30347a345e7a61bebffa3e05d94586622ea Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 02:06:54 +0100 Subject: [PATCH 082/168] Dead actors are unaware of everything --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 002cd561d6..2ce196fdd7 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -857,6 +857,9 @@ namespace MWMechanics bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer) { + if (observer.getClass().getCreatureStats(observer).isDead()) + return false; + const MWWorld::Store& store = MWBase::Environment::get().getWorld()->getStore().get(); CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); From d4a98ffc270e6e19504c4da1615bf26d4b352ef6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 02:27:44 +0100 Subject: [PATCH 083/168] Increase fight rating when being the victim of a crime --- .../mwmechanics/mechanicsmanagerimp.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 2ce196fdd7..57b8767239 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -840,6 +840,25 @@ namespace MWMechanics ptr.getClass().getNpcStats(ptr).setBounty(ptr.getClass().getNpcStats(ptr).getBounty() + arg); + if (!victim.isEmpty()) + { + int fight = 0; + // Increase in fight rating for each type of crime + if (type == OT_Trespassing || type == OT_SleepingInOwnedBed) + fight = store.find("iFightTrespass")->getFloat(); + else if (type == OT_Pickpocket) + fight = store.find("iFightPickpocket")->getInt(); + else if (type == OT_Assault) + fight = store.find("iFightAttack")->getInt(); + else if (type == OT_Murder) + fight = store.find("iFightKilling")->getInt(); + else if (type == OT_Theft) + fight = store.find("fFightStealing")->getFloat(); + // Not sure if this should be permanent? + fight = victim.getClass().getCreatureStats(victim).getAiSetting(CreatureStats::AI_Fight).getBase() + fight; + victim.getClass().getCreatureStats(victim).setAiSetting(CreatureStats::AI_Fight, fight); + } + // If committing a crime against a faction member, expell from the faction if (!victim.isEmpty() && victim.getClass().isNpc()) { From 12944f2459a13296b71ee4c9ea2bafac2d549256 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 03:07:35 +0100 Subject: [PATCH 084/168] Fix an auto equipping bug that allowed twohanded weapon and shield at the same time --- apps/openmw/mwworld/inventorystore.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index b11c22c72d..3e81da2122 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -165,7 +165,6 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) { const MWMechanics::NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor); - MWWorld::InventoryStore& invStore = MWWorld::Class::get(actor).getInventoryStore(actor); TSlots slots_; initSlots (slots_); @@ -266,10 +265,10 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) case 0: continue; case 2: - invStore.unequipSlot(MWWorld::InventoryStore::Slot_CarriedLeft, actor); + slots_[MWWorld::InventoryStore::Slot_CarriedLeft] = end(); break; case 3: - invStore.unequipSlot(MWWorld::InventoryStore::Slot_CarriedRight, actor); + // Prefer keeping twohanded weapon break; } From 909494ff3524a93a450d63656fe450dd863cdda5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 03:08:16 +0100 Subject: [PATCH 085/168] Implement Assault crimes. In other words, NPCs now fight back! --- apps/openmw/mwclass/npc.cpp | 4 ++++ apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 11 ++++++----- apps/openmw/mwmechanics/spellcasting.cpp | 7 +++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 1c5c302d80..68b7d41f5c 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -587,6 +587,10 @@ namespace MWClass // NOTE: 'object' and/or 'attacker' may be empty. + // Attacking peaceful NPCs is a crime + if (ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) + MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault); + if(!successful) { // TODO: Handle HitAttemptOnMe script function diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 57b8767239..901b6e4144 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -786,7 +786,8 @@ namespace MWMechanics bool MechanicsManager::commitCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) { - // TODO: expell from faction + if (ptr.getRefData().getHandle() != "player") + return false; bool reported=false; for (Actors::PtrControllerMap::const_iterator it = mActors.begin(); it != mActors.end(); ++it) @@ -803,10 +804,7 @@ namespace MWMechanics // Actor has witnessed a crime. Will he report it? // (not sure, is > 0 correct?) - if (it->first.getClass().getCreatureStats(it->first).getAiSetting(CreatureStats::AI_Alarm).getModified() > 0 - // This is a bit inconsistent, but AFAIK assaulted NPCs can not report if they are alone - && (type != OT_Assault || it->first != victim) - ) + if (it->first.getClass().getCreatureStats(it->first).getAiSetting(CreatureStats::AI_Alarm).getModified() > 0) { // TODO: stats.setAlarmed(true) on NPCs within earshot // fAlarmRadius ? @@ -836,6 +834,9 @@ namespace MWMechanics else if (type == OT_Theft) arg *= store.find("fCrimeStealing")->getFloat(); + // TODO: In some cases (type == Assault), if no NPCs are within earshot, the report will have no effect. + // however other crime types seem to be always produce a bounty. + MWBase::Environment::get().getWindowManager()->messageBox("#{sCrimeMessage}"); ptr.getClass().getNpcStats(ptr).setBounty(ptr.getClass().getNpcStats(ptr).getBounty() + arg); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 8c4c4d292e..b8c36d2138 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -57,6 +57,7 @@ namespace MWMechanics ESM::EffectList reflectedEffects; std::vector appliedLastingEffects; bool firstAppliedEffect = true; + bool anyHarmfulEffect = false; for (std::vector::const_iterator effectIt (effects.mList.begin()); effectIt!=effects.mList.end(); ++effectIt) @@ -77,6 +78,8 @@ namespace MWMechanics float magnitudeMult = 1; if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful && target.getClass().isActor()) { + anyHarmfulEffect = true; + // If player is attempting to cast a harmful spell, show the target's HP bar if (caster.getRefData().getHandle() == "player" && target != caster) MWBase::Environment::get().getWindowManager()->setEnemy(target); @@ -218,6 +221,10 @@ namespace MWMechanics if (appliedLastingEffects.size()) target.getClass().getCreatureStats(target).getActiveSpells().addSpell(mId, mStack, appliedLastingEffects, mSourceName, caster.getRefData().getHandle()); + + if (anyHarmfulEffect && target.getClass().isActor() + && target.getClass().getCreatureStats(target).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) + MWBase::Environment::get().getMechanicsManager()->commitCrime(caster, target, MWBase::MechanicsManager::OT_Assault); } void CastSpell::applyInstantEffect(const MWWorld::Ptr &target, const MWWorld::Ptr &caster, MWMechanics::EffectKey effect, float magnitude) From bf6d302fbadbfdf3399e12a2fbfaca6d06406bec Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 03:29:41 +0100 Subject: [PATCH 086/168] Confiscate stolen items when caught --- apps/openmw/mwbase/world.hpp | 3 ++ apps/openmw/mwscript/miscextensions.cpp | 5 ++-- apps/openmw/mwworld/cells.cpp | 12 ++++++++ apps/openmw/mwworld/cells.hpp | 6 ++++ apps/openmw/mwworld/worldimp.cpp | 40 +++++++++++++++++++++++++ apps/openmw/mwworld/worldimp.hpp | 3 ++ 6 files changed, 66 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 43e526ecba..10e25b376b 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -451,6 +451,9 @@ namespace MWBase /// Update the value of some globals according to the world state, which may be used by dialogue entries. /// This should be called when initiating a dialogue. virtual void updateDialogueGlobals() = 0; + + /// Moves all stolen items from \a ptr to the closest evidence chest. + virtual void confiscateStolenItems(const MWWorld::Ptr& ptr) = 0; }; } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a403d76edf..f69f2e7cb0 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -769,8 +769,8 @@ namespace MWScript MWWorld::Ptr player = world->getPlayerPtr(); world->teleportToClosestMarker(player, "prisonmarker"); player.getClass().getNpcStats(player).setBounty(0); + world->confiscateStolenItems(player); // TODO: pass time, change skills, show messagebox - // TODO: move stolen items to closest evidence chest // iDaysinPrisonMod } }; @@ -782,8 +782,7 @@ namespace MWScript { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); player.getClass().getNpcStats(player).setBounty(0); - - // TODO: move stolen items to closest evidence chest + MWBase::Environment::get().getWorld()->confiscateStolenItems(player); } }; diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 621ff3b313..575e10f049 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -271,3 +271,15 @@ void MWWorld::Cells::getExteriorPtrs(const std::string &name, std::vector &out) +{ + for (std::map::iterator iter = mInteriors.begin(); + iter!=mInteriors.end(); ++iter) + { + Ptr ptr = getPtrAndCache (name, iter->second); + if (!ptr.isEmpty()) + out.push_back(ptr); + } + +} diff --git a/apps/openmw/mwworld/cells.hpp b/apps/openmw/mwworld/cells.hpp index 31de2f60e8..afa7c03f28 100644 --- a/apps/openmw/mwworld/cells.hpp +++ b/apps/openmw/mwworld/cells.hpp @@ -56,6 +56,12 @@ namespace MWWorld /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. /// @note name must be lower case void getExteriorPtrs (const std::string& name, std::vector& out); + + /// Get all Ptrs referencing \a name in interior cells + /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. + /// @note name must be lower case + void getInteriorPtrs (const std::string& name, std::vector& out); + }; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 738c71a7df..c5315afe66 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2446,4 +2446,44 @@ namespace MWWorld mGlobalVariables->setInt("crimegoldturnin", turnIn); mGlobalVariables->setInt("pchasturnin", (turnIn <= playerGold) ? 1 : 0); } + + void World::confiscateStolenItems(const Ptr &ptr) + { + Ogre::Vector3 playerPos; + if (!findInteriorPositionInWorldSpace(ptr.getCell(), playerPos)) + playerPos = mPlayer->getLastKnownExteriorPosition(); + + MWWorld::Ptr closestChest; + float closestDistance = FLT_MAX; + + std::vector chests; + mCells.getInteriorPtrs("stolen_goods", chests); + + Ogre::Vector3 chestPos; + for (std::vector::iterator it = chests.begin(); it != chests.end(); ++it) + { + if (!findInteriorPositionInWorldSpace(it->getCell(), chestPos)) + continue; + + float distance = playerPos.squaredDistance(chestPos); + if (distance < closestDistance) + { + closestDistance = distance; + closestChest = *it; + } + } + + if (!closestChest.isEmpty()) + { + ContainerStore& store = ptr.getClass().getContainerStore(ptr); + for (ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + { + if (!it->getCellRef().mOwner.empty() && it->getCellRef().mOwner != "player") + { + closestChest.getClass().getContainerStore(closestChest).add(*it, it->getRefData().getCount(), closestChest); + store.remove(*it, it->getRefData().getCount(), ptr); + } + } + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index cc087a89f1..8c091de50f 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -536,6 +536,9 @@ namespace MWWorld /// Update the value of some globals according to the world state, which may be used by dialogue entries. /// This should be called when initiating a dialogue. virtual void updateDialogueGlobals(); + + /// Moves all stolen items from \a ptr to the closest evidence chest. + virtual void confiscateStolenItems(const MWWorld::Ptr& ptr); }; } From 9127839cc1b9e2c71aede268b1e2c0a1220a019a Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 03:33:17 +0100 Subject: [PATCH 087/168] Add a searchPtr method as required for getting an owner, which may already be dead and disposed of. --- apps/openmw/mwbase/world.hpp | 4 ++++ apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 15 ++++++++++----- apps/openmw/mwworld/worldimp.hpp | 4 ++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 10e25b376b..2fb5f02eb6 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -157,6 +157,10 @@ namespace MWBase ///< Return a pointer to a liveCellRef with the given name. /// \param activeOnly do non search inactive cells. + virtual MWWorld::Ptr searchPtr (const std::string& name, bool activeOnly) = 0; + ///< Return a pointer to a liveCellRef with the given name. + /// \param activeOnly do non search inactive cells. + virtual MWWorld::Ptr getPtrViaHandle (const std::string& handle) = 0; ///< Return a pointer to a liveCellRef with the given Ogre handle. diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 901b6e4144..76ba2ff16c 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -34,7 +34,7 @@ namespace } if (!item.getCellRef().mOwner.empty()) - victim = MWBase::Environment::get().getWorld()->getPtr(item.getCellRef().mOwner, true); + victim = MWBase::Environment::get().getWorld()->searchPtr(item.getCellRef().mOwner, true); return (!isOwned && !isFactionOwned); } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c5315afe66..ca85d7a7f4 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -485,8 +485,9 @@ namespace MWWorld mLocalScripts.remove (ref); } - Ptr World::getPtr (const std::string& name, bool activeOnly) + Ptr World::searchPtr (const std::string& name, bool activeOnly) { + Ptr ret; // the player is always in an active cell. if (name=="player") { @@ -514,12 +515,16 @@ namespace MWWorld if (!activeOnly) { - Ptr ptr = mCells.getPtr (lowerCaseName); - - if (!ptr.isEmpty()) - return ptr; + ret = mCells.getPtr (lowerCaseName); } + return ret; + } + Ptr World::getPtr (const std::string& name, bool activeOnly) + { + Ptr ret = searchPtr(name, activeOnly); + if (!ret.isEmpty()) + return ret; throw std::runtime_error ("unknown ID: " + name); } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 8c091de50f..d5ccd7625d 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -232,6 +232,10 @@ namespace MWWorld ///< Return a pointer to a liveCellRef with the given name. /// \param activeOnly do non search inactive cells. + virtual Ptr searchPtr (const std::string& name, bool activeOnly); + ///< Return a pointer to a liveCellRef with the given name. + /// \param activeOnly do non search inactive cells. + virtual Ptr getPtrViaHandle (const std::string& handle); ///< Return a pointer to a liveCellRef with the given Ogre handle. From 9ddee8fd8c6b00e7ff5f4904118056b02bdf30d2 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 04:03:13 +0100 Subject: [PATCH 088/168] Autocalculate NPC reputation as according to research wiki --- apps/openmw/mwclass/npc.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 68b7d41f5c..12ed2dd09b 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -307,6 +307,17 @@ namespace MWClass autoCalculateSkills(ref->mBase, data->mNpcStats); } + if (data->mNpcStats.getFactionRanks().size()) + { + static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get() + .find("iAutoRepFacMod")->getInt(); + static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get() + .find("iAutoRepLevMod")->getInt(); + int rank = data->mNpcStats.getFactionRanks().begin()->second; + + data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1)); + } + data->mNpcStats.getAiSequence().fill(ref->mBase->mAiPackage); data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Hello, ref->mBase->mAiData.mHello); From ce6aab89cf9d7dde54f994aba21c7fda228ff269 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 04:58:30 +0100 Subject: [PATCH 089/168] Fix a possible permutation issue --- components/terrain/material.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/components/terrain/material.cpp b/components/terrain/material.cpp index be468866ba..8e78d22166 100644 --- a/components/terrain/material.cpp +++ b/components/terrain/material.cpp @@ -297,6 +297,7 @@ namespace Terrain sh::makeProperty (new sh::BooleanValue(useSpecular))); boost::hash_combine(normalMaps, useNormalMap); boost::hash_combine(normalMaps, useNormalMap && layer.mParallax); + boost::hash_combine(normalMaps, useSpecular); if (i+layerOffset > 0) { From 3896c88403c71cfef013fa9cc713fe5a8a910910 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 05:58:05 +0100 Subject: [PATCH 090/168] Use VFX_DefaultCast / VFX_DefaultHit if the magic effect does not specify any --- apps/openmw/mwmechanics/actors.cpp | 2 +- apps/openmw/mwmechanics/character.cpp | 7 ++++++- apps/openmw/mwmechanics/spellcasting.cpp | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index afc94255bb..468a218927 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -525,7 +525,7 @@ namespace MWMechanics ref.getPtr().getCellRef().mPos = ipos; // TODO: Add AI to follow player and fight for him - + // TODO: VFX_SummonStart, VFX_SummonEnd creatureStats.mSummonedCreatures.insert(std::make_pair(it->first, MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),*store,ipos).getRefData().getHandle())); } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 99067a6b72..fed3f485f2 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -592,7 +592,12 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun const ESM::MagicEffect *effect; effect = store.get().find(effectentry.mEffectID); - const ESM::Static* castStatic = store.get().find (effect->mCasting); + const ESM::Static* castStatic; + if (!effect->mCasting.empty()) + castStatic = store.get().find (effect->mCasting); + else + castStatic = store.get().find ("VFX_DefaultCast"); + mAnimation->addEffect("meshes\\" + castStatic->mModel, effect->mIndex); castStatic = MWBase::Environment::get().getWorld()->getStore().get().find ("VFX_Hands"); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index b8c36d2138..850c4dcf51 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -200,15 +200,17 @@ namespace MWMechanics } // Add VFX + const ESM::Static* castStatic; if (!magicEffect->mHit.empty()) - { - const ESM::Static* castStatic = MWBase::Environment::get().getWorld()->getStore().get().find (magicEffect->mHit); - bool loop = magicEffect->mData.mFlags & ESM::MagicEffect::ContinuousVfx; - // Note: in case of non actor, a free effect should be fine as well - MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(target); - if (anim) - anim->addEffect("meshes\\" + castStatic->mModel, magicEffect->mIndex, loop, ""); - } + castStatic = MWBase::Environment::get().getWorld()->getStore().get().find (magicEffect->mHit); + else + castStatic = MWBase::Environment::get().getWorld()->getStore().get().find ("VFX_DefaultHit"); + + bool loop = magicEffect->mData.mFlags & ESM::MagicEffect::ContinuousVfx; + // Note: in case of non actor, a free effect should be fine as well + MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(target); + if (anim) + anim->addEffect("meshes\\" + castStatic->mModel, magicEffect->mIndex, loop, ""); } // TODO: For Area effects, launch a growing particle effect that applies the effect to more actors as it hits them. Best managed in World. From a2ba0dde31036bb45646488a6d4bc6348c65a443 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 06:47:58 +0100 Subject: [PATCH 091/168] Implemented GoToJail --- apps/openmw/mwbase/world.hpp | 2 + apps/openmw/mwscript/miscextensions.cpp | 7 +-- apps/openmw/mwworld/worldimp.cpp | 79 ++++++++++++++++++++++++- apps/openmw/mwworld/worldimp.hpp | 3 + 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 2fb5f02eb6..fe40fab24f 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -458,6 +458,8 @@ namespace MWBase /// Moves all stolen items from \a ptr to the closest evidence chest. virtual void confiscateStolenItems(const MWWorld::Ptr& ptr) = 0; + + virtual void goToJail () = 0; }; } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index f69f2e7cb0..bb3600a272 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -766,12 +766,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWBase::World* world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayerPtr(); - world->teleportToClosestMarker(player, "prisonmarker"); - player.getClass().getNpcStats(player).setBounty(0); - world->confiscateStolenItems(player); - // TODO: pass time, change skills, show messagebox - // iDaysinPrisonMod + world->goToJail(); } }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index ca85d7a7f4..620058c65f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -216,7 +216,7 @@ namespace MWWorld mSky (true), mCells (mStore, mEsm), mActivationDistanceOverride (mActivationDistanceOverride), mFallback(fallbackMap), mPlayIntro(0), mTeleportEnabled(true), mLevitationEnabled(false), - mFacedDistance(FLT_MAX), mGodMode(false) + mFacedDistance(FLT_MAX), mGodMode(false), mGoToJail(false) { mPhysics = new PhysicsSystem(renderer); mPhysEngine = mPhysics->getEngine(); @@ -259,6 +259,9 @@ namespace MWWorld void World::startNewGame() { + mGoToJail = false; + mLevitationEnabled = true; + mTeleportEnabled = true; mWorldScene->changeToVoid(); mStore.clearDynamic(); @@ -1272,6 +1275,9 @@ namespace MWWorld mRendering->playVideo(mFallback.getFallbackString("Movies_New_Game"), true); } + if (mGoToJail && !paused) + goToJail(); + updateWeather(duration); mWorldScene->update (duration, paused); @@ -2491,4 +2497,75 @@ namespace MWWorld } } } + + void World::goToJail() + { + if (!mGoToJail) + { + // Save for next update, since the player should be able to read the dialog text first + mGoToJail = true; + return; + } + else + { + mGoToJail = false; + + MWWorld::Ptr player = getPlayerPtr(); + teleportToClosestMarker(player, "prisonmarker"); + int bounty = player.getClass().getNpcStats(player).getBounty(); + player.getClass().getNpcStats(player).setBounty(0); + confiscateStolenItems(player); + + int iDaysinPrisonMod = getStore().get().find("iDaysinPrisonMod")->getInt(); + int days = std::max(1, bounty / iDaysinPrisonMod); + + advanceTime(days * 24); + + std::set skills; + for (int day=0; day (RAND_MAX) + 1) * ESM::Skill::Length; + skills.insert(skill); + + MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill); + if (skill == ESM::Skill::Security || skill == ESM::Skill::Sneak) + value.setBase(std::min(100, value.getBase()+1)); + else + value.setBase(value.getBase()-1); + } + + const Store& gmst = getStore().get(); + + std::string message; + if (days == 1) + message = gmst.find("sNotifyMessage42")->getString(); + else + message = gmst.find("sNotifyMessage43")->getString(); + + std::stringstream dayStr; + dayStr << days; + if (message.find("%d") != std::string::npos) + message.replace(message.find("%d"), 2, dayStr.str()); + + for (std::set::iterator it = skills.begin(); it != skills.end(); ++it) + { + std::string skillName = gmst.find(ESM::Skill::sSkillNameIds[*it])->getString(); + std::stringstream skillValue; + skillValue << player.getClass().getNpcStats(player).getSkill(*it).getBase(); + std::string skillMsg = gmst.find("sNotifyMessage44")->getString(); + if (*it == ESM::Skill::Sneak || *it == ESM::Skill::Security) + skillMsg = gmst.find("sNotifyMessage39")->getString(); + + if (skillMsg.find("%s") != std::string::npos) + skillMsg.replace(skillMsg.find("%s"), 2, skillName); + if (skillMsg.find("%d") != std::string::npos) + skillMsg.replace(skillMsg.find("%d"), 2, skillValue.str()); + message += "\n" + skillMsg; + } + + std::vector buttons; + buttons.push_back("#{sOk}"); + MWBase::Environment::get().getWindowManager()->messageBox(message, buttons); + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index d5ccd7625d..634cc8d6b6 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -151,6 +151,7 @@ namespace MWWorld bool mTeleportEnabled; bool mLevitationEnabled; + bool mGoToJail; /// Called when \a object is moved to an inactive cell void objectLeftActiveCell (MWWorld::Ptr object, MWWorld::Ptr movedPtr); @@ -543,6 +544,8 @@ namespace MWWorld /// Moves all stolen items from \a ptr to the closest evidence chest. virtual void confiscateStolenItems(const MWWorld::Ptr& ptr); + + virtual void goToJail (); }; } From 3db299f1b2c8074d9febbe257066f1c610bf617d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 21:04:31 +0100 Subject: [PATCH 092/168] Fix fall damage crash --- apps/openmw/mwclass/npc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 12ed2dd09b..41c6de40cc 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -599,7 +599,7 @@ namespace MWClass // NOTE: 'object' and/or 'attacker' may be empty. // Attacking peaceful NPCs is a crime - if (ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) + if (!attacker.isEmpty() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault); if(!successful) From 224f288359bfc6a523fdcfc4d338ecf47574096c Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 21:30:09 +0100 Subject: [PATCH 093/168] Don't attempt to change disposition for creatures --- apps/openmw/mwgui/tradewindow.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 1cd4c1c7c0..14024dec6b 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -318,7 +318,8 @@ namespace MWGui messageBox("#{sNotifyMessage9}"); int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt(); - MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterFailDisposition); + if (mPtr.getClass().isNpc()) + MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterFailDisposition); return; } @@ -327,7 +328,8 @@ namespace MWGui } int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt(); - MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterSuccessDisposition); + if (mPtr.getClass().isNpc()) + MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterSuccessDisposition); // make the item transfer mTradeModel->transferItems(); From dddc0979a294aa516aeb21ab4c01ac29f04315e4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 22:04:46 +0100 Subject: [PATCH 094/168] Fix another fatigue cap issue --- apps/openmw/mwmechanics/spellcasting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 850c4dcf51..de078f9efd 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -437,7 +437,7 @@ namespace MWMechanics DynamicStat fatigue = stats.getFatigue(); const float normalizedEncumbrance = mCaster.getClass().getEncumbrance(mCaster) / mCaster.getClass().getCapacity(mCaster); float fatigueLoss = spell->mData.mCost * (fFatigueSpellBase + normalizedEncumbrance * fFatigueSpellMult); - fatigue.setCurrent(std::max(0.f, fatigue.getCurrent() - fatigueLoss)); + fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss); stats.setFatigue(fatigue); bool fail = false; From 44b2380874007c7dfb29b1b4c9d1a85fab6bfed5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 22:26:26 +0100 Subject: [PATCH 095/168] Closes #947: Decrease fatigue when running, swimming and attacking --- apps/openmw/mwclass/npc.cpp | 14 +++++++++ apps/openmw/mwmechanics/character.cpp | 37 ++++++++++++++++++++++-- apps/openmw/mwmechanics/spellcasting.cpp | 3 +- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 41c6de40cc..dc219f3730 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -436,6 +436,20 @@ namespace MWClass if(!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name()) weapon = MWWorld::Ptr(); + // Reduce fatigue + // somewhat of a guess, but using the weapon weight makes sense + const float fFatigueAttackBase = gmst.find("fFatigueAttackBase")->getFloat(); + const float fFatigueAttackMult = gmst.find("fFatigueAttackMult")->getFloat(); + const float fWeaponFatigueMult = gmst.find("fWeaponFatigueMult")->getFloat(); + MWMechanics::DynamicStat fatigue = getCreatureStats(ptr).getFatigue(); + const float normalizedEncumbrance = getEncumbrance(ptr) / getCapacity(ptr); + float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult; + if (!weapon.isEmpty()) + fatigueLoss += weapon.getClass().getWeight(weapon) * getNpcStats(ptr).getAttackStrength() * fWeaponFatigueMult; + fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss); + getCreatureStats(ptr).setFatigue(fatigue); + + float dist = 100.0f * (!weapon.isEmpty() ? weapon.get()->mBase->mData.mReach : gmst.find("fHandToHandReach")->getFloat()); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index b29ae29144..0856ada0c7 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -900,6 +900,41 @@ void CharacterController::update(float duration) } } + // reduce fatigue + const MWWorld::Store &gmst = world->getStore().get(); + float fatigueLoss = 0; + static const float fFatigueRunBase = gmst.find("fFatigueRunBase")->getFloat(); + static const float fFatigueRunMult = gmst.find("fFatigueRunMult")->getFloat(); + static const float fFatigueSwimWalkBase = gmst.find("fFatigueSwimWalkBase")->getFloat(); + static const float fFatigueSwimRunBase = gmst.find("fFatigueSwimRunBase")->getFloat(); + static const float fFatigueSwimWalkMult = gmst.find("fFatigueSwimWalkMult")->getFloat(); + static const float fFatigueSwimRunMult = gmst.find("fFatigueSwimRunMult")->getFloat(); + static const float fFatigueSneakBase = gmst.find("fFatigueSneakBase")->getFloat(); + static const float fFatigueSneakMult = gmst.find("fFatigueSneakMult")->getFloat(); + + const float encumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr); + if (encumbrance < 1) + { + if (sneak) + fatigueLoss = fFatigueSneakBase + encumbrance * fFatigueSneakMult; + else + { + if (inwater) + { + if (!isrunning) + fatigueLoss = fFatigueSwimWalkBase + encumbrance * fFatigueSwimWalkMult; + else + fatigueLoss = fFatigueSwimRunBase + encumbrance * fFatigueSwimRunMult; + } + if (isrunning) + fatigueLoss = fFatigueRunBase + encumbrance * fFatigueRunMult; + } + } + fatigueLoss *= duration; + DynamicStat fatigue = cls.getCreatureStats(mPtr).getFatigue(); + fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss, fatigue.getCurrent() < 0); + cls.getCreatureStats(mPtr).setFatigue(fatigue); + if(sneak || inwater || flying) vec.z = 0.0f; @@ -916,8 +951,6 @@ void CharacterController::update(float duration) cls.getCreatureStats(mPtr).land(); } - const MWWorld::Store &gmst = world->getStore().get(); - forcestateupdate = (mJumpState != JumpState_Falling); mJumpState = JumpState_Falling; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index de078f9efd..be67b65928 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -437,8 +437,7 @@ namespace MWMechanics DynamicStat fatigue = stats.getFatigue(); const float normalizedEncumbrance = mCaster.getClass().getEncumbrance(mCaster) / mCaster.getClass().getCapacity(mCaster); float fatigueLoss = spell->mData.mCost * (fFatigueSpellBase + normalizedEncumbrance * fFatigueSpellMult); - fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss); - stats.setFatigue(fatigue); + fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss); stats.setFatigue(fatigue); bool fail = false; From 10ddea45e9f66a03b957608e2aef9f90ec2c1ecf Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 23:11:23 +0100 Subject: [PATCH 096/168] Move crime from onHit to hit, since failed hits are apparently also a crime --- apps/openmw/mwclass/npc.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index dc219f3730..86f0fbc3bf 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -468,6 +468,10 @@ namespace MWClass if(ptr.getRefData().getHandle() == "player") MWBase::Environment::get().getWindowManager()->setEnemy(victim); + // Attacking peaceful NPCs is a crime + if (victim.getClass().isNpc() && victim.getClass().getCreatureStats(victim).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) + MWBase::Environment::get().getMechanicsManager()->commitCrime(ptr, victim, MWBase::MechanicsManager::OT_Assault); + int weapskill = ESM::Skill::HandToHand; if(!weapon.isEmpty()) weapskill = get(weapon).getEquipmentSkill(weapon); @@ -612,10 +616,6 @@ namespace MWClass // NOTE: 'object' and/or 'attacker' may be empty. - // Attacking peaceful NPCs is a crime - if (!attacker.isEmpty() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) - MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault); - if(!successful) { // TODO: Handle HitAttemptOnMe script function From 921ef6cd9c7d36a15bf38dcd5ff2bac005c81dae Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 12 Jan 2014 00:42:27 +0100 Subject: [PATCH 097/168] Closes #1093: Show weapon when initializing the character controller with a weapon equipped --- apps/openmw/mwmechanics/character.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 0856ada0c7..e5236f02b4 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -441,6 +441,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim { getWeaponGroup(mWeaponType, mCurrentWeapon); mUpperBodyState = UpperCharState_WeapEquiped; + mAnimation->showWeapons(true); } } From 1d19d36bd6a14e55a7ea90c155f386ebf235d4a4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 12 Jan 2014 01:20:37 +0100 Subject: [PATCH 098/168] Remove unused magic effect flags and update esmtool output --- apps/esmtool/labels.cpp | 39 +++++++++-------------------- apps/openmw/mwmechanics/alchemy.cpp | 2 +- components/esm/loadmgef.hpp | 6 +---- 3 files changed, 14 insertions(+), 33 deletions(-) diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp index 7b1fc7fb21..56c9a2fadb 100644 --- a/apps/esmtool/labels.cpp +++ b/apps/esmtool/labels.cpp @@ -764,34 +764,19 @@ std::string magicEffectFlags(int flags) { std::string properties = ""; if (flags == 0) properties += "[None] "; - // Enchanting & SpellMaking occur on the same list of effects. - // "EXTRA SPELL" appears in the construction set under both the - // spell making and enchanting tabs as an allowed effect. Since - // most of the effects without this flags are defective in various - // ways, it's still very unclear what these flag bits are. - if (flags & ESM::MagicEffect::SpellMaking) properties += "SpellMaking "; - if (flags & ESM::MagicEffect::Enchanting) properties += "Enchanting "; - if (flags & 0x00000040) properties += "RangeNoSelf "; - if (flags & 0x00000080) properties += "RangeTouch "; - if (flags & 0x00000100) properties += "RangeTarget "; - if (flags & 0x00001000) properties += "Unknown2 "; - if (flags & 0x00000001) properties += "AffectSkill "; - if (flags & 0x00000002) properties += "AffectAttribute "; + if (flags & ESM::MagicEffect::TargetAttribute) properties += "TargetAttribute "; + if (flags & ESM::MagicEffect::TargetSkill) properties += "TargetSkill "; if (flags & ESM::MagicEffect::NoDuration) properties += "NoDuration "; - if (flags & 0x00000008) properties += "NoMagnitude "; - if (flags & 0x00000010) properties += "Negative "; - if (flags & 0x00000020) properties += "Unknown1 "; - // ESM componet says 0x800 is negative, but none of the magic - // effects have this flags set. - if (flags & ESM::MagicEffect::Negative) properties += "Unused "; - // Since only Chameleon has this flag it could be anything - // that uniquely distinguishes Chameleon. - if (flags & 0x00002000) properties += "Chameleon "; - if (flags & 0x00004000) properties += "Bound "; - if (flags & 0x00008000) properties += "Summon "; - // Calm, Demoralize, Frenzy, Lock, Open, Rally, Soultrap, Turn Unded - if (flags & 0x00010000) properties += "Unknown3 "; - if (flags & 0x00020000) properties += "Absorb "; + if (flags & ESM::MagicEffect::NoMagnitude) properties += "NoMagnitude "; + if (flags & ESM::MagicEffect::Harmful) properties += "Harmful "; + if (flags & ESM::MagicEffect::ContinuousVfx) properties += "ContinuousVFX "; + if (flags & ESM::MagicEffect::CastSelf) properties += "CastSelf "; + if (flags & ESM::MagicEffect::CastTouch) properties += "CastTouch "; + if (flags & ESM::MagicEffect::CastTarget) properties += "CastTarget "; + if (flags & ESM::MagicEffect::UncappedDamage) properties += "UncappedDamage "; + if (flags & ESM::MagicEffect::NonRecastable) properties += "NonRecastable "; + if (flags & ESM::MagicEffect::Unreflectable) properties += "Unreflectable "; + if (flags & ESM::MagicEffect::CasterLinked) properties += "CasterLinked "; if (flags & 0xFFFC0000) properties += "Invalid "; properties += str(boost::format("(0x%08X)") % flags); return properties; diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index f994c28b84..af58e9ee0b 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -62,7 +62,7 @@ void MWMechanics::Alchemy::applyTools (int flags, float& value) const { bool magnitude = !(flags & ESM::MagicEffect::NoMagnitude); bool duration = !(flags & ESM::MagicEffect::NoDuration); - bool negative = flags & (ESM::MagicEffect::Negative | ESM::MagicEffect::Harmful); + bool negative = flags & (ESM::MagicEffect::Harmful); int tool = negative ? ESM::Apparatus::Retort : ESM::Apparatus::Albemic; diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index 77056b9ec6..8281f4969d 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -28,11 +28,7 @@ struct MagicEffect UncappedDamage = 0x1000, // Negates multiple cap behaviours. Allows an effect to reduce an attribute below zero; removes the normal minimum effect duration of 1 second. NonRecastable = 0x4000, // Does not land if parent spell is already affecting target. Shows "you cannot re-cast" message for self target. Unreflectable = 0x10000, // Cannot be reflected, the effect always lands normally. - CasterLinked = 0x20000, // Must quench if caster is dead, or not an NPC/creature. Not allowed in containter/door trap spells. - SpellMaking = 0x0200, - Enchanting = 0x0400, - Negative = 0x0800 // A harmful effect. Will determine whether - // eg. NPCs regard this spell as an attack. (same as 0x10?) + CasterLinked = 0x20000 // Must quench if caster is dead, or not an NPC/creature. Not allowed in containter/door trap spells. }; enum MagnitudeDisplayType { From fb778f8ecd76a703e0da6c2aa260d142f63d4490 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 12 Jan 2014 04:09:51 +0100 Subject: [PATCH 099/168] Use fEncumbranceStrMult --- apps/openmw/mwclass/npc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 86f0fbc3bf..4aa27e38a3 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1055,7 +1055,8 @@ namespace MWClass float Npc::getCapacity (const MWWorld::Ptr& ptr) const { const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); - return stats.getAttribute(0).getModified()*5; + static const float fEncumbranceStrMult = MWBase::Environment::get().getWorld()->getStore().get().find("fEncumbranceStrMult")->getFloat(); + return stats.getAttribute(0).getModified()*fEncumbranceStrMult; } float Npc::getEncumbrance (const MWWorld::Ptr& ptr) const From 767c72e619b1217842bd87e4dc72793310f4b751 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 12 Jan 2014 10:04:06 +0100 Subject: [PATCH 100/168] Fix diagonal movement being faster than forward movement --- apps/openmw/mwmechanics/character.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index e5236f02b4..86785ec228 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -863,6 +863,7 @@ void CharacterController::update(float duration) bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); bool flying = world->isFlying(mPtr); Ogre::Vector3 vec = cls.getMovementVector(mPtr); + vec.normalise(); if(mHitState != CharState_None && mJumpState == JumpState_None) vec = Ogre::Vector3(0.0f); Ogre::Vector3 rot = cls.getRotationVector(mPtr); @@ -1119,9 +1120,11 @@ void CharacterController::update(float duration) else moved = Ogre::Vector3(0.0f); - // Ensure we're moving in generally the right direction + // Ensure we're moving in generally the right direction... if(mMovementSpeed > 0.f) { + float l = moved.length(); + if((movement.x < 0.0f && movement.x < moved.x*2.0f) || (movement.x > 0.0f && movement.x > moved.x*2.0f)) moved.x = movement.x; @@ -1131,7 +1134,12 @@ void CharacterController::update(float duration) if((movement.z < 0.0f && movement.z < moved.z*2.0f) || (movement.z > 0.0f && movement.z > moved.z*2.0f)) moved.z = movement.z; + // but keep the original speed + float newLength = moved.length(); + if (newLength > 0) + moved *= (l / newLength); } + // Update movement if(moved.squaredLength() > 1.0f) world->queueMovement(mPtr, moved); From f78b846f9e88347097c1de8e7cacdd09627be2f1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 12 Jan 2014 10:21:49 +0100 Subject: [PATCH 101/168] Handle CasterLinked magic effect flag --- apps/openmw/mwmechanics/activespells.cpp | 18 ++++++++++++++++++ apps/openmw/mwmechanics/activespells.hpp | 3 +++ apps/openmw/mwmechanics/actors.cpp | 7 +++++++ apps/openmw/mwmechanics/spellcasting.cpp | 5 +++-- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 2a71659742..994798b0bb 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -205,4 +205,22 @@ namespace MWMechanics } mSpellsChanged = true; } + + void ActiveSpells::purge(const std::string &actorHandle) + { + for (TContainer::iterator it = mSpells.begin(); it != mSpells.end(); ++it) + { + for (std::vector::iterator effectIt = it->second.mEffects.begin(); + effectIt != it->second.mEffects.end();) + { + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mKey.mId); + if (effect->mData.mFlags & ESM::MagicEffect::CasterLinked + && it->second.mCasterHandle == actorHandle) + effectIt = it->second.mEffects.erase(effectIt); + else + effectIt++; + } + } + mSpellsChanged = true; + } } diff --git a/apps/openmw/mwmechanics/activespells.hpp b/apps/openmw/mwmechanics/activespells.hpp index 2ddb4ec556..7a40afb4cb 100644 --- a/apps/openmw/mwmechanics/activespells.hpp +++ b/apps/openmw/mwmechanics/activespells.hpp @@ -90,6 +90,9 @@ namespace MWMechanics /// Remove all active effects, if roll succeeds (for each effect) void purgeAll (float chance); + /// Remove all effects with CASTER_LINKED flag that were cast by \a actorHandle + void purge (const std::string& actorHandle); + bool isSpellActive (std::string id) const; ///< case insensitive diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 468a218927..6f710988e8 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -814,6 +814,13 @@ namespace MWMechanics stats.setMagicEffects(MWMechanics::MagicEffects()); calculateCreatureStatModifiers(iter->first, 0); + // Make sure spell effects with CasterLinked flag are removed + for(PtrControllerMap::iterator iter2(mActors.begin());iter2 != mActors.end();++iter2) + { + MWMechanics::ActiveSpells& spells = iter2->first.getClass().getCreatureStats(iter2->first).getActiveSpells(); + spells.purge(iter->first.getRefData().getHandle()); + } + ++mDeathCount[cls.getId(iter->first)]; if(cls.isEssential(iter->first)) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index be67b65928..a0e91791ba 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -164,8 +164,9 @@ namespace MWMechanics ActiveSpells::Effect effect_ = effect; effect_.mMagnitude *= -1; effects.push_back(effect_); + // Also make sure to set casterHandle = target, so that the effect on the caster gets purged when the target dies caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell("", true, - effects, mSourceName, caster.getRefData().getHandle()); + effects, mSourceName, target.getRefData().getHandle()); } } } @@ -224,7 +225,7 @@ namespace MWMechanics target.getClass().getCreatureStats(target).getActiveSpells().addSpell(mId, mStack, appliedLastingEffects, mSourceName, caster.getRefData().getHandle()); - if (anyHarmfulEffect && target.getClass().isActor() + if (anyHarmfulEffect && target.getClass().isActor() && target != caster && target.getClass().getCreatureStats(target).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) MWBase::Environment::get().getMechanicsManager()->commitCrime(caster, target, MWBase::MechanicsManager::OT_Assault); } From 7983b07b106e6898c14f5277326d88b64384394b Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 13 Jan 2014 06:15:22 +0100 Subject: [PATCH 102/168] Get bk_treasuryreport script to work properly: - OnPcEquip needs to be set on *using* any item, not just equipping - Handle PcSkipEquip - Execute item's script once immediately after setting OnPcEquip - Do not set OnPcEquip when an item that has skipped equipping sets pcskipequip back to 0 and gets equipped --- apps/openmw/mwgui/inventorywindow.cpp | 60 ++++++++++++++++++++------- apps/openmw/mwgui/inventorywindow.hpp | 4 ++ apps/openmw/mwgui/quickkeysmenu.cpp | 14 +------ apps/openmw/mwworld/actionequip.cpp | 6 --- 4 files changed, 50 insertions(+), 34 deletions(-) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 7781c8526d..7139c1b2cc 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -13,6 +13,8 @@ #include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/action.hpp" +#include "../mwscript/interpretercontext.hpp" +#include "../mwbase/scriptmanager.hpp" #include "bookwindow.hpp" #include "scrollwindow.hpp" @@ -351,6 +353,48 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setWeaponVisibility(!mPinned); } + void InventoryWindow::useItem(const MWWorld::Ptr &ptr) + { + const std::string& script = ptr.getClass().getScript(ptr); + + // If the item has a script, set its OnPcEquip to 1 + if (!script.empty() + // Another morrowind oddity: when an item has skipped equipping and pcskipequip is reset to 0 afterwards, + // the next time it is equipped will work normally, but will not set onpcequip + && (ptr != mSkippedToEquip || ptr.getRefData().getLocals().getIntVar(script, "pcskipequip") == 1)) + ptr.getRefData().getLocals().setVarByInt(script, "onpcequip", 1); + + // Give the script a chance to run once before we do anything else + // this is important when setting pcskipequip as a reaction to onpcequip being set (bk_treasuryreport does this) + if (!script.empty()) + { + MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr); + MWBase::Environment::get().getScriptManager()->run (script, interpreterContext); + } + + if (script.empty() || ptr.getRefData().getLocals().getIntVar(script, "pcskipequip") == 0) + { + boost::shared_ptr action = MWWorld::Class::get(ptr).use(ptr); + + action->execute (MWBase::Environment::get().getWorld()->getPlayerPtr()); + + // this is necessary for books/scrolls: if they are already in the player's inventory, + // the "Take" button should not be visible. + // NOTE: the take button is "reset" when the window opens, so we can safely do the following + // without screwing up future book windows + MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false); + MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false); + + mSkippedToEquip = MWWorld::Ptr(); + } + else + mSkippedToEquip = ptr; + + mItemView->update(); + + notifyContentChanged(); + } + void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender) { if (mDragAndDrop->mIsOnDragAndDrop) @@ -369,21 +413,7 @@ namespace MWGui mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount); ptr = *it; } - - boost::shared_ptr action = MWWorld::Class::get(ptr).use(ptr); - - action->execute (MWBase::Environment::get().getWorld()->getPlayerPtr()); - - // this is necessary for books/scrolls: if they are already in the player's inventory, - // the "Take" button should not be visible. - // NOTE: the take button is "reset" when the window opens, so we can safely do the following - // without screwing up future book windows - MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false); - MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false); - - mItemView->update(); - - notifyContentChanged(); + useItem(ptr); } else { diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index 112e737fab..7e5a0fe105 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -46,6 +46,8 @@ namespace MWGui void updatePlayer(); + void useItem(const MWWorld::Ptr& ptr); + void setGuiMode(GuiMode mode); private: @@ -74,6 +76,8 @@ namespace MWGui MyGUI::Button* mFilterMagic; MyGUI::Button* mFilterMisc; + MWWorld::Ptr mSkippedToEquip; + GuiMode mGuiMode; int mLastXSize; diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index 77127f59b8..61e414fc4e 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -308,19 +308,7 @@ namespace MWGui { MWWorld::Ptr item = *button->getChildAt (0)->getUserData(); - boost::shared_ptr action = MWWorld::Class::get(item).use(item); - - action->execute (MWBase::Environment::get().getWorld()->getPlayerPtr()); - - // this is necessary for books/scrolls: if they are already in the player's inventory, - // the "Take" button should not be visible. - // NOTE: the take button is "reset" when the window opens, so we can safely do the following - // without screwing up future book windows - MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false); - MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false); - - // since we changed equipping status, update the inventory window - MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView(); + MWBase::Environment::get().getWindowManager()->getInventoryWindow()->useItem(item); } else if (type == Type_MagicItem) { diff --git a/apps/openmw/mwworld/actionequip.cpp b/apps/openmw/mwworld/actionequip.cpp index 6a0b4eec7d..348b09ad99 100644 --- a/apps/openmw/mwworld/actionequip.cpp +++ b/apps/openmw/mwworld/actionequip.cpp @@ -80,11 +80,5 @@ namespace MWWorld break; } } - - std::string script = MWWorld::Class::get(object).getScript(object); - - /* Set OnPCEquip Variable on item's script, if the player is equipping it, and it has a script with that variable declared */ - if(equipped && actor == MWBase::Environment::get().getWorld()->getPlayerPtr() && script != "") - object.getRefData().getLocals().setVarByInt(script, "onpcequip", 1); } } From 63cd70f810ea12f1f9ba16141b6e36921bcf33a0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 Jan 2014 10:03:25 +0100 Subject: [PATCH 103/168] some junk removal --- apps/openmw/mwworld/actionequip.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/openmw/mwworld/actionequip.cpp b/apps/openmw/mwworld/actionequip.cpp index 348b09ad99..d34773bd51 100644 --- a/apps/openmw/mwworld/actionequip.cpp +++ b/apps/openmw/mwworld/actionequip.cpp @@ -54,8 +54,6 @@ namespace MWWorld assert(it != invStore.end()); - bool equipped = false; - // equip the item in the first free slot for (std::vector::const_iterator slot=slots_.first.begin(); slot!=slots_.first.end(); ++slot) @@ -68,7 +66,6 @@ namespace MWWorld if (slot == --slots_.first.end()) { invStore.equip(*slot, it, actor); - equipped = true; break; } @@ -76,7 +73,6 @@ namespace MWWorld { // slot is not occupied invStore.equip(*slot, it, actor); - equipped = true; break; } } From 83872f6bf58f143b2bd97d833b5f0f870cc72766 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 13 Jan 2014 01:42:19 +0100 Subject: [PATCH 104/168] Knockdown / hit recovery improvements. Use formula and GMSTs from research wiki for knockdown determination. Hand-to-hand automatically knocks out when fatigue empty. --- apps/openmw/mwclass/npc.cpp | 30 +++++++++++++- apps/openmw/mwclass/npc.hpp | 3 ++ apps/openmw/mwmechanics/character.cpp | 48 +++++++++++------------ apps/openmw/mwmechanics/creaturestats.cpp | 22 ++++++++++- apps/openmw/mwmechanics/creaturestats.hpp | 9 ++++- 5 files changed, 85 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 4aa27e38a3..e08a3c07ea 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -242,6 +242,9 @@ namespace MWClass fJumpAcroMultiplier = gmst.find("fJumpAcroMultiplier"); fJumpRunMultiplier = gmst.find("fJumpRunMultiplier"); fWereWolfRunMult = gmst.find("fWereWolfRunMult"); + fKnockDownMult = gmst.find("fKnockDownMult"); + iKnockDownOddsMult = gmst.find("iKnockDownOddsMult"); + iKnockDownOddsBase = gmst.find("iKnockDownOddsBase"); inited = true; } @@ -651,7 +654,20 @@ namespace MWClass { MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); } - getCreatureStats(ptr).setAttacked(true);//used in CharacterController + getCreatureStats(ptr).setAttacked(true); + + // Check for knockdown + float agilityTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() * fKnockDownMult->getFloat(); + float knockdownTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() + * iKnockDownOddsMult->getInt() * 0.01 + iKnockDownOddsBase->getInt(); + roll = std::rand()/ (static_cast (RAND_MAX) + 1) * 100; // [0, 99] + if (ishealth && agilityTerm <= damage && knockdownTerm <= roll) + { + getCreatureStats(ptr).setKnockedDown(true); + + } + else + getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur? if(object.isEmpty()) { @@ -726,6 +742,15 @@ namespace MWClass fatigue.setCurrent(fatigue.getCurrent() - damage, true); getCreatureStats(ptr).setFatigue(fatigue); } + + if (object.isEmpty()) + { + // Hand-to-hand automatically knocks down when running out of fatigue + if (getCreatureStats(ptr).getFatigue().getCurrent() < 0) + { + getCreatureStats(ptr).setKnockedDown(true); + } + } } void Npc::setActorHealth(const MWWorld::Ptr& ptr, float health, const MWWorld::Ptr& attacker) const @@ -1286,4 +1311,7 @@ namespace MWClass const ESM::GameSetting *Npc::fJumpAcroMultiplier; const ESM::GameSetting *Npc::fJumpRunMultiplier; const ESM::GameSetting *Npc::fWereWolfRunMult; + const ESM::GameSetting *Npc::fKnockDownMult; + const ESM::GameSetting *Npc::iKnockDownOddsMult; + const ESM::GameSetting *Npc::iKnockDownOddsBase; } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index c39ca42ef4..22a9632e85 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -33,6 +33,9 @@ namespace MWClass static const ESM::GameSetting *fJumpAcroMultiplier; static const ESM::GameSetting *fJumpRunMultiplier; static const ESM::GameSetting *fWereWolfRunMult; + static const ESM::GameSetting *fKnockDownMult; + static const ESM::GameSetting *iKnockDownOddsMult; + static const ESM::GameSetting *iKnockDownOddsBase; public: diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 86785ec228..07859d57c5 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -157,40 +157,40 @@ public: void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force) { - //hit recoils/knockdown animations handling - if(MWWorld::Class::get(mPtr).isActor()) + // hit recoils/knockdown animations handling + if(mPtr.getClass().isActor()) { - if(MWWorld::Class::get(mPtr).getCreatureStats(mPtr).getAttacked()) + bool recovery = mPtr.getClass().getCreatureStats(mPtr).getHitRecovery(); + bool knockdown = mPtr.getClass().getCreatureStats(mPtr).getKnockedDown(); + if(mHitState == CharState_None) { - MWWorld::Class::get(mPtr).getCreatureStats(mPtr).setAttacked(false); - - if(mHitState == CharState_None) + if(knockdown) { - if(mJumpState != JumpState_None && !MWBase::Environment::get().getWorld()->isFlying(mPtr) - && !MWBase::Environment::get().getWorld()->isSwimming(mPtr) ) + mHitState = CharState_KnockDown; + mCurrentHit = sHitList[sHitListSize-1]; + mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::Group_All, true, 1, "start", "stop", 0.0f, 0); + } + else if (recovery) + { + mHitState = CharState_Hit; + int iHit = rand() % (sHitListSize-1); + mCurrentHit = sHitList[iHit]; + if(mPtr.getRefData().getHandle()=="player" && !mAnimation->hasAnimation(mCurrentHit)) { - mHitState = CharState_KnockDown; - mCurrentHit = sHitList[sHitListSize-1]; - mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::Group_All, true, 1, "start", "stop", 0.0f, 0); - } - else - { - mHitState = CharState_Hit; - int iHit = rand() % (sHitListSize-1); + //only 3 different hit animations if player is in 1st person + int iHit = rand() % (sHitListSize-3); mCurrentHit = sHitList[iHit]; - if(mPtr.getRefData().getHandle()=="player" && !mAnimation->hasAnimation(mCurrentHit)) - { - //only 3 different hit animations if player is in 1st person - int iHit = rand() % (sHitListSize-3); - mCurrentHit = sHitList[iHit]; - } - mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::Group_All, true, 1, "start", "stop", 0.0f, 0); } + mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::Group_All, true, 1, "start", "stop", 0.0f, 0); } } - else if(mHitState != CharState_None && !mAnimation->isPlaying(mCurrentHit)) + else if(!mAnimation->isPlaying(mCurrentHit)) { mCurrentHit.erase(); + if (knockdown) + mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(false); + if (recovery) + mPtr.getClass().getCreatureStats(mPtr).setHitRecovery(false); mHitState = CharState_None; } } diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index b5b9b7156a..aadce499ea 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -15,7 +15,7 @@ namespace MWMechanics mAttacked (false), mHostile (false), mAttackingOrSpell(false), mAttackType(AT_Chop), mIsWerewolf(false), - mFallHeight(0), mRecalcDynamicStats(false) + mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mHitRecovery(false) { for (int i=0; i<4; ++i) mAiSettings[i] = 0; @@ -402,4 +402,24 @@ namespace MWMechanics } return false; } + + void CreatureStats::setKnockedDown(bool value) + { + mKnockdown = value; + } + + bool CreatureStats::getKnockedDown() const + { + return mKnockdown; + } + + void CreatureStats::setHitRecovery(bool value) + { + mHitRecovery = value; + } + + bool CreatureStats::getHitRecovery() const + { + return mHitRecovery; + } } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 6e08046384..1f82a9b5c0 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -34,7 +34,9 @@ namespace MWMechanics bool mAlarmed; bool mAttacked; bool mHostile; - bool mAttackingOrSpell;//for the player, this is true if the left mouse button is pressed, false if not. + bool mAttackingOrSpell; + bool mKnockdown; + bool mHitRecovery; float mFallHeight; @@ -186,6 +188,11 @@ namespace MWMechanics float getEvasion() const; + void setKnockedDown(bool value); + bool getKnockedDown() const; + void setHitRecovery(bool value); + bool getHitRecovery() const; + void setLastHitObject(const std::string &objectid); const std::string &getLastHitObject() const; From 3a1b6dd35455d0f0ee33bbfa76493306ee997287 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 13 Jan 2014 01:47:10 +0100 Subject: [PATCH 105/168] Handle fCombatKODamageMult and fCombatCriticalStrikeMult. Fix SelectWrapper Function_Detected. --- apps/openmw/mwclass/npc.cpp | 22 ++++++++++------------ apps/openmw/mwdialogue/filter.cpp | 2 +- apps/openmw/mwworld/class.cpp | 5 ----- apps/openmw/mwworld/class.hpp | 5 ----- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e08a3c07ea..19561e53d6 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -518,12 +518,6 @@ namespace MWClass weapon.getCellRef().mCharge = weapmaxhealth; damage *= float(weapon.getCellRef().mCharge) / weapmaxhealth; } - if(!othercls.hasDetected(victim, ptr)) - { - damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat(); - MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}"); - MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f); - } if (!MWBase::Environment::get().getWorld()->getGodModeState()) weapon.getCellRef().mCharge -= std::min(std::max(1, @@ -545,12 +539,6 @@ namespace MWClass float maxstrike = gmst.find("fMaxHandToHandMult")->getFloat(); damage = stats.getSkill(weapskill).getModified(); damage *= minstrike + ((maxstrike-minstrike)*stats.getAttackStrength()); - if(!othercls.hasDetected(victim, ptr)) - { - damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat(); - MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}"); - MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f); - } healthdmg = (otherstats.getFatigue().getCurrent() < 1.0f) || (otherstats.getMagicEffects().get(ESM::MagicEffect::Paralyze).mMagnitude > 0); @@ -577,6 +565,16 @@ namespace MWClass if(ptr.getRefData().getHandle() == "player") skillUsageSucceeded(ptr, weapskill, 0); + bool detected = MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, victim); + if(!detected) + { + damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat(); + MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}"); + MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f); + } + if (othercls.getCreatureStats(victim).getKnockedDown()) + damage *= gmst.find("fCombatKODamageMult")->getFloat(); + // Apply "On hit" enchanted weapons std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : ""; if (!enchantmentName.empty()) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 4f478afce4..d7b7df983c 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -525,7 +525,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_Detected: - return MWWorld::Class::get (mActor).hasDetected (mActor, player); + return MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, mActor); case SelectWrapper::Function_Attacked: diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 0119cdea5f..934dae015f 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -232,11 +232,6 @@ namespace MWWorld return false; } - bool Class::hasDetected (const MWWorld::Ptr& ptr, const MWWorld::Ptr& ptr2) const - { - return true; - } - float Class::getArmorRating (const MWWorld::Ptr& ptr) const { throw std::runtime_error("Class does not support armor rating"); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 08d769fbe0..c0b010eae8 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -240,11 +240,6 @@ namespace MWWorld /// /// (default implementation: return false) - virtual bool hasDetected (const MWWorld::Ptr& ptr, const MWWorld::Ptr& ptr2) const; - ///< Has \æ ptr detected \a ptr2? - /// - /// (default implementation: return false) - virtual std::string getUpSoundId (const Ptr& ptr) const; ///< Return the up sound ID of \a ptr or throw an exception, if class does not support ID retrieval /// (default implementation: throw an exception) From 413bf127de15af153a28849bbefa7d57f4c62a6d Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 13 Jan 2014 02:54:54 +0100 Subject: [PATCH 106/168] Allow drain fatigue effect to reduce below zero --- apps/openmw/mwmechanics/actors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 6f710988e8..e2255f8cb4 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -334,7 +334,7 @@ namespace MWMechanics float currentDiff = creatureStats.getMagicEffects().get(ESM::MagicEffect::RestoreHealth+i).mMagnitude - creatureStats.getMagicEffects().get(ESM::MagicEffect::DamageHealth+i).mMagnitude - creatureStats.getMagicEffects().get(ESM::MagicEffect::AbsorbHealth+i).mMagnitude; - stat.setCurrent(stat.getCurrent() + currentDiff * duration); + stat.setCurrent(stat.getCurrent() + currentDiff * duration, i == 2); creatureStats.setDynamic(i, stat); } From cd06b2177dc1344acedd51adcdc22bce0f512110 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 13 Jan 2014 02:55:18 +0100 Subject: [PATCH 107/168] Automatically knock down when fatigue goes below zero --- apps/openmw/mwclass/npc.cpp | 9 --------- apps/openmw/mwmechanics/creaturestats.cpp | 3 +++ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 19561e53d6..a7ff92cf5e 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -740,15 +740,6 @@ namespace MWClass fatigue.setCurrent(fatigue.getCurrent() - damage, true); getCreatureStats(ptr).setFatigue(fatigue); } - - if (object.isEmpty()) - { - // Hand-to-hand automatically knocks down when running out of fatigue - if (getCreatureStats(ptr).getFatigue().getCurrent() < 0) - { - getCreatureStats(ptr).setKnockedDown(true); - } - } } void Npc::setActorHealth(const MWWorld::Ptr& ptr, float health, const MWWorld::Ptr& attacker) const diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index aadce499ea..ba6f0ba047 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -207,6 +207,9 @@ namespace MWMechanics mDynamic[index] = value; + if (index == 2 && value.getCurrent() < 0) + setKnockedDown(true); + if (index==0 && mDynamic[index].getCurrent()<1) { if (!mDead) From 73268a8606df642fe360e028b491eccebdc2f608 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 13 Jan 2014 07:05:52 +0100 Subject: [PATCH 108/168] Fix skill progress not working --- apps/openmw/mwgui/statswindow.cpp | 2 +- apps/openmw/mwmechanics/npcstats.cpp | 2 +- apps/openmw/mwmechanics/stat.hpp | 12 ++++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 17bb24e838..37128c43f3 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -185,7 +185,7 @@ namespace MWGui MyGUI::TextBox* widget = mSkillWidgetMap[(int)parSkill]; if (widget) { - float modified = value.getModified(), base = value.getBase(); + int modified = value.getModified(), base = value.getBase(); std::string text = boost::lexical_cast(std::floor(modified)); std::string state = "normal"; if (modified > base) diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 289fcc70fe..f77b042716 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -207,7 +207,7 @@ void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, if(mIsWerewolf) return; - MWMechanics::SkillValue value = getSkill (skillIndex); + MWMechanics::SkillValue& value = getSkill (skillIndex); value.setProgress(value.getProgress() + getSkillGain (skillIndex, class_, usageType)); diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index e66cf86de7..75ac6939aa 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -246,6 +246,18 @@ namespace MWMechanics { return !(left == right); } + + inline bool operator== (const SkillValue& left, const SkillValue& right) + { + return left.getBase() == right.getBase() + && left.getModifier() == right.getModifier() + && left.getDamage() == right.getDamage() + && left.getProgress() == right.getProgress(); + } + inline bool operator!= (const SkillValue& left, const SkillValue& right) + { + return !(left == right); + } } #endif From ba27b693f80091241f4979ef6876883afa69912b Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 13 Jan 2014 07:27:08 +0100 Subject: [PATCH 109/168] Increase sneak skill on successful pickpocket --- apps/openmw/mwgui/container.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index d22842b575..858378c03f 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -349,6 +349,8 @@ namespace MWGui mPickpocketDetected = true; return false; } + else + player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, 1); } else { From 17cc6a695cb2adbbb2cd2c6e41a0651d7bd87c11 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 13 Jan 2014 18:34:28 +0100 Subject: [PATCH 110/168] fixed bug resposnsible for exception throwed. --- apps/opencs/model/tools/referenceablecheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 36878d44b7..d5064d272b 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -39,7 +39,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str stage -= activatorSize; - const int potionSize(mReferencables.getActivators().getSize()); + const int potionSize(mReferencables.getPotions().getSize()); if (stage < potionSize) { From 59de794e58023edeaf218b739bb578fe80cd8150 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 13 Jan 2014 19:02:23 +0100 Subject: [PATCH 111/168] Creature check was not invoked. --- apps/opencs/model/tools/referenceablecheck.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index d5064d272b..f89c641d41 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -206,7 +206,16 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str staticCheck(stage, mReferencables.getStatics(), messages); return; } + + stage -= staticSize; + const int creatureSize(mReferencables.getCreatures().getSize()); + + if (stage < creatureSize) + { + creatureCheck(stage, mReferencables.getCreatures(), messages); + return; + } // if we come that far, we are about to perform our last, final check. finalCheck(messages); return; @@ -215,7 +224,7 @@ void CSMTools::ReferenceableCheckStage::perform(int stage, std::vector< std::str int CSMTools::ReferenceableCheckStage::setup() { mPlayerPresent = false; - return mReferencables.getSize() + 2; //DANGER, final check is not performed if it is just +1 + return mReferencables.getSize() + 1; } void CSMTools::ReferenceableCheckStage::bookCheck( From e34cb9e93196745519aa2e5340a04a698d1af680 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 13 Jan 2014 19:17:03 +0100 Subject: [PATCH 112/168] changed according to the scrawl sugestion --- apps/opencs/model/tools/referenceablecheck.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index f89c641d41..3be594d3e0 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -2,6 +2,7 @@ #include "../world/record.hpp" #include "../world/universalid.hpp" #include +#include "../../../../openmw/apps/openmw/mwclass/misc.hpp" CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, @@ -660,7 +661,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( int gold(npc.mNpdt52.mGold); //Detect if player is present - if ( boost::algorithm::iequals(npc.mId, "player") ) + if (Misc::StringUtils::ciEqual(npc.mId, "player")) { mPlayerPresent = true; } From 0d0005c433b5b17ea0647c2c769030e4c21f8084 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 02:20:13 +0100 Subject: [PATCH 113/168] Fix fatigue not restoring when waiting --- apps/openmw/mwbase/mechanicsmanager.hpp | 5 +++-- apps/openmw/mwgui/trainingwindow.cpp | 2 ++ apps/openmw/mwgui/travelwindow.cpp | 2 +- apps/openmw/mwgui/waitdialog.cpp | 3 +-- apps/openmw/mwmechanics/actors.cpp | 12 +++++------- apps/openmw/mwmechanics/actors.hpp | 4 ++-- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 4 ++-- apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 5 +++-- 8 files changed, 19 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 85fcfc75ba..d1472de388 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -76,8 +76,9 @@ namespace MWBase virtual void setPlayerClass (const ESM::Class& class_) = 0; ///< Set player class to custom class. - virtual void restoreDynamicStats() = 0; - ///< If the player is sleeping, this should be called every hour. + virtual void rest(bool sleep) = 0; + ///< If the player is sleeping or waiting, this should be called every hour. + /// @param sleep is the player sleeping or waiting? virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0; ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 24be5363d6..bee76992af 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -154,6 +154,8 @@ namespace MWGui // advance time MWBase::Environment::get().getWorld ()->advanceTime (2); + MWBase::Environment::get().getMechanicsManager()->rest(false); + MWBase::Environment::get().getMechanicsManager()->rest(false); MWBase::Environment::get().getWorld ()->getFader()->fadeOut(0.25); mFadeTimeRemaining = 0.5; diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index dcf54d25a3..c314ce1fda 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -148,7 +148,7 @@ namespace MWGui int hours = static_cast(d /MWBase::Environment::get().getWorld()->getStore().get().find("fTravelTimeMult")->getFloat()); for(int i = 0;i < hours;i++) { - MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats (); + MWBase::Environment::get().getMechanicsManager ()->rest (true); } MWBase::Environment::get().getWorld()->advanceTime(hours); diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index e71ed4247c..5058e53eef 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -253,8 +253,7 @@ namespace MWGui if (mCurHour <= mHours) { MWBase::Environment::get().getWorld ()->advanceTime (1); - if (mSleeping) - MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats (); + MWBase::Environment::get().getMechanicsManager ()->rest (mSleeping); } } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index e2255f8cb4..0fc7210b25 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -199,7 +199,7 @@ namespace MWMechanics } // fatigue restoration - calculateRestoration(ptr, duration); + calculateRestoration(ptr, duration, false); } void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) @@ -257,7 +257,7 @@ namespace MWMechanics creatureStats.setFatigue(fatigue); } - void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration) + void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration, bool sleep) { if (ptr.getClass().getCreatureStats(ptr).isDead()) return; @@ -272,10 +272,9 @@ namespace MWMechanics if (normalizedEncumbrance > 1) normalizedEncumbrance = 1; - if (duration == 3600) + if (sleep) { // the actor is sleeping, restore health and magicka - bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0; DynamicStat health = stats.getHealth(); @@ -294,7 +293,6 @@ namespace MWMechanics } // restore fatigue - float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat (); float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat (); float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat (); @@ -847,10 +845,10 @@ namespace MWMechanics } } } - void Actors::restoreDynamicStats() + void Actors::restoreDynamicStats(bool sleep) { for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) - calculateRestoration(iter->first, 3600); + calculateRestoration(iter->first, 3600, sleep); } int Actors::countDeaths (const std::string& id) const diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 7046543e6a..382aa54005 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -36,7 +36,7 @@ namespace MWMechanics void calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration); void calculateNpcStatModifiers (const MWWorld::Ptr& ptr); - void calculateRestoration (const MWWorld::Ptr& ptr, float duration); + void calculateRestoration (const MWWorld::Ptr& ptr, float duration, bool sleep); void updateDrowning (const MWWorld::Ptr& ptr, float duration); @@ -79,7 +79,7 @@ namespace MWMechanics ///< This function is normally called automatically during the update process, but it can /// also be called explicitly at any time to force an update. - void restoreDynamicStats(); + void restoreDynamicStats(bool sleep); ///< If the player is sleeping, this should be called every hour. int countDeaths (const std::string& id) const; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 76ba2ff16c..456b3a8f9e 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -370,9 +370,9 @@ namespace MWMechanics mObjects.update(duration, paused); } - void MechanicsManager::restoreDynamicStats() + void MechanicsManager::rest(bool sleep) { - mActors.restoreDynamicStats (); + mActors.restoreDynamicStats (sleep); } void MechanicsManager::setPlayerName (const std::string& name) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 569cd2fca0..25e556e6a2 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -81,8 +81,9 @@ namespace MWMechanics virtual void setPlayerClass (const ESM::Class& class_); ///< Set player class to custom class. - virtual void restoreDynamicStats(); - ///< If the player is sleeping, this should be called every hour. + virtual void rest(bool sleep); + ///< If the player is sleeping or waiting, this should be called every hour. + /// @param sleep is the player sleeping or waiting? virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying); ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. From 95651857f3eb90a5c6e0ee1879c7f2154c471508 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 02:52:34 +0100 Subject: [PATCH 114/168] Fix code duplication --- apps/openmw/mwbase/mechanicsmanager.hpp | 3 + apps/openmw/mwgui/waitdialog.cpp | 38 +-------- apps/openmw/mwmechanics/actors.cpp | 77 +++++++++++++------ apps/openmw/mwmechanics/actors.hpp | 3 + .../mwmechanics/mechanicsmanagerimp.cpp | 5 ++ .../mwmechanics/mechanicsmanagerimp.hpp | 3 + 6 files changed, 69 insertions(+), 60 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index d1472de388..726c8cf04a 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -80,6 +80,9 @@ namespace MWBase ///< If the player is sleeping or waiting, this should be called every hour. /// @param sleep is the player sleeping or waiting? + virtual int getHoursToRest() const = 0; + ///< Calculate how many hours the player needs to rest in order to be fully healed + virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0; ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 5058e53eef..1ad703790a 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -144,43 +144,7 @@ namespace MWGui void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender) { - // we need to sleep for a specific time, and since that isn't calculated yet, we'll do it here - // I'm making the assumption here that the # of hours rested is calculated when rest is started - // TODO: the rougher logic here (calculating the hourly deltas) should really go into helper funcs elsewhere - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); - const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - - float hourlyHealthDelta = stats.getAttribute(ESM::Attribute::Endurance).getModified() * 0.1; - - bool stunted = (stats.getMagicEffects().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0); - float fRestMagicMult = store.get().find("fRestMagicMult")->getFloat(); - float hourlyMagickaDelta = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); - - // this massive duplication is why it has to be put into helper functions instead - float fFatigueReturnBase = store.get().find("fFatigueReturnBase")->getFloat(); - float fFatigueReturnMult = store.get().find("fFatigueReturnMult")->getFloat(); - float fEndFatigueMult = store.get().find("fEndFatigueMult")->getFloat(); - float capacity = MWWorld::Class::get(player).getCapacity(player); - float encumbrance = MWWorld::Class::get(player).getEncumbrance(player); - float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity); - if (normalizedEncumbrance > 1) - normalizedEncumbrance = 1; - float hourlyFatigueDelta = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance); - hourlyFatigueDelta *= 3600 * fEndFatigueMult * stats.getAttribute(ESM::Attribute::Endurance).getModified(); - - float healthHours = hourlyHealthDelta >= 0.0 - ? (stats.getHealth().getBase() - stats.getHealth().getCurrent()) / hourlyHealthDelta - : 1.0f; - float magickaHours = stunted ? 0.0 : - hourlyMagickaDelta >= 0.0 - ? (stats.getMagicka().getBase() - stats.getMagicka().getCurrent()) / hourlyMagickaDelta - : 1.0f; - float fatigueHours = hourlyFatigueDelta >= 0.0 - ? (stats.getFatigue().getBase() - stats.getFatigue().getCurrent()) / hourlyFatigueDelta - : 1.0f; - - int autoHours = int(std::ceil( std::max(std::max(healthHours, magickaHours), std::max(fatigueHours, 1.0f)) )); // this should use a variadic max if possible + int autoHours = MWBase::Environment::get().getMechanicsManager()->getHoursToRest(); startWaiting(autoHours); } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0fc7210b25..a0be8357d7 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -82,6 +82,23 @@ bool disintegrateSlot (MWWorld::Ptr ptr, int slot, float disintegrate) return false; } +void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float& magicka) +{ + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); + const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); + + bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0; + int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); + + health = 0.1 * endurance; + + magicka = 0; + if (!stunted) + { + float fRestMagicMult = settings.find("fRestMagicMult")->getFloat (); + magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); + } +} } @@ -261,37 +278,32 @@ namespace MWMechanics { if (ptr.getClass().getCreatureStats(ptr).isDead()) return; - CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); + + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); - int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); - - float capacity = MWWorld::Class::get(ptr).getCapacity(ptr); - float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr); - float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity); - if (normalizedEncumbrance > 1) - normalizedEncumbrance = 1; - if (sleep) { - // the actor is sleeping, restore health and magicka - bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0; + float health, magicka; + getRestorationPerHourOfSleep(ptr, health, magicka); - DynamicStat health = stats.getHealth(); - health.setCurrent (health.getCurrent() + 0.1 * endurance); - stats.setHealth (health); + DynamicStat stat = stats.getHealth(); + stat.setCurrent(stat.getCurrent() + health); + stats.setHealth(stat); - if (!stunted) - { - float fRestMagicMult = settings.find("fRestMagicMult")->getFloat (); - - DynamicStat magicka = stats.getMagicka(); - magicka.setCurrent (magicka.getCurrent() - + fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified()); - stats.setMagicka (magicka); - } + stat = stats.getMagicka(); + stat.setCurrent(stat.getCurrent() + magicka); + stats.setMagicka(stat); } + int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); + + float capacity = ptr.getClass().getCapacity(ptr); + float encumbrance = ptr.getClass().getEncumbrance(ptr); + float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity); + if (normalizedEncumbrance > 1) + normalizedEncumbrance = 1; + // restore fatigue float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat (); float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat (); @@ -303,6 +315,7 @@ namespace MWMechanics DynamicStat fatigue = stats.getFatigue(); fatigue.setCurrent (fatigue.getCurrent() + duration * x); stats.setFatigue (fatigue); + } void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration) @@ -851,6 +864,24 @@ namespace MWMechanics calculateRestoration(iter->first, 3600, sleep); } + int Actors::getHoursToRest(const MWWorld::Ptr &ptr) const + { + float healthPerHour, magickaPerHour; + getRestorationPerHourOfSleep(ptr, healthPerHour, magickaPerHour); + + CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + + float healthHours = healthPerHour >= 0 + ? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour + : 1.0f; + float magickaHours = magickaPerHour >= 0 + ? (stats.getMagicka().getModified() - stats.getMagicka().getCurrent()) / magickaPerHour + : 1.0f; + + int autoHours = std::ceil(std::max(1.f, std::max(healthHours, magickaHours))); + return autoHours; + } + int Actors::countDeaths (const std::string& id) const { std::map::const_iterator iter = mDeathCount.find(id); diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 382aa54005..b7544dad41 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -81,6 +81,9 @@ namespace MWMechanics void restoreDynamicStats(bool sleep); ///< If the player is sleeping, this should be called every hour. + + int getHoursToRest(const MWWorld::Ptr& ptr) const; + ///< Calculate how many hours the given actor needs to rest in order to be fully healed int countDeaths (const std::string& id) const; ///< Return the number of deaths for actors with the given ID. diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 456b3a8f9e..d6dd73bd08 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -375,6 +375,11 @@ namespace MWMechanics mActors.restoreDynamicStats (sleep); } + int MechanicsManager::getHoursToRest() const + { + return mActors.getHoursToRest(mWatched); + } + void MechanicsManager::setPlayerName (const std::string& name) { MWBase::World *world = MWBase::Environment::get().getWorld(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 25e556e6a2..469123df98 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -85,6 +85,9 @@ namespace MWMechanics ///< If the player is sleeping or waiting, this should be called every hour. /// @param sleep is the player sleeping or waiting? + virtual int getHoursToRest() const; + ///< Calculate how many hours the player needs to rest in order to be fully healed + virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying); ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. From 2196ce427aa7b2eb0d40cae7ccf82c060f5b7103 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 03:08:37 +0100 Subject: [PATCH 115/168] Closes #556: Link movie volume to 'master' volume slider, instead of 'music'. --- apps/openmw/mwsound/soundmanagerimp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 28a3aae371..a7ee968314 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -156,11 +156,12 @@ namespace MWSound volume *= mFootstepsVolume; break; case Play_TypeMusic: - case Play_TypeMovie: volume *= mMusicVolume; break; case Play_TypeMask: break; + default: + break; } return volume; } From 396efd580b74dadb34fe3b5156e3d79d3949321e Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 03:26:56 +0100 Subject: [PATCH 116/168] Fix a leftover of the old coordinate system --- apps/openmw/mwsound/openal_output.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 4ee754b35d..9dc0b8c5db 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -403,7 +403,7 @@ void OpenAL_SoundStream::update() alSourcef(mSource, AL_GAIN, gain); alSourcef(mSource, AL_PITCH, pitch); - alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]); + alSource3f(mSource, AL_POSITION, mPos[0], mPos[1], mPos[2]); alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f); alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f); throwALerror(); From 9de3abcb5f8cd5a5f7486cdf73b5729fc870761d Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 03:34:11 +0100 Subject: [PATCH 117/168] Closes #1105: Do not reduce magicka if unable to cast --- apps/openmw/mwworld/worldimp.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 620058c65f..f9899c3a20 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2075,8 +2075,11 @@ namespace MWWorld } // Reduce mana - magicka.setCurrent(magicka.getCurrent() - spell->mData.mCost); - stats.setMagicka(magicka); + if (!fail) + { + magicka.setCurrent(magicka.getCurrent() - spell->mData.mCost); + stats.setMagicka(magicka); + } } if (isPlayer && fail) From 6aa56354c0eaba9f7c6a2aa4a892cc8d65f8832e Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 05:24:58 +0100 Subject: [PATCH 118/168] Revert "Bug #991: Don't autoequip items with harmful permanent enchantments" This is no longer needed, since merchants no longer equip items sold to them (2f35e5a04ef828d4e99e28e0be74b175c766d13d). Also, items with harmful enchantments that are initially in the NPCs inventory *must* be equipped (e.g. slave bracers) This reverts commit 71d9755ef167a25ea3ce8098325b44e0811b6bf8. --- apps/openmw/mwworld/inventorystore.cpp | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 3e81da2122..e8938b2c0e 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -195,29 +195,6 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) std::pair, bool> itemsSlots = MWWorld::Class::get (*iter).getEquipmentSlots (*iter); - // Skip items that have *only* harmful permanent effects - if (!test.getClass().getEnchantment(test).empty()) - { - const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Enchantment* enchantment = store.get().find(test.getClass().getEnchantment(test)); - bool harmfulEffect = false; - bool usefulEffect = false; - if (enchantment->mData.mType == ESM::Enchantment::ConstantEffect) - { - for (std::vector::const_iterator it = enchantment->mEffects.mList.begin(); - it != enchantment->mEffects.mList.end(); ++it) - { - const ESM::MagicEffect* effect = store.get().find(it->mEffectID); - if (effect->mData.mFlags & ESM::MagicEffect::Harmful) - harmfulEffect = true; - else - usefulEffect = true; - } - } - if (harmfulEffect && !usefulEffect) - continue; - } - for (std::vector::const_iterator iter2 (itemsSlots.first.begin()); iter2!=itemsSlots.first.end(); ++iter2) { From 90b92a8f41a95cde1bf239052fe4a61e63dfc9e9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 05:37:06 +0100 Subject: [PATCH 119/168] Move levelled list code out of ContainerStore --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwmechanics/levelledlist.hpp | 78 +++++++++++++++++++++++ apps/openmw/mwworld/containerstore.cpp | 79 ++++++------------------ apps/openmw/mwworld/containerstore.hpp | 2 +- 4 files changed, 98 insertions(+), 63 deletions(-) create mode 100644 apps/openmw/mwmechanics/levelledlist.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index eb5b71ec34..4da5e29970 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -74,7 +74,7 @@ add_openmw_dir (mwmechanics mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow aiescort aiactivate aicombat repair enchanting pathfinding security spellsuccess spellcasting - disease pickpocket + disease pickpocket levelledlist ) add_openmw_dir (mwbase diff --git a/apps/openmw/mwmechanics/levelledlist.hpp b/apps/openmw/mwmechanics/levelledlist.hpp new file mode 100644 index 0000000000..af5f71f51b --- /dev/null +++ b/apps/openmw/mwmechanics/levelledlist.hpp @@ -0,0 +1,78 @@ +#ifndef OPENMW_MECHANICS_LEVELLEDLIST_H +#define OPENMW_MECHANICS_LEVELLEDLIST_H + +#include "../mwworld/ptr.hpp" +#include "../mwworld/manualref.hpp" +#include "../mwworld/class.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" + +namespace MWMechanics +{ + + /// @return ID of resulting item, or empty if none + std::string getLevelledItem (const ESM::LeveledListBase* levItem, unsigned char failChance=0) + { + const std::vector& items = levItem->mList; + + const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerLevel = player.getClass().getCreatureStats(player).getLevel(); + + failChance += levItem->mChanceNone; + + float random = static_cast (std::rand()) / RAND_MAX; + if (random < failChance/100.f) + return std::string(); + + std::vector candidates; + int highestLevel = 0; + for (std::vector::const_iterator it = items.begin(); it != items.end(); ++it) + { + if (it->mLevel > highestLevel) + highestLevel = it->mLevel; + } + + std::pair highest = std::make_pair(-1, ""); + for (std::vector::const_iterator it = items.begin(); it != items.end(); ++it) + { + if (playerLevel >= it->mLevel + && (levItem->mFlags & ESM::LeveledListBase::AllLevels || it->mLevel == highestLevel)) + { + candidates.push_back(it->mId); + if (it->mLevel >= highest.first) + highest = std::make_pair(it->mLevel, it->mId); + } + + } + if (candidates.empty()) + return std::string(); + std::string item = candidates[std::rand()%candidates.size()]; + + // Is this another levelled item or a real item? + try + { + MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, 1); + if (ref.getPtr().getTypeName() != typeid(ESM::ItemLevList).name() + && ref.getPtr().getTypeName() != typeid(ESM::CreatureLevList).name()) + { + return item; + } + else + { + if (ref.getPtr().getTypeName() == typeid(ESM::ItemLevList).name()) + return getLevelledItem(ref.getPtr().get()->mBase, failChance); + else + return getLevelledItem(ref.getPtr().get()->mBase, failChance); + } + } + catch (std::logic_error& e) + { + // Vanilla doesn't fail on nonexistent items in levelled lists + std::cerr << "Warning: ignoring nonexistent item '" << item << "'" << std::endl; + return std::string(); + } + } + +} + +#endif diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 744971985c..864bb2a0d3 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -5,17 +5,11 @@ #include #include -#include - -#include -#include -#include - #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwbase/scriptmanager.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/levelledlist.hpp" #include "manualref.hpp" #include "refdata.hpp" @@ -309,72 +303,35 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std:: } void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, const std::string& faction, - int count, unsigned char failChance, bool topLevel) + int count, bool topLevel) { count = std::abs(count); /// \todo implement item restocking (indicated by negative count) - try + ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count); + + if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name()) { - ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count); + const ESM::ItemLevList* levItem = ref.getPtr().get()->mBase; - if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name()) + if (topLevel && count > 1 && levItem->mFlags & ESM::ItemLevList::Each) { - const ESM::ItemLevList* levItem = ref.getPtr().get()->mBase; - const std::vector& items = levItem->mList; - - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - int playerLevel = player.getClass().getCreatureStats(player).getLevel(); - - failChance += levItem->mChanceNone; - - if (topLevel && count > 1 && levItem->mFlags & ESM::ItemLevList::Each) - { - for (int i=0; i (std::rand()) / RAND_MAX; - if (random >= failChance/100.f) - { - std::vector candidates; - int highestLevel = 0; - for (std::vector::const_iterator it = items.begin(); it != items.end(); ++it) - { - if (it->mLevel > highestLevel) - highestLevel = it->mLevel; - } - - std::pair highest = std::make_pair(-1, ""); - for (std::vector::const_iterator it = items.begin(); it != items.end(); ++it) - { - if (playerLevel >= it->mLevel - && (levItem->mFlags & ESM::ItemLevList::AllLevels || it->mLevel == highestLevel)) - { - candidates.push_back(it->mId); - if (it->mLevel >= highest.first) - highest = std::make_pair(it->mLevel, it->mId); - } - - } - if (candidates.empty()) - return; - std::string item = candidates[std::rand()%candidates.size()]; - addInitialItem(item, owner, faction, count, failChance, false); - } + for (int i=0; i()->mBase); + if (id.empty()) + return; + addInitialItem(id, owner, faction, count, false); } } - catch (std::logic_error& e) + else { - // Vanilla doesn't fail on nonexistent items in levelled lists - std::cerr << "Warning: ignoring nonexistent item '" << id << "'" << std::endl; - return; + ref.getPtr().getCellRef().mOwner = owner; + ref.getPtr().getCellRef().mFaction = faction; + addImp (ref.getPtr(), count); } } diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 936468f8dc..0a17287408 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -54,7 +54,7 @@ namespace MWWorld mutable float mCachedWeight; mutable bool mWeightUpToDate; ContainerStoreIterator addImp (const Ptr& ptr, int count); - void addInitialItem (const std::string& id, const std::string& owner, const std::string& faction, int count, unsigned char failChance=0, bool topLevel=true); + void addInitialItem (const std::string& id, const std::string& owner, const std::string& faction, int count, bool topLevel=true); public: From 26d972280f7f555855b5782066a830373cee9486 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 06:03:34 +0100 Subject: [PATCH 120/168] Fix a few text defines --- components/interpreter/defines.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/interpreter/defines.cpp b/components/interpreter/defines.cpp index 5774c96aec..6f3b5bb5aa 100644 --- a/components/interpreter/defines.cpp +++ b/components/interpreter/defines.cpp @@ -64,7 +64,7 @@ namespace Interpreter{ retval << context.getActionBinding("#{sRestKey}"); } else if((found = Check(temp, "actionmenumode", &i, &start))){ - retval << context.getActionBinding("#{sJournal}"); + retval << context.getActionBinding("#{sInventory}"); } else if((found = Check(temp, "actionactivate", &i, &start))){ retval << context.getActionBinding("#{sActivate}"); @@ -88,10 +88,10 @@ namespace Interpreter{ retval << context.getActionBinding("#{sBack}"); } else if((found = Check(temp, "actionuse", &i, &start))){ - retval << "PLACEHOLDER_ACTION_USE"; + retval << context.getActionBinding("#{sUse}"); } else if((found = Check(temp, "actionrun", &i, &start))){ - retval << "PLACEHOLDER_ACTION_RUN"; + retval << context.getActionBinding("#{sRun}"); } else if((found = Check(temp, "pcclass", &i, &start))){ retval << context.getPCClass(); From b8583124e0f49097f362b1b9e5a2054f246813be Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 06:13:30 +0100 Subject: [PATCH 121/168] Correction for RemoveSoulgem instruction --- apps/openmw/mwscript/containerextensions.cpp | 2 +- apps/openmw/mwscript/miscextensions.cpp | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 202ec64647..7bac7cdbea 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -282,7 +282,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - const std::string &name = runtime.getStringLiteral (runtime[0].mInteger); + const std::string &name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr); diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index bb3600a272..637159475f 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -371,15 +371,20 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWWorld::Ptr ptr = R()(runtime); std::string soul = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr); - - store.remove(soul, 1, ptr); + for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + { + if (::Misc::StringUtils::ciEqual(it->getCellRef().mSoul, soul)) + { + store.remove(*it, 1, ptr); + return; + } + } } }; From 69381c49c71f18cd7e58bb71682c5cbbb7abf215 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 07:39:44 +0100 Subject: [PATCH 122/168] Added a todo comment --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index d6dd73bd08..1738f9fdd1 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -901,6 +901,9 @@ namespace MWMechanics static float fSneakSkillMult = store.find("fSneakSkillMult")->getFloat(); static float fSneakBootMult = store.find("fSneakBootMult")->getFloat(); float sneak = 0; + // TODO: According to Hrnchamd Research:Movement, "Creatures have generalized combat, magic and stealth + // stats which substitute for the specific skills (in the same way as specializations)." + // This probably applies to a large part of the code base. if (ptr.getClass().isNpc()) sneak = ptr.getClass().getNpcStats(ptr).getSkill(ESM::Skill::Sneak).getModified(); int agility = stats.getAttribute(ESM::Attribute::Agility).getModified(); From 52b9ebff9dc40545efa4e3676b5f42bd40ce7d7f Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 07:40:17 +0100 Subject: [PATCH 123/168] Closes #1092: Implement sleep interruption. Fix levelled list flags for creatures. Change World::copyObjectToCell to search for the correct cell. --- apps/esmtool/labels.cpp | 22 ++++++--- apps/esmtool/labels.hpp | 3 +- apps/esmtool/record.cpp | 8 ++-- apps/openmw/mwbase/world.hpp | 3 ++ apps/openmw/mwgui/waitdialog.cpp | 35 ++++++++++++++- apps/openmw/mwgui/waitdialog.hpp | 3 ++ apps/openmw/mwmechanics/actors.cpp | 2 +- apps/openmw/mwmechanics/character.cpp | 1 + apps/openmw/mwmechanics/levelledlist.hpp | 16 ++++--- apps/openmw/mwworld/containerstore.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 57 ++++++++++++++++++++---- apps/openmw/mwworld/worldimp.hpp | 5 ++- components/esm/loadlevlist.hpp | 36 +++++++++------ 13 files changed, 150 insertions(+), 43 deletions(-) diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp index 56c9a2fadb..d270a9534c 100644 --- a/apps/esmtool/labels.cpp +++ b/apps/esmtool/labels.cpp @@ -717,16 +717,26 @@ std::string landFlags(int flags) return properties; } -std::string leveledListFlags(int flags) +std::string itemListFlags(int flags) { std::string properties = ""; if (flags == 0) properties += "[None] "; - if (flags & ESM::LeveledListBase::AllLevels) properties += "AllLevels "; - // This flag apparently not present on creature lists... - if (flags & ESM::LeveledListBase::Each) properties += "Each "; + if (flags & ESM::ItemLevList::AllLevels) properties += "AllLevels "; + if (flags & ESM::ItemLevList::Each) properties += "Each "; int unused = (0xFFFFFFFF ^ - (ESM::LeveledListBase::AllLevels| - ESM::LeveledListBase::Each)); + (ESM::ItemLevList::AllLevels| + ESM::ItemLevList::Each)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string creatureListFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::CreatureLevList::AllLevels) properties += "AllLevels "; + int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels); if (flags & unused) properties += "Invalid "; properties += str(boost::format("(0x%08X)") % flags); return properties; diff --git a/apps/esmtool/labels.hpp b/apps/esmtool/labels.hpp index 48d7b249bd..007f933164 100644 --- a/apps/esmtool/labels.hpp +++ b/apps/esmtool/labels.hpp @@ -50,7 +50,8 @@ std::string cellFlags(int flags); std::string containerFlags(int flags); std::string creatureFlags(int flags); std::string landFlags(int flags); -std::string leveledListFlags(int flags); +std::string creatureListFlags(int flags); +std::string itemListFlags(int flags); std::string lightFlags(int flags); std::string magicEffectFlags(int flags); std::string npcFlags(int flags); diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index a5664c1c86..b68004f1f6 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -834,7 +834,8 @@ template<> void Record::print() { std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; - std::cout << " Flags: " << leveledListFlags(mData.mFlags) << std::endl; + std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl; + std::cout << " Chance none: " << mData.mChanceNone << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) @@ -846,11 +847,12 @@ template<> void Record::print() { std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; - std::cout << " Flags: " << leveledListFlags(mData.mFlags) << std::endl; + std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl; + std::cout << " Chance none: " << mData.mChanceNone << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) - std::cout << " Inventory: Count: " << iit->mLevel + std::cout << " Inventory: Level: " << iit->mLevel << " Item: " << iit->mId << std::endl; } diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index fe40fab24f..83fcba87cc 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -460,6 +460,9 @@ namespace MWBase virtual void confiscateStolenItems(const MWWorld::Ptr& ptr) = 0; virtual void goToJail () = 0; + + /// Spawn a random creature from a levelled list next to the player + virtual void spawnRandomCreature(const std::string& creatureList) = 0; }; } diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 1ad703790a..f52771ffe8 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -48,6 +48,7 @@ namespace MWGui , mRemainingTime(0.05) , mCurHour(0) , mManualHours(1) + , mInterruptAt(-1) { getWidget(mDateTimeText, "DateTimeText"); getWidget(mRestText, "RestText"); @@ -156,7 +157,8 @@ namespace MWGui void WaitDialog::startWaiting(int hoursToWait) { - MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.2); + MWBase::World* world = MWBase::Environment::get().getWorld(); + world->getFader ()->fadeOut(0.2); setVisible(false); mProgressBar.setVisible (true); @@ -164,6 +166,30 @@ namespace MWGui mCurHour = 0; mHours = hoursToWait; + // FIXME: move this somewhere else? + mInterruptAt = -1; + MWWorld::Ptr player = world->getPlayerPtr(); + if (mSleeping && player.getCell()->isExterior()) + { + std::string regionstr = player.getCell()->mCell->mRegion; + if (!regionstr.empty()) + { + const ESM::Region *region = world->getStore().get().find (regionstr); + if (!region->mSleepList.empty()) + { + float fSleepRandMod = world->getStore().get().find("fSleepRandMod")->getFloat(); + int x = std::rand()/ (static_cast (RAND_MAX) + 1) * hoursToWait; // [0, hoursRested] + float y = fSleepRandMod * hoursToWait; + if (x > y) + { + float fSleepRestMod = world->getStore().get().find("fSleepRestMod")->getFloat(); + mInterruptAt = int(fSleepRestMod * hoursToWait); + mInterruptCreatureList = region->mSleepList; + } + } + } + } + mRemainingTime = 0.05; mProgressBar.setProgress (0, mHours); } @@ -206,6 +232,13 @@ namespace MWGui if (!mWaiting) return; + if (mCurHour == mInterruptAt) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sSleepInterrupt}"); + MWBase::Environment::get().getWorld()->spawnRandomCreature(mInterruptCreatureList); + stopWaiting(); + } + mRemainingTime -= dt; while (mRemainingTime < 0) diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp index 2723f7a805..d96649af6f 100644 --- a/apps/openmw/mwgui/waitdialog.hpp +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -51,6 +51,9 @@ namespace MWGui int mManualHours; // stores the hours to rest selected via slider float mRemainingTime; + int mInterruptAt; + std::string mInterruptCreatureList; + WaitDialogProgressBar mProgressBar; void onUntilHealedButtonClicked(MyGUI::Widget* sender); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index a0be8357d7..99381a204e 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -515,7 +515,7 @@ namespace MWMechanics if (magnitude > 0) { ESM::Position ipos = ptr.getRefData().getPosition(); - Ogre::Vector3 pos(ipos.pos[0],ipos.pos[1],ipos.pos[2]); + Ogre::Vector3 pos(ipos.pos); Ogre::Quaternion rot(Ogre::Radian(-ipos.rot[2]), Ogre::Vector3::UNIT_Z); const float distance = 50; pos = pos + distance*rot.yAxis(); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 07859d57c5..9a3983b077 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -860,6 +860,7 @@ void CharacterController::update(float duration) bool onground = world->isOnGround(mPtr); bool inwater = world->isSwimming(mPtr); bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); + isrunning = true; bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); bool flying = world->isFlying(mPtr); Ogre::Vector3 vec = cls.getMovementVector(mPtr); diff --git a/apps/openmw/mwmechanics/levelledlist.hpp b/apps/openmw/mwmechanics/levelledlist.hpp index af5f71f51b..d65503011a 100644 --- a/apps/openmw/mwmechanics/levelledlist.hpp +++ b/apps/openmw/mwmechanics/levelledlist.hpp @@ -11,7 +11,7 @@ namespace MWMechanics { /// @return ID of resulting item, or empty if none - std::string getLevelledItem (const ESM::LeveledListBase* levItem, unsigned char failChance=0) + inline std::string getLevelledItem (const ESM::LeveledListBase* levItem, bool creature, unsigned char failChance=0) { const std::vector& items = levItem->mList; @@ -20,29 +20,33 @@ namespace MWMechanics failChance += levItem->mChanceNone; - float random = static_cast (std::rand()) / RAND_MAX; - if (random < failChance/100.f) + int random = std::rand()/ (static_cast (RAND_MAX) + 1) * 100; // [0, 99] + if (random < failChance) return std::string(); std::vector candidates; int highestLevel = 0; for (std::vector::const_iterator it = items.begin(); it != items.end(); ++it) { - if (it->mLevel > highestLevel) + if (it->mLevel > highestLevel && it->mLevel <= playerLevel) highestLevel = it->mLevel; } + // For levelled creatures, the flags are swapped. This file format just makes so much sense. + bool allLevels = levItem->mFlags & ESM::ItemLevList::AllLevels; + if (creature) + allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels; + std::pair highest = std::make_pair(-1, ""); for (std::vector::const_iterator it = items.begin(); it != items.end(); ++it) { if (playerLevel >= it->mLevel - && (levItem->mFlags & ESM::LeveledListBase::AllLevels || it->mLevel == highestLevel)) + && (allLevels || it->mLevel == highestLevel)) { candidates.push_back(it->mId); if (it->mLevel >= highest.first) highest = std::make_pair(it->mLevel, it->mId); } - } if (candidates.empty()) return std::string(); diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 864bb2a0d3..475eeb8f40 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -321,7 +321,7 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std:: } else { - std::string id = MWMechanics::getLevelledItem(ref.getPtr().get()->mBase); + std::string id = MWMechanics::getLevelledItem(ref.getPtr().get()->mBase, false); if (id.empty()) return; addInitialItem(id, owner, faction, count, false); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f9899c3a20..ebc1044bc4 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -27,6 +27,7 @@ #include "../mwmechanics/movement.hpp" #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/spellcasting.hpp" +#include "../mwmechanics/levelledlist.hpp" #include "../mwrender/sky.hpp" @@ -1538,23 +1539,28 @@ namespace MWWorld } - Ptr World::copyObjectToCell(const Ptr &object, CellStore &cell, const ESM::Position &pos, bool adjustPos) + Ptr World::copyObjectToCell(const Ptr &object, CellStore &cell, ESM::Position pos, bool adjustPos) { - /// \todo add searching correct cell for position specified - MWWorld::Ptr dropped = - MWWorld::Class::get(object).copyToCell(object, cell, pos); - if (object.getClass().isActor() || adjustPos) { Ogre::Vector3 min, max; if (mPhysics->getObjectAABB(object, min, max)) { - float *pos = dropped.getRefData().getPosition().pos; - pos[0] -= (min.x + max.x) / 2; - pos[1] -= (min.y + max.y) / 2; - pos[2] -= min.z; + pos.pos[0] -= (min.x + max.x) / 2; + pos.pos[1] -= (min.y + max.y) / 2; + pos.pos[2] -= min.z; } } + if (cell.isExterior()) + { + int cellX, cellY; + positionToIndex(pos.pos[0], pos.pos[1], cellX, cellY); + cell = *mCells.getExterior(cellX, cellY); + } + + MWWorld::Ptr dropped = + MWWorld::Class::get(object).copyToCell(object, cell, pos); + if (mWorldScene->isCellActive(cell)) { if (dropped.getRefData().isEnabled()) { mWorldScene->addObjectToScene(dropped); @@ -2571,4 +2577,37 @@ namespace MWWorld MWBase::Environment::get().getWindowManager()->messageBox(message, buttons); } } + + void World::spawnRandomCreature(const std::string &creatureList) + { + const ESM::CreatureLevList* list = getStore().get().find(creatureList); + + int iNumberCreatures = getStore().get().find("iNumberCreatures")->getInt(); + int numCreatures = 1 + std::rand()/ (static_cast (RAND_MAX) + 1) * iNumberCreatures; // [1, iNumberCreatures] + + for (int i=0; igetPlayer().getRefData().getPosition(); + Ogre::Vector3 pos(ipos.pos); + Ogre::Quaternion rot(Ogre::Radian(-ipos.rot[2]), Ogre::Vector3::UNIT_Z); + const float distance = 50; + pos = pos + distance*rot.yAxis(); + ipos.pos[0] = pos.x; + ipos.pos[1] = pos.y; + ipos.pos[2] = pos.z; + ipos.rot[0] = 0; + ipos.rot[1] = 0; + ipos.rot[2] = 0; + + MWWorld::CellStore* cell = mPlayer->getPlayer().getCell(); + MWWorld::ManualRef ref(getStore(), selectedCreature, 1); + ref.getPtr().getCellRef().mPos = ipos; + + safePlaceObject(ref.getPtr(),*cell,ipos); + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 634cc8d6b6..92975400a4 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -114,7 +114,7 @@ namespace MWWorld bool moveObjectImp (const Ptr& ptr, float x, float y, float z); ///< @return true if the active cell (cell player is in) changed - Ptr copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos, bool adjustPos=true); + Ptr copyObjectToCell(const Ptr &ptr, CellStore &cell, ESM::Position pos, bool adjustPos=true); void updateWindowManager (); void performUpdateSceneQueries (); @@ -546,6 +546,9 @@ namespace MWWorld virtual void confiscateStolenItems(const MWWorld::Ptr& ptr); virtual void goToJail (); + + /// Spawn a random creature from a levelled list next to the player + virtual void spawnRandomCreature(const std::string& creatureList); }; } diff --git a/components/esm/loadlevlist.hpp b/components/esm/loadlevlist.hpp index 9dcc6177a1..a4e1b85c2d 100644 --- a/components/esm/loadlevlist.hpp +++ b/components/esm/loadlevlist.hpp @@ -20,20 +20,6 @@ class ESMWriter; struct LeveledListBase { - enum Flags - { - - Each = 0x01, // Select a new item each time this - // list is instantiated, instead of - // giving several identical items - // (used when a container has more - // than one instance of one leveled - // list.) - AllLevels = 0x02 // Calculate from all levels <= player - // level, not just the closest below - // player. - }; - int mFlags; unsigned char mChanceNone; // Chance that none are selected (0-100) std::string mId; @@ -61,6 +47,14 @@ struct CreatureLevList: LeveledListBase { static unsigned int sRecordId; + enum Flags + { + + AllLevels = 0x01 // Calculate from all levels <= player + // level, not just the closest below + // player. + }; + CreatureLevList() { mRecName = "CNAM"; @@ -71,6 +65,20 @@ struct ItemLevList: LeveledListBase { static unsigned int sRecordId; + enum Flags + { + + Each = 0x01, // Select a new item each time this + // list is instantiated, instead of + // giving several identical items + // (used when a container has more + // than one instance of one leveled + // list.) + AllLevels = 0x02 // Calculate from all levels <= player + // level, not just the closest below + // player. + }; + ItemLevList() { mRecName = "INAM"; From 2c1ef610b9251fa40cc0a4a6e08813ed886865b8 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 14 Jan 2014 09:16:59 +0100 Subject: [PATCH 124/168] Moving back to boost for case insensitive comparsion. --- apps/opencs/model/tools/referenceablecheck.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 3be594d3e0..f89c641d41 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -2,7 +2,6 @@ #include "../world/record.hpp" #include "../world/universalid.hpp" #include -#include "../../../../openmw/apps/openmw/mwclass/misc.hpp" CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, @@ -661,7 +660,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( int gold(npc.mNpdt52.mGold); //Detect if player is present - if (Misc::StringUtils::ciEqual(npc.mId, "player")) + if ( boost::algorithm::iequals(npc.mId, "player") ) { mPlayerPresent = true; } From c981a2a6f86c2a5938bcba902cae4c8abf417925 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 14 Jan 2014 09:25:03 +0100 Subject: [PATCH 125/168] Removed boost in favor of #include . Hopefully this will make scrawl happy. :P --- apps/opencs/model/tools/referenceablecheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index f89c641d41..5624480af5 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1,7 +1,7 @@ #include "referenceablecheck.hpp" #include "../world/record.hpp" #include "../world/universalid.hpp" -#include +#include CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, @@ -660,7 +660,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( int gold(npc.mNpdt52.mGold); //Detect if player is present - if ( boost::algorithm::iequals(npc.mId, "player") ) + if (Misc::StringUtils::ciEqual(npc.mId, "player")) //Happy now, scrawl? { mPlayerPresent = true; } From 15d946415e0110993efe8fca1610356f9c72cfaf Mon Sep 17 00:00:00 2001 From: greye Date: Tue, 14 Jan 2014 12:46:53 +0400 Subject: [PATCH 126/168] minor cleanup Removed case folding via std::transform, excessive lowerCase() replaced with ciEqual(). --- apps/launcher/unshieldthread.cpp | 6 ++--- apps/opencs/model/world/columns.cpp | 2 +- apps/opencs/model/world/infocollection.cpp | 6 ++--- apps/openmw/mwdialogue/filter.cpp | 27 +++++++++---------- apps/openmw/mwgui/dialogue.cpp | 2 +- apps/openmw/mwgui/messagebox.cpp | 2 +- .../mwmechanics/mechanicsmanagerimp.cpp | 16 ++++++----- apps/openmw/mwworld/cells.cpp | 5 ++-- apps/openmw/mwworld/cellstore.cpp | 8 +----- apps/openmw/mwworld/containerstore.cpp | 2 +- apps/openmw/mwworld/store.cpp | 4 --- 11 files changed, 36 insertions(+), 44 deletions(-) diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index d0dbeb1bdb..52f9357108 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -235,7 +235,7 @@ namespace { for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) { - if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + if(Misc::StringUtils::ciEqual(dir->path().filename().string(), filename)) return dir->path(); } } @@ -243,7 +243,7 @@ namespace { for ( bfs::directory_iterator end, dir(in); dir != end; ++dir ) { - if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + if(Misc::StringUtils::ciEqual(dir->path().filename().string(), filename)) return dir->path(); } } @@ -255,7 +255,7 @@ namespace { for(bfs::directory_iterator end, dir(in); dir != end; ++dir) { - if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + if(Misc::StringUtils::ciEqual(dir->path().filename().string(), filename)) return true; } diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 9c0d5b0fd5..2f3911270e 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -220,7 +220,7 @@ int CSMWorld::Columns::getId (const std::string& name) std::string name2 = Misc::StringUtils::lowerCase (name); for (int i=0; sNames[i].mName; ++i) - if (name2==Misc::StringUtils::lowerCase (sNames[i].mName)) + if (Misc::StringUtils::ciEqual(sNames[i].mName, name2)) return sNames[i].mId; return -1; diff --git a/apps/opencs/model/world/infocollection.cpp b/apps/opencs/model/world/infocollection.cpp index 87bb925c2e..50d09f3139 100644 --- a/apps/opencs/model/world/infocollection.cpp +++ b/apps/opencs/model/world/infocollection.cpp @@ -67,7 +67,7 @@ int CSMWorld::InfoCollection::getIndex (const std::string& id, const std::string std::pair range = getTopicRange (topic); for (; range.first!=range.second; ++range.first) - if (Misc::StringUtils::lowerCase (range.first->get().mId)==fullId) + if (Misc::StringUtils::ciEqual(range.first->get().mId, fullId)) return std::distance (getRecords().begin(), range.first); return -1; @@ -177,8 +177,8 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s RecordConstIterator end = begin; for (; end!=getRecords().end(); ++end) - if (Misc::StringUtils::lowerCase (end->get().mTopicId)!=topic2) + if (!Misc::StringUtils::ciEqual(end->get().mTopicId, topic2)) break; return Range (begin, end); -} \ No newline at end of file +} diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index d7b7df983c..f132d13a31 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -24,7 +24,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const // actor id if (!info.mActor.empty()) { - if ( Misc::StringUtils::lowerCase (info.mActor)!=MWWorld::Class::get (mActor).getId (mActor)) + if ( !Misc::StringUtils::ciEqual(info.mActor, MWWorld::Class::get (mActor).getId (mActor))) return false; } else if (isCreature) @@ -41,7 +41,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const MWWorld::LiveCellRef *cellRef = mActor.get(); - if (Misc::StringUtils::lowerCase (info.mRace)!= Misc::StringUtils::lowerCase (cellRef->mBase->mRace)) + if (!Misc::StringUtils::ciEqual(info.mRace, cellRef->mBase->mRace)) return false; } @@ -53,7 +53,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const MWWorld::LiveCellRef *cellRef = mActor.get(); - if ( Misc::StringUtils::lowerCase (info.mClass)!= Misc::StringUtils::lowerCase (cellRef->mBase->mClass)) + if ( !Misc::StringUtils::ciEqual(info.mClass, cellRef->mBase->mClass)) return false; } @@ -110,7 +110,7 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const // check cell if (!info.mCell.empty()) - if (Misc::StringUtils::lowerCase (player.getCell()->mCell->mName) != Misc::StringUtils::lowerCase (info.mCell)) + if (!Misc::StringUtils::ciEqual(player.getCell()->mCell->mName, info.mCell)) return false; return true; @@ -188,7 +188,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c int i = 0; for (; i (script->mVarNames.size()); ++i) - if (Misc::StringUtils::lowerCase(script->mVarNames[i]) == name) + if (Misc::StringUtils::ciEqual(script->mVarNames[i], name)) break; if (i>=static_cast (script->mVarNames.size())) @@ -262,7 +262,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con std::string name = select.getName(); for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) - if (Misc::StringUtils::lowerCase(iter->getCellRef().mRefID) == name) + if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, name)) sum += iter->getRefData().getCount(); return sum; @@ -429,23 +429,23 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_NotId: - return select.getName()!=Misc::StringUtils::lowerCase (MWWorld::Class::get (mActor).getId (mActor)); + return !Misc::StringUtils::ciEqual(MWWorld::Class::get (mActor).getId (mActor), select.getName()); case SelectWrapper::Function_NotFaction: - return Misc::StringUtils::lowerCase (mActor.get()->mBase->mFaction)!=select.getName(); + return !Misc::StringUtils::ciEqual(mActor.get()->mBase->mFaction, select.getName()); case SelectWrapper::Function_NotClass: - return Misc::StringUtils::lowerCase (mActor.get()->mBase->mClass)!=select.getName(); + return !Misc::StringUtils::ciEqual(mActor.get()->mBase->mClass, select.getName()); case SelectWrapper::Function_NotRace: - return Misc::StringUtils::lowerCase (mActor.get()->mBase->mRace)!=select.getName(); + return !Misc::StringUtils::ciEqual(mActor.get()->mBase->mRace, select.getName()); case SelectWrapper::Function_NotCell: - return Misc::StringUtils::lowerCase (mActor.getCell()->mCell->mName)!=select.getName(); + return !Misc::StringUtils::ciEqual(mActor.getCell()->mCell->mName, select.getName()); case SelectWrapper::Function_NotLocal: { @@ -462,7 +462,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co int i = 0; for (; i < static_cast (script->mVarNames.size()); ++i) - if (Misc::StringUtils::lowerCase(script->mVarNames[i]) == name) + if (Misc::StringUtils::ciEqual(script->mVarNames[i], name)) break; if (i >= static_cast (script->mVarNames.size())) @@ -478,8 +478,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_SameRace: - return Misc::StringUtils::lowerCase (mActor.get()->mBase->mRace)!= - Misc::StringUtils::lowerCase (player.get()->mBase->mRace); + return !Misc::StringUtils::ciEqual(mActor.get()->mBase->mRace, player.get()->mBase->mRace); case SelectWrapper::Function_SameFaction: diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 8269e8364b..481c983142 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -545,7 +545,7 @@ namespace MWGui for (size_t i=0; igetItemCount(); ++i) { std::string item = mTopicsList->getItemNameAt(i); - if (Misc::StringUtils::lowerCase(item) == title) + if (Misc::StringUtils::ciEqual(item, title)) { realTitle = item; break; diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index ae01f42931..644b8f66a5 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -333,7 +333,7 @@ namespace MWGui std::vector::const_iterator button; for(button = mButtons.begin(); button != mButtons.end(); ++button) { - if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok) + if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok)) { MyGUI::InputManager::getInstance().setKeyFocusWidget(*button); (*button)->eventKeyButtonPressed += MyGUI::newDelegate(this, &InteractiveMessageBox::onKeyPressed); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 1738f9fdd1..79a038dffe 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -472,21 +472,23 @@ namespace MWMechanics std::string npcFaction = ""; if(!npcSkill.getFactionRanks().empty()) npcFaction = npcSkill.getFactionRanks().begin()->first; - if (playerStats.getFactionRanks().find(Misc::StringUtils::lowerCase(npcFaction)) != playerStats.getFactionRanks().end()) + Misc::StringUtils::toLower(npcFaction); + + if (playerStats.getFactionRanks().find(npcFaction) != playerStats.getFactionRanks().end()) { - for(std::vector::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.begin(); - it != MWBase::Environment::get().getWorld()->getStore().get().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.end(); ++it) + for(std::vector::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get().find(npcFaction)->mReactions.begin(); + it != MWBase::Environment::get().getWorld()->getStore().get().find(npcFaction)->mReactions.end(); ++it) { - if(Misc::StringUtils::lowerCase(it->mFaction) == Misc::StringUtils::lowerCase(npcFaction) + if(Misc::StringUtils::ciEqual(it->mFaction, npcFaction) && !playerStats.getExpelled(it->mFaction)) reaction = it->mReaction; } - rank = playerStats.getFactionRanks().find(Misc::StringUtils::lowerCase(npcFaction))->second; + rank = playerStats.getFactionRanks().find(npcFaction)->second; } else if (npcFaction != "") { - for(std::vector::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.begin(); - it != MWBase::Environment::get().getWorld()->getStore().get().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.end();++it) + for(std::vector::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get().find(npcFaction)->mReactions.begin(); + it != MWBase::Environment::get().getWorld()->getStore().get().find(npcFaction)->mReactions.end();++it) { if(playerStats.getFactionRanks().find(Misc::StringUtils::lowerCase(it->mFaction)) != playerStats.getFactionRanks().end() ) { diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 575e10f049..c8a070e21c 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -11,11 +11,12 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getCellStore (const ESM::Cell *cell) { if (cell->mData.mFlags & ESM::Cell::Interior) { - std::map::iterator result = mInteriors.find (Misc::StringUtils::lowerCase(cell->mName)); + std::string lowerName(Misc::StringUtils::lowerCase(cell->mName)); + std::map::iterator result = mInteriors.find (lowerName); if (result==mInteriors.end()) { - result = mInteriors.insert (std::make_pair (Misc::StringUtils::lowerCase(cell->mName), Ptr::CellStore (cell))).first; + result = mInteriors.insert (std::make_pair (lowerName, Ptr::CellStore (cell))).first; } return &result->second; diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 0c145ab600..b492c6f32d 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -204,14 +204,8 @@ namespace MWWorld ESM::CellRef &ref = const_cast(*it); //ESM::CellRef &ref = const_cast(it->second); - std::string lowerCase; - - std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); - int rec = store.find(ref.mRefID); - - ref.mRefID = lowerCase; + Misc::StringUtils::toLower(ref.mRefID); /* We can optimize this further by storing the pointer to the record itself in store.all, so that we don't need to look it diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 475eeb8f40..154fa1999d 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -45,7 +45,7 @@ namespace for (typename MWWorld::CellRefList::List::iterator iter (list.mList.begin()); iter!=list.mList.end(); ++iter) { - if (Misc::StringUtils::lowerCase (iter->mBase->mId)==id2) + if (Misc::StringUtils::ciEqual(iter->mBase->mId, id2)) { MWWorld::Ptr ptr (&*iter, 0); ptr.setContainerStore (store); diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 512883f1a3..ca37cc5912 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -31,10 +31,6 @@ void Store::load(ESM::ESMReader &esm, const std::string &id) // Get regular moved reference data. Adapted from CellStore::loadRefs. Maybe we can optimize the following // implementation when the oher implementation works as well. cell->getNextRef(esm, ref); - std::string lowerCase; - - std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); // Add data required to make reference appear in the correct cell. // We should not need to test for duplicates, as this part of the code is pre-cell merge. From 61707694e8bf5878b8f7243722bdc6d5a92aa76e Mon Sep 17 00:00:00 2001 From: greye Date: Tue, 14 Jan 2014 16:22:50 +0400 Subject: [PATCH 127/168] fix memory leak in AISequence --- apps/openmw/mwmechanics/aisequence.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index 916ba1b49f..79a953e385 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -67,7 +67,10 @@ bool MWMechanics::AiSequence::getCombatTarget(std::string &targetActorId) const void MWMechanics::AiSequence::stopCombat() { while (getTypeId() == AiPackage::TypeIdCombat) + { + delete *mPackages.begin(); mPackages.erase (mPackages.begin()); + } } bool MWMechanics::AiSequence::isPackageDone() const @@ -83,6 +86,7 @@ void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor,float duration) { if (mPackages.front()->execute (actor,duration)) { + delete *mPackages.begin(); mPackages.erase (mPackages.begin()); mDone = true; } From 89d4a90c063bcc90acf1bfe085ad924e81622246 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 15 Jan 2014 10:30:43 +0100 Subject: [PATCH 128/168] Localised version of morrowind will no longer spam false positives. Don't check diff, please. --- apps/opencs/model/tools/referenceablecheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 5624480af5..ed0fec1dac 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -769,7 +769,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( for (int i = 0; i < mRaces.getSize(); ++i) { - if (dynamic_cast(mRaces.getRecord(i).get()).mName == npc.mRace) //mId in class, mName for race. Stupid. + if (Misc::StringUtils::ciEqual(dynamic_cast(mRaces.getRecord(i).get()).mId, npc.mRace)) { noSuchRace = false; break; From fbcb1a14fc1db7ec495f9cba0970c807dd53bf15 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 15 Jan 2014 11:12:56 +0100 Subject: [PATCH 129/168] ooops, using search id --- apps/opencs/model/tools/referenceablecheck.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index ed0fec1dac..62b2a51722 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -765,18 +765,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( } else //checking if there is a such race { - bool noSuchRace(true); - - for (int i = 0; i < mRaces.getSize(); ++i) - { - if (Misc::StringUtils::ciEqual(dynamic_cast(mRaces.getRecord(i).get()).mId, npc.mRace)) - { - noSuchRace = false; - break; - } - } - - if (noSuchRace) + if ((!mRaces.searchId(npc.mRace))) { messages.push_back(id.toString() + "|" + npc.mId + " has invalid race"); } From 3d722ba1043fa400e578a7688714cf84aa3c5842 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 15 Jan 2014 11:59:11 +0100 Subject: [PATCH 130/168] Corrected brackets. --- apps/opencs/model/tools/referenceablecheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 62b2a51722..6615d0a579 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -765,7 +765,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( } else //checking if there is a such race { - if ((!mRaces.searchId(npc.mRace))) + if (!mRaces.searchId(npc.mRace)) { messages.push_back(id.toString() + "|" + npc.mId + " has invalid race"); } From 6224344957f1c5eff6f88cd94166ffc8491272e6 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 15 Jan 2014 12:52:38 +0100 Subject: [PATCH 131/168] Being any idiot is hard. --- apps/opencs/model/tools/referenceablecheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 6615d0a579..dab61bfffa 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -765,7 +765,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck( } else //checking if there is a such race { - if (!mRaces.searchId(npc.mRace)) + if (mRaces.searchId(npc.mRace) == -1) { messages.push_back(id.toString() + "|" + npc.mId + " has invalid race"); } From a4602326f3f565cca8e44ec7f402841a00249b32 Mon Sep 17 00:00:00 2001 From: Sandy Date: Wed, 15 Jan 2014 07:30:07 -0500 Subject: [PATCH 132/168] openmw is now available in [community] --- readme.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.txt b/readme.txt index 5b9aafcb34..6b388dc724 100644 --- a/readme.txt +++ b/readme.txt @@ -23,8 +23,8 @@ Ubuntu (and most others) Download the .deb file and install it in the usual way. Arch Linux -There's an OpenMW package available in the AUR Repository: -http://aur.archlinux.org/packages.php?ID=21419 +There's an OpenMW package available in the [community] Repository: +https://www.archlinux.org/packages/?sort=&q=openmw OS X: Open DMG file, copy OpenMW folder anywhere, for example in /Applications From de64c5717961dc247cdbd16e6de371e65c33c681 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 09:07:57 +0100 Subject: [PATCH 133/168] Fix some typos and accidental commit --- apps/esmtool/record.cpp | 4 +--- apps/openmw/mwmechanics/character.cpp | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index b68004f1f6..184d11bb40 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -835,7 +835,6 @@ void Record::print() { std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl; - std::cout << " Chance none: " << mData.mChanceNone << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) @@ -848,7 +847,6 @@ void Record::print() { std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl; - std::cout << " Chance none: " << mData.mChanceNone << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) @@ -960,7 +958,7 @@ void Record::print() std::cout << " RGB Color: " << "(" << mData.mData.mRed << "," << mData.mData.mGreen << "," - << mData.mData.mGreen << ")" << std::endl; + << mData.mData.mBlue << ")" << std::endl; } template<> diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 9a3983b077..07859d57c5 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -860,7 +860,6 @@ void CharacterController::update(float duration) bool onground = world->isOnGround(mPtr); bool inwater = world->isSwimming(mPtr); bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); - isrunning = true; bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); bool flying = world->isFlying(mPtr); Ogre::Vector3 vec = cls.getMovementVector(mPtr); From a432661b8afe05898d7de02f9051a637482c7d2e Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 09:10:09 +0100 Subject: [PATCH 134/168] Minor correction --- apps/openmw/mwgui/waitdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index f52771ffe8..0ead54d9d9 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -183,7 +183,7 @@ namespace MWGui if (x > y) { float fSleepRestMod = world->getStore().get().find("fSleepRestMod")->getFloat(); - mInterruptAt = int(fSleepRestMod * hoursToWait); + mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait); mInterruptCreatureList = region->mSleepList; } } From 0c4b6ea89f31f3cb5523eda963cf0d979336ec80 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 09:35:38 +0100 Subject: [PATCH 135/168] Minor fix --- apps/openmw/mwclass/npc.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index a7ff92cf5e..7ba5f340c2 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -471,10 +471,6 @@ namespace MWClass if(ptr.getRefData().getHandle() == "player") MWBase::Environment::get().getWindowManager()->setEnemy(victim); - // Attacking peaceful NPCs is a crime - if (victim.getClass().isNpc() && victim.getClass().getCreatureStats(victim).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) - MWBase::Environment::get().getMechanicsManager()->commitCrime(ptr, victim, MWBase::MechanicsManager::OT_Assault); - int weapskill = ESM::Skill::HandToHand; if(!weapon.isEmpty()) weapskill = get(weapon).getEquipmentSkill(weapon); @@ -617,6 +613,10 @@ namespace MWClass // NOTE: 'object' and/or 'attacker' may be empty. + // Attacking peaceful NPCs is a crime + if (!attacker.isEmpty() && ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) + MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault); + if(!successful) { // TODO: Handle HitAttemptOnMe script function @@ -631,7 +631,7 @@ namespace MWClass if(!attacker.isEmpty() && attacker.getRefData().getHandle() == "player") { - const std::string &script = ptr.get()->mBase->mScript; + const std::string &script = ptr.getClass().getScript(ptr); /* Set the OnPCHitMe script variable. The script is responsible for clearing it. */ if(!script.empty()) ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1); From d0500e8124aacbe640fdea6364f3c2c0c85d0df3 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 09:47:31 +0100 Subject: [PATCH 136/168] Some unneeded includes cleanup --- apps/openmw/mwclass/npc.cpp | 2 -- apps/openmw/mwgui/birth.cpp | 7 +++---- apps/openmw/mwgui/class.cpp | 8 +++----- apps/openmw/mwgui/race.cpp | 7 +++---- apps/openmw/mwmechanics/enchanting.cpp | 3 +-- apps/openmw/mwscript/guiextensions.cpp | 2 -- apps/openmw/mwscript/statsextensions.cpp | 2 -- apps/openmw/mwscript/transformationextensions.cpp | 5 +---- apps/openmw/mwworld/weather.cpp | 1 - components/bsa/bsa_archive.cpp | 2 ++ components/bsa/bsa_archive.hpp | 2 -- components/nifogre/material.cpp | 2 -- 12 files changed, 13 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 7ba5f340c2..ef56653975 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -3,8 +3,6 @@ #include -#include - #include #include diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 9656067097..9c8e07f3ea 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -1,6 +1,5 @@ #include "birth.hpp" -#include #include #include "../mwbase/environment.hpp" @@ -77,7 +76,7 @@ namespace MWGui size_t count = mBirthList->getItemCount(); for (size_t i = 0; i < count; ++i) { - if (boost::iequals(*mBirthList->getItemDataAt(i), birthId)) + if (Misc::StringUtils::ciEqual(*mBirthList->getItemDataAt(i), birthId)) { mBirthList->setIndexSelected(i); MyGUI::Button* okButton; @@ -112,7 +111,7 @@ namespace MWGui getWidget(okButton, "OKButton"); const std::string *birthId = mBirthList->getItemDataAt(_index); - if (boost::iequals(mCurrentBirthId, *birthId)) + if (Misc::StringUtils::ciEqual(mCurrentBirthId, *birthId)) return; mCurrentBirthId = *birthId; @@ -148,7 +147,7 @@ namespace MWGui mBirthList->setIndexSelected(index); mCurrentBirthId = it2->first; } - else if (boost::iequals(it2->first, mCurrentBirthId)) + else if (Misc::StringUtils::ciEqual(it2->first, mCurrentBirthId)) { mBirthList->setIndexSelected(index); } diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 7965669f19..1e1aebd953 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -1,7 +1,5 @@ #include "class.hpp" -#include - #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" @@ -128,7 +126,7 @@ namespace MWGui size_t count = mClassList->getItemCount(); for (size_t i = 0; i < count; ++i) { - if (boost::iequals(*mClassList->getItemDataAt(i), classId)) + if (Misc::StringUtils::ciEqual(*mClassList->getItemDataAt(i), classId)) { mClassList->setIndexSelected(i); MyGUI::Button* okButton; @@ -163,7 +161,7 @@ namespace MWGui getWidget(okButton, "OKButton"); const std::string *classId = mClassList->getItemDataAt(_index); - if (boost::iequals(mCurrentClassId, *classId)) + if (Misc::StringUtils::ciEqual(mCurrentClassId, *classId)) return; mCurrentClassId = *classId; @@ -193,7 +191,7 @@ namespace MWGui mCurrentClassId = id; mClassList->setIndexSelected(index); } - else if (boost::iequals(id, mCurrentClassId)) + else if (Misc::StringUtils::ciEqual(id, mCurrentClassId)) { mClassList->setIndexSelected(index); } diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 2c73226e3d..299b34b517 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -1,6 +1,5 @@ #include "race.hpp" -#include #include #include @@ -140,7 +139,7 @@ namespace MWGui size_t count = mRaceList->getItemCount(); for (size_t i = 0; i < count; ++i) { - if (boost::iequals(*mRaceList->getItemDataAt(i), raceId)) + if (Misc::StringUtils::ciEqual(*mRaceList->getItemDataAt(i), raceId)) { mRaceList->setIndexSelected(i); MyGUI::Button* okButton; @@ -230,7 +229,7 @@ namespace MWGui MyGUI::Button* okButton; getWidget(okButton, "OKButton"); const std::string *raceId = mRaceList->getItemDataAt(_index); - if (boost::iequals(mCurrentRaceId, *raceId)) + if (Misc::StringUtils::ciEqual(mCurrentRaceId, *raceId)) return; mCurrentRaceId = *raceId; @@ -320,7 +319,7 @@ namespace MWGui continue; mRaceList->addItem(it->mName, it->mId); - if (boost::iequals(it->mId, mCurrentRaceId)) + if (Misc::StringUtils::ciEqual(it->mId, mCurrentRaceId)) mRaceList->setIndexSelected(index); ++index; } diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 9ccc69f901..6c765aa419 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -6,7 +6,6 @@ #include "creaturestats.hpp" #include "npcstats.hpp" -#include namespace MWMechanics { @@ -60,7 +59,7 @@ namespace MWMechanics store.remove(mSoulGemPtr, 1, player); //Exception for Azura Star, new one will be added after enchanting - if(boost::iequals(mSoulGemPtr.get()->mBase->mId, "Misc_SoulGem_Azura")) + if(Misc::StringUtils::ciEqual(mSoulGemPtr.get()->mBase->mId, "Misc_SoulGem_Azura")) store.add("Misc_SoulGem_Azura", 1, player); if(mSelfEnchanting) diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index b5e2bd2931..ab8901881b 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -1,8 +1,6 @@ #include "guiextensions.hpp" -#include - #include #include diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index d6c2cb8947..095fad7ab5 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -3,8 +3,6 @@ #include -#include - #include #include "../mwworld/esmstore.hpp" diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 81aff9958a..43a0fedce9 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -1,9 +1,5 @@ -#include - -#include #include -#include "../mwworld/esmstore.hpp" #include #include @@ -18,6 +14,7 @@ #include "../mwworld/class.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/player.hpp" +#include "../mwworld/esmstore.hpp" #include "interpretercontext.hpp" #include "ref.hpp" diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index c34beb3f2d..b00ad15ca3 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -1,6 +1,5 @@ #include "weather.hpp" -#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 8f07b9e503..eb741fb105 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -23,6 +23,8 @@ #include "bsa_archive.hpp" +#include + #include #include #include diff --git a/components/bsa/bsa_archive.hpp b/components/bsa/bsa_archive.hpp index 18f7377ff2..7f9ebaae10 100644 --- a/components/bsa/bsa_archive.hpp +++ b/components/bsa/bsa_archive.hpp @@ -22,8 +22,6 @@ */ #include -#include -#include #include #ifndef BSA_BSA_ARCHIVE_H diff --git a/components/nifogre/material.cpp b/components/nifogre/material.cpp index e2cc3712b6..4dae1a93de 100644 --- a/components/nifogre/material.cpp +++ b/components/nifogre/material.cpp @@ -10,8 +10,6 @@ #include #include -#include -#include #include From 264736c1391470cc690722f959a722d2c41a476b Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 10:24:49 +0100 Subject: [PATCH 137/168] Remove hopelessly outdated nifogre tests --- components/nifogre/tests/.gitignore | 5 - components/nifogre/tests/Makefile | 19 ---- components/nifogre/tests/ogre_common.cpp | 97 ------------------- .../tests/ogre_manualresource_test.cpp | 40 -------- components/nifogre/tests/ogre_mesh_common.cpp | 69 ------------- components/nifogre/tests/ogre_nif_test.cpp | 50 ---------- .../nifogre/tests/ogre_skeleton_test.cpp | 21 ---- .../tests/output/ogre_manualresource_test.out | 3 - .../nifogre/tests/output/ogre_nif_test.out | 0 .../tests/output/ogre_skeleton_test.out | 1 - components/nifogre/tests/plugins.cfg | 12 --- components/nifogre/tests/test.sh | 18 ---- 12 files changed, 335 deletions(-) delete mode 100644 components/nifogre/tests/.gitignore delete mode 100644 components/nifogre/tests/Makefile delete mode 100644 components/nifogre/tests/ogre_common.cpp delete mode 100644 components/nifogre/tests/ogre_manualresource_test.cpp delete mode 100644 components/nifogre/tests/ogre_mesh_common.cpp delete mode 100644 components/nifogre/tests/ogre_nif_test.cpp delete mode 100644 components/nifogre/tests/ogre_skeleton_test.cpp delete mode 100644 components/nifogre/tests/output/ogre_manualresource_test.out delete mode 100644 components/nifogre/tests/output/ogre_nif_test.out delete mode 100644 components/nifogre/tests/output/ogre_skeleton_test.out delete mode 100644 components/nifogre/tests/plugins.cfg delete mode 100755 components/nifogre/tests/test.sh diff --git a/components/nifogre/tests/.gitignore b/components/nifogre/tests/.gitignore deleted file mode 100644 index 1a55699834..0000000000 --- a/components/nifogre/tests/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.png -meshlist.txt -ogre.cfg -*_test -chris* diff --git a/components/nifogre/tests/Makefile b/components/nifogre/tests/Makefile deleted file mode 100644 index a7c50d1003..0000000000 --- a/components/nifogre/tests/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -GCC=g++ - -all: ogre_manualresource_test ogre_nif_test ogre_skeleton_test - -I_OGRE=$(shell pkg-config --cflags OGRE) -L_OGRE=$(shell pkg-config --libs OGRE) - -ogre_manualresource_test: ogre_manualresource_test.cpp - $(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE) - -ogre_skeleton_test: ogre_skeleton_test.cpp - $(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE) - -ogre_nif_test: ogre_nif_test.cpp ../../nif/nif_file.cpp ../../bsa/bsa_file.cpp ../../bsa/bsa_archive.cpp ../../tools/stringops.cpp ../../mangle/vfs/servers/ogre_vfs.cpp ../ogre_nif_loader.cpp - $(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE) - -clean: - rm *_test - diff --git a/components/nifogre/tests/ogre_common.cpp b/components/nifogre/tests/ogre_common.cpp deleted file mode 100644 index 657913f30f..0000000000 --- a/components/nifogre/tests/ogre_common.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include - -using namespace std; -using namespace Ogre; - -Root *root; -RenderWindow *window; -SceneManager *mgr; - -int shot = 0; - -// Lets you quit by closing the window -struct QuitListener : FrameListener -{ - bool frameStarted(const FrameEvent& evt) - { -#ifdef SCREENSHOT - if(shot == 1) window->writeContentsToFile("nif.png"); - if(shot < 2) shot++; -#endif - - if(window->isClosed()) - return false; - return true; - } -} qlistener; - -// This has to be packaged in a struct because C++ sucks -struct C -{ - static void doTest(); -}; - -int main(int argc, char**args) -{ - // Disable Ogre logging - new LogManager; - Log *log = LogManager::getSingleton().createLog(""); - log->setDebugOutputEnabled(false); - - // Set up Root. - root = new Root("plugins.cfg","ogre.cfg",""); - - if(!root->restoreConfig()) - { - cout << "WARNING: we do NOT recommend fullscreen mode!\n"; - if(!root->showConfigDialog()) - return 1; - } - - mgr = root->createSceneManager(ST_GENERIC); - - // Only render if there are arguments on the command line (we don't - // care what they are.) - bool render = (argc>=2); - - // Create a window - window = root->initialise(true, "Test"); - if(render) - { - // More initialization - Camera *cam = mgr->createCamera("cam"); - Viewport *vp = window->addViewport(cam); - cam->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight())); - cam->setFOVy(Degree(55)); - cam->setPosition(0,0,0); - cam->lookAt(0,0,10); - cam->setNearClipDistance(1); - - root->addFrameListener(&qlistener); - - // Background color - vp->setBackgroundColour(ColourValue(0.5,0.5,0.5)); - - mgr->setAmbientLight(ColourValue(1,1,1)); - } - - // Run the actual test - C::doTest(); - - // Render loop - if(render) - { - cout << "Rendering. Close the window to exit.\n"; - root->startRendering(); - } - - // Cleanup - delete root; - return 0; -} - -void doTest() -{ - cout << "hello\n"; -} diff --git a/components/nifogre/tests/ogre_manualresource_test.cpp b/components/nifogre/tests/ogre_manualresource_test.cpp deleted file mode 100644 index 75e169d540..0000000000 --- a/components/nifogre/tests/ogre_manualresource_test.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - This is a test of the manual resource loader interface to Ogre, - applied to manually created meshes. It defines a simple mesh - consisting of two triangles, and creates three instances of it as - different meshes using the same loader. It is a precursor to the NIF - loading code. If the Ogre interface changes and you have to change - this test, then you will also have to change parts of the NIF - loader. - */ - -#include "ogre_mesh_common.cpp" - -void C::doTest() -{ - // Create a couple of manual meshes - makeMesh("mesh1.mm"); - makeMesh("mesh2.mm"); - makeMesh("mesh3.mm"); - - // Display the meshes - { - SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node"); - Entity *ent = mgr->createEntity("Mesh1", "mesh1.mm"); - node->attachObject(ent); - node->setPosition(3,1,8); - } - - { - SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node2"); - Entity *ent = mgr->createEntity("Mesh2", "mesh2.mm"); - node->attachObject(ent); - node->setPosition(-3,1,8); - } - { - SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node3"); - Entity *ent = mgr->createEntity("Mesh3", "mesh3.mm"); - node->attachObject(ent); - node->setPosition(0,-2,8); - } -} diff --git a/components/nifogre/tests/ogre_mesh_common.cpp b/components/nifogre/tests/ogre_mesh_common.cpp deleted file mode 100644 index 72e51e3317..0000000000 --- a/components/nifogre/tests/ogre_mesh_common.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "ogre_common.cpp" - -struct MyMeshLoader : ManualResourceLoader -{ - void loadResource(Resource *resource) - { - Mesh *mesh = dynamic_cast(resource); - assert(mesh); - - const String& name = mesh->getName(); - cout << "Manually loading mesh " << name << endl; - - // Create the mesh here - int numVerts = 4; - int numFaces = 2*3; - const float vertices[] = - { -1,-1,0, 1,-1,0, - 1,1,0, -1,1,0 }; - - const short faces[] = - { 0,2,1, 0,3,2 }; - - mesh->sharedVertexData = new VertexData(); - mesh->sharedVertexData->vertexCount = numVerts; - - VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; - - decl->addElement(0, 0, VET_FLOAT3, VES_POSITION); - - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - VertexElement::getTypeSize(VET_FLOAT3), - numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - // Upload the vertex data to the card - vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); - - // Set vertex buffer binding so buffer 0 is bound to our vertex buffer - VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; - bind->setBinding(0, vbuf); - - /// Allocate index buffer of the requested number of faces - HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). - createIndexBuffer(HardwareIndexBuffer::IT_16BIT, - numFaces, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - /// Upload the index data to the card - ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); - - SubMesh* sub = mesh->createSubMesh(name+"tris"); - sub->useSharedVertices = true; - - /// Set parameters of the submesh - sub->indexData->indexBuffer = ibuf; - sub->indexData->indexCount = numFaces; - sub->indexData->indexStart = 0; - - mesh->_setBounds(AxisAlignedBox(-1.1,-1.1,-1.1,1.1,1.1,1.1)); - mesh->_setBoundingSphereRadius(2); - } -}; - -MyMeshLoader mml; - -MeshPtr makeMesh(const string &name) -{ - return MeshManager::getSingleton().createManual(name, "General", &mml); -} diff --git a/components/nifogre/tests/ogre_nif_test.cpp b/components/nifogre/tests/ogre_nif_test.cpp deleted file mode 100644 index decd43df57..0000000000 --- a/components/nifogre/tests/ogre_nif_test.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "../ogre_nif_loader.hpp" -#include "../../bsa/bsa_archive.hpp" - -//#define SCREENSHOT - -#include "ogre_common.cpp" - -//const char* mesh = "meshes\\a\\towershield_steel.nif"; -//const char* mesh = "meshes\\r\\bonelord.nif"; -//const char* mesh = "meshes\\m\\text_scroll_open_01.nif"; -const char* mesh = "meshes\\f\\ex_ashl_a_banner_r.nif"; - -void C::doTest() -{ - // Add Morrowind.bsa resource location - Bsa::addBSA("../../data/Morrowind.bsa"); - - // Insert the mesh - NifOgre::NIFLoader::load(mesh); - NifOgre::NIFLoader::load(mesh); - - /* - SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node"); - Entity *ent = mgr->createEntity("Mesh1", mesh); - node->attachObject(ent); - - // Works great for the scroll - node->setPosition(0,4,50); - node->pitch(Degree(20)); - node->roll(Degree(10)); - node->yaw(Degree(-10)); - - /* Bone lord - node->setPosition(0,-70,170); - node->pitch(Degree(-90)); - */ - - // Display it from two different angles - shield and banner - const int sep = 45; - SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node"); - Entity *ent = mgr->createEntity("Mesh1", mesh); - node->attachObject(ent); - node->setPosition(sep,0,130); - node = node->createChildSceneNode("node2"); - ent = mgr->createEntity("Mesh2", mesh); - node->attachObject(ent); - node->setPosition(-2*sep,0,0); - node->yaw(Degree(180)); - //*/ -} diff --git a/components/nifogre/tests/ogre_skeleton_test.cpp b/components/nifogre/tests/ogre_skeleton_test.cpp deleted file mode 100644 index df9139b95b..0000000000 --- a/components/nifogre/tests/ogre_skeleton_test.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "ogre_common.cpp" - -void C::doTest() -{ - SkeletonManager &skm = SkeletonManager::getSingleton(); - - SkeletonPtr skp = skm.create("MySkel", "General"); - - cout << "hello\n"; - /* - MeshPtr msh = makeMesh("mesh1"); - - // Display the mesh - { - SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node"); - Entity *ent = mgr->createEntity("Mesh1", "mesh1"); - node->attachObject(ent); - node->setPosition(0,0,4); - } - */ -} diff --git a/components/nifogre/tests/output/ogre_manualresource_test.out b/components/nifogre/tests/output/ogre_manualresource_test.out deleted file mode 100644 index 2eab2d50dd..0000000000 --- a/components/nifogre/tests/output/ogre_manualresource_test.out +++ /dev/null @@ -1,3 +0,0 @@ -Manually loading mesh mesh1.mm -Manually loading mesh mesh2.mm -Manually loading mesh mesh3.mm diff --git a/components/nifogre/tests/output/ogre_nif_test.out b/components/nifogre/tests/output/ogre_nif_test.out deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/nifogre/tests/output/ogre_skeleton_test.out b/components/nifogre/tests/output/ogre_skeleton_test.out deleted file mode 100644 index ce01362503..0000000000 --- a/components/nifogre/tests/output/ogre_skeleton_test.out +++ /dev/null @@ -1 +0,0 @@ -hello diff --git a/components/nifogre/tests/plugins.cfg b/components/nifogre/tests/plugins.cfg deleted file mode 100644 index 9133aec32d..0000000000 --- a/components/nifogre/tests/plugins.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# Defines plugins to load - -# Define plugin folder -PluginFolder=/usr/local/lib/OGRE - -# Define plugins -Plugin=RenderSystem_GL -Plugin=Plugin_ParticleFX -Plugin=Plugin_OctreeSceneManager - - - diff --git a/components/nifogre/tests/test.sh b/components/nifogre/tests/test.sh deleted file mode 100755 index 2d07708adc..0000000000 --- a/components/nifogre/tests/test.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -make || exit - -mkdir -p output - -PROGS=*_test - -for a in $PROGS; do - if [ -f "output/$a.out" ]; then - echo "Running $a:" - ./$a | diff output/$a.out - - else - echo "Creating $a.out" - ./$a > "output/$a.out" - git add "output/$a.out" - fi -done From d4aeb177f9c63377fcf5eb2788ce4e5af9d3651b Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Jan 2014 10:47:56 +0100 Subject: [PATCH 138/168] Remove unused btKinematicCharacterController --- CMakeLists.txt | 2 - .../bullet/btKinematicCharacterController.cpp | 643 ------------------ .../bullet/btKinematicCharacterController.h | 168 ----- libs/openengine/bullet/physic.cpp | 1 - 4 files changed, 814 deletions(-) delete mode 100644 libs/openengine/bullet/btKinematicCharacterController.cpp delete mode 100644 libs/openengine/bullet/btKinematicCharacterController.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cb2fd5b2d..b365e162f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,8 +93,6 @@ set(OENGINE_GUI ) set(OENGINE_BULLET - ${LIBDIR}/openengine/bullet/btKinematicCharacterController.cpp - ${LIBDIR}/openengine/bullet/btKinematicCharacterController.h ${LIBDIR}/openengine/bullet/BtOgre.cpp ${LIBDIR}/openengine/bullet/BtOgreExtras.h ${LIBDIR}/openengine/bullet/BtOgreGP.h diff --git a/libs/openengine/bullet/btKinematicCharacterController.cpp b/libs/openengine/bullet/btKinematicCharacterController.cpp deleted file mode 100644 index fc4f3278f4..0000000000 --- a/libs/openengine/bullet/btKinematicCharacterController.cpp +++ /dev/null @@ -1,643 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -#include "LinearMath/btIDebugDraw.h" -#include "BulletCollision/CollisionDispatch/btGhostObject.h" -#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" -#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" -#include "LinearMath/btDefaultMotionState.h" -#include "btKinematicCharacterController.h" - -///@todo Interact with dynamic objects, -///Ride kinematicly animated platforms properly -///Support ducking -class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback -{ -public: - btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) - { - m_me[0] = me; - count = 1; - } - - btKinematicClosestNotMeRayResultCallback (btCollisionObject* me[], int count_) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) - { - count = count_; - - for(int i = 0; i < count; i++) - m_me[i] = me[i]; - } - - virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) - { - for(int i = 0; i < count; i++) - if (rayResult.m_collisionObject == m_me[i]) - return 1.0; - - return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace); - } -protected: - btCollisionObject* m_me[10]; - int count; -}; - -class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback -{ -public: - btKinematicClosestNotMeConvexResultCallback( btCollisionObject* me, const btVector3& up, btScalar minSlopeDot ) - : btCollisionWorld::ClosestConvexResultCallback( btVector3( 0.0, 0.0, 0.0 ), btVector3( 0.0, 0.0, 0.0 ) ), - m_me( me ), m_up( up ), m_minSlopeDot( minSlopeDot ) - { - } - - virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace) - { - if( convexResult.m_hitCollisionObject == m_me ) - return btScalar( 1 ); - - btVector3 hitNormalWorld; - if( normalInWorldSpace ) - { - hitNormalWorld = convexResult.m_hitNormalLocal; - } - else - { - ///need to transform normal into worldspace - hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; - } - - // NOTE : m_hitNormalLocal is not always vertical on the ground with a capsule or a box... - - btScalar dotUp = m_up.dot(hitNormalWorld); - if( dotUp < m_minSlopeDot ) - return btScalar( 1 ); - - return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace); - } - -protected: - btCollisionObject* m_me; - const btVector3 m_up; - btScalar m_minSlopeDot; -}; - - - -btKinematicCharacterController::btKinematicCharacterController( btPairCachingGhostObject* externalGhostObject_, - btPairCachingGhostObject* internalGhostObject_, - btScalar stepHeight, - btScalar constantScale, - btScalar gravity, - btScalar fallVelocity, - btScalar jumpVelocity, - btScalar recoveringFactor ) -{ - m_upAxis = btKinematicCharacterController::Y_AXIS; - - m_walkDirection.setValue( btScalar( 0 ), btScalar( 0 ), btScalar( 0 ) ); - - m_useGhostObjectSweepTest = true; - - externalGhostObject = externalGhostObject_; - internalGhostObject = internalGhostObject_; - - m_recoveringFactor = recoveringFactor; - - m_stepHeight = stepHeight; - - m_useWalkDirection = true; // use walk direction by default, legacy behavior - m_velocityTimeInterval = btScalar( 0 ); - m_verticalVelocity = btScalar( 0 ); - m_verticalOffset = btScalar( 0 ); - - m_gravity = constantScale * gravity; - m_fallSpeed = constantScale * fallVelocity; // Terminal velocity of a sky diver in m/s. - - m_jumpSpeed = constantScale * jumpVelocity; // ? - m_wasJumping = false; - - setMaxSlope( btRadians( 45.0 ) ); - - mCollision = true; -} - - -btKinematicCharacterController::~btKinematicCharacterController () -{ -} - -void btKinematicCharacterController::setVerticalVelocity(float z) -{ - m_verticalVelocity = z; -} - -bool btKinematicCharacterController::recoverFromPenetration( btCollisionWorld* collisionWorld ) -{ - bool penetration = false; - - if(!mCollision) return penetration; - - collisionWorld->getDispatcher()->dispatchAllCollisionPairs( internalGhostObject->getOverlappingPairCache(), - collisionWorld->getDispatchInfo(), - collisionWorld->getDispatcher() ); - - btVector3 currentPosition = internalGhostObject->getWorldTransform().getOrigin(); - - btScalar maxPen = btScalar( 0 ); - - for( int i = 0; i < internalGhostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++ ) - { - m_manifoldArray.resize(0); - - btBroadphasePair* collisionPair = &internalGhostObject->getOverlappingPairCache()->getOverlappingPairArray()[i]; - - if( collisionPair->m_algorithm ) - collisionPair->m_algorithm->getAllContactManifolds( m_manifoldArray ); - - - for( int j = 0; j < m_manifoldArray.size(); j++ ) - { - btPersistentManifold* manifold = m_manifoldArray[j]; - - btScalar directionSign = manifold->getBody0() == internalGhostObject ? btScalar( -1.0 ) : btScalar( 1.0 ); - - for( int p = 0; p < manifold->getNumContacts(); p++ ) - { - const btManifoldPoint&pt = manifold->getContactPoint( p ); - if( (manifold->getBody1() == externalGhostObject && manifold->getBody0() == internalGhostObject) - ||(manifold->getBody0() == externalGhostObject && manifold->getBody1() == internalGhostObject) ) - { - } - else - { - btScalar dist = pt.getDistance(); - - if( dist < 0.0 ) - { - if( dist < maxPen ) - maxPen = dist; - - // NOTE : btScalar affects the stairs but the parkinson... - // 0.0 , the capsule can break the walls... - currentPosition += pt.m_normalWorldOnB * directionSign * dist * m_recoveringFactor; - - penetration = true; - } - } - } - - // ??? - //manifold->clearManifold(); - } - } - - btTransform transform = internalGhostObject->getWorldTransform(); - - transform.setOrigin( currentPosition ); - - internalGhostObject->setWorldTransform( transform ); - externalGhostObject->setWorldTransform( transform ); - - return penetration; -} - - -btVector3 btKinematicCharacterController::stepUp( btCollisionWorld* world, const btVector3& currentPosition, btScalar& currentStepOffset ) -{ - btVector3 targetPosition = currentPosition + getUpAxisDirections()[ m_upAxis ] * ( m_stepHeight + ( m_verticalOffset > btScalar( 0.0 ) ? m_verticalOffset : 0.0 ) ); - - //if the no collisions mode is on, no need to go any further - if(!mCollision) - { - currentStepOffset = m_stepHeight; - return targetPosition; - } - - // Retrieve the collision shape - // - btCollisionShape* collisionShape = externalGhostObject->getCollisionShape(); - btAssert( collisionShape->isConvex() ); - - btConvexShape* convexShape = ( btConvexShape* )collisionShape; - - // FIXME: Handle penetration properly - // - btTransform start; - start.setIdentity(); - start.setOrigin( currentPosition + getUpAxisDirections()[ m_upAxis ] * ( convexShape->getMargin() ) ); - - btTransform end; - end.setIdentity(); - end.setOrigin( targetPosition ); - - btKinematicClosestNotMeConvexResultCallback callback( externalGhostObject, -getUpAxisDirections()[ m_upAxis ], m_maxSlopeCosine ); - callback.m_collisionFilterGroup = externalGhostObject->getBroadphaseHandle()->m_collisionFilterGroup; - callback.m_collisionFilterMask = externalGhostObject->getBroadphaseHandle()->m_collisionFilterMask; - - // Sweep test - // - if( m_useGhostObjectSweepTest ) - externalGhostObject->convexSweepTest( convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration ); - - else - world->convexSweepTest( convexShape, start, end, callback ); - - if( callback.hasHit() ) - { - // Only modify the position if the hit was a slope and not a wall or ceiling. - // - if( callback.m_hitNormalWorld.dot(getUpAxisDirections()[m_upAxis]) > btScalar( 0.0 ) ) - { - // We moved up only a fraction of the step height - // - currentStepOffset = m_stepHeight * callback.m_closestHitFraction; - - return currentPosition.lerp( targetPosition, callback.m_closestHitFraction ); - } - - m_verticalVelocity = btScalar( 0.0 ); - m_verticalOffset = btScalar( 0.0 ); - - return currentPosition; - } - else - { - currentStepOffset = m_stepHeight; - return targetPosition; - } -} - - -///Reflect the vector d around the vector r -inline btVector3 reflect( const btVector3& d, const btVector3& r ) -{ - return d - ( btScalar( 2.0 ) * d.dot( r ) ) * r; -} - - -///Project a vector u on another vector v -inline btVector3 project( const btVector3& u, const btVector3& v ) -{ - return v * u.dot( v ); -} - - -///Helper for computing the character sliding -inline btVector3 slide( const btVector3& direction, const btVector3& planeNormal ) -{ - return direction - project( direction, planeNormal ); -} - - - -btVector3 slideOnCollision( const btVector3& fromPosition, const btVector3& toPosition, const btVector3& hitNormal ) -{ - btVector3 moveDirection = toPosition - fromPosition; - btScalar moveLength = moveDirection.length(); - - if( moveLength <= btScalar( SIMD_EPSILON ) ) - return toPosition; - - moveDirection.normalize(); - - btVector3 reflectDir = reflect( moveDirection, hitNormal ); - reflectDir.normalize(); - - return fromPosition + slide( reflectDir, hitNormal ) * moveLength; -} - - -btVector3 btKinematicCharacterController::stepForwardAndStrafe( btCollisionWorld* collisionWorld, const btVector3& currentPosition, const btVector3& walkMove ) -{ - // We go to ! - // - btVector3 targetPosition = currentPosition + walkMove; - - //if the no collisions mode is on, no need to go any further - if(!mCollision) return targetPosition; - - // Retrieve the collision shape - // - btCollisionShape* collisionShape = externalGhostObject->getCollisionShape(); - btAssert( collisionShape->isConvex() ); - - btConvexShape* convexShape = ( btConvexShape* )collisionShape; - - btTransform start; - start.setIdentity(); - - btTransform end; - end.setIdentity(); - - btScalar fraction = btScalar( 1.0 ); - - // This optimization scheme suffers in the corners. - // It basically jumps from a wall to another, then fails to find a new - // position (after 4 iterations here) and finally don't move at all. - // - // The stepping algorithm adds some problems with stairs. It seems - // the treads create some fake corner using capsules for collisions. - // - for( int i = 0; i < 4 && fraction > btScalar( 0.01 ); i++ ) - { - start.setOrigin( currentPosition ); - end.setOrigin( targetPosition ); - - btVector3 sweepDirNegative = currentPosition - targetPosition; - - btKinematicClosestNotMeConvexResultCallback callback( externalGhostObject, sweepDirNegative, btScalar( 0.0 ) ); - callback.m_collisionFilterGroup = externalGhostObject->getBroadphaseHandle()->m_collisionFilterGroup; - callback.m_collisionFilterMask = externalGhostObject->getBroadphaseHandle()->m_collisionFilterMask; - - if( m_useGhostObjectSweepTest ) - externalGhostObject->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration ); - - else - collisionWorld->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration ); - - if( callback.hasHit() ) - { - // Try another target position - // - targetPosition = slideOnCollision( currentPosition, targetPosition, callback.m_hitNormalWorld ); - fraction = callback.m_closestHitFraction; - } - else - - // Move to the valid target position - // - return targetPosition; - } - - // Don't move if you can't find a valid target position... - // It prevents some flickering. - // - return currentPosition; -} - - -///Handle the gravity -btScalar btKinematicCharacterController::addFallOffset( bool wasOnGround, btScalar currentStepOffset, btScalar dt ) -{ - btScalar downVelocity = ( m_verticalVelocity < 0.0 ? -m_verticalVelocity : btScalar( 0.0 ) ) * dt; - - if( downVelocity > btScalar( 0.0 ) && downVelocity < m_stepHeight && ( wasOnGround || !m_wasJumping ) ) - downVelocity = m_stepHeight; - - return currentStepOffset + downVelocity; -} - - -btVector3 btKinematicCharacterController::stepDown( btCollisionWorld* collisionWorld, const btVector3& currentPosition, btScalar currentStepOffset ) -{ - btVector3 stepDrop = getUpAxisDirections()[ m_upAxis ] * currentStepOffset; - - // Be sure we are falling from the last m_currentPosition - // It prevents some flickering - // - btVector3 targetPosition = currentPosition - stepDrop; - - //if the no collisions mode is on, no need to go any further - if(!mCollision) return targetPosition; - - btTransform start; - start.setIdentity(); - start.setOrigin( currentPosition ); - - btTransform end; - end.setIdentity(); - end.setOrigin( targetPosition ); - - btKinematicClosestNotMeConvexResultCallback callback( internalGhostObject, getUpAxisDirections()[ m_upAxis ], m_maxSlopeCosine ); - callback.m_collisionFilterGroup = internalGhostObject->getBroadphaseHandle()->m_collisionFilterGroup; - callback.m_collisionFilterMask = internalGhostObject->getBroadphaseHandle()->m_collisionFilterMask; - - // Retrieve the collision shape - // - btCollisionShape* collisionShape = internalGhostObject->getCollisionShape(); - btAssert( collisionShape->isConvex() ); - btConvexShape* convexShape = ( btConvexShape* )collisionShape; - - if( m_useGhostObjectSweepTest ) - externalGhostObject->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration ); - - else - collisionWorld->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration ); - - if( callback.hasHit() ) - { - m_verticalVelocity = btScalar( 0.0 ); - m_verticalOffset = btScalar( 0.0 ); - m_wasJumping = false; - - // We dropped a fraction of the height -> hit floor - // - return currentPosition.lerp( targetPosition, callback.m_closestHitFraction ); - } - else - - // We dropped the full height - // - return targetPosition; -} - - - -void btKinematicCharacterController::setWalkDirection( const btVector3& walkDirection ) -{ - m_useWalkDirection = true; - m_walkDirection = walkDirection; -} - - -void btKinematicCharacterController::setVelocityForTimeInterval( const btVector3& velocity, btScalar timeInterval ) -{ - m_useWalkDirection = false; - m_walkDirection = velocity; - m_velocityTimeInterval = timeInterval; -} - - -void btKinematicCharacterController::reset() -{ -} - - -void btKinematicCharacterController::warp( const btVector3& origin ) -{ - btTransform transform; - transform.setIdentity(); - transform.setOrigin( -origin ); - - externalGhostObject->setWorldTransform( transform ); - internalGhostObject->setWorldTransform( transform ); -} - - -void btKinematicCharacterController::preStep( btCollisionWorld* collisionWorld ) -{ - BT_PROFILE( "preStep" ); - - for( int i = 0; i < 4 && recoverFromPenetration ( collisionWorld ); i++ ); -} - - -void btKinematicCharacterController::playerStep( btCollisionWorld* collisionWorld, btScalar dt ) -{ - BT_PROFILE( "playerStep" ); - - if( !m_useWalkDirection && m_velocityTimeInterval <= btScalar( 0.0 ) ) - return; - - bool wasOnGround = onGround(); - - // Handle the gravity - // - m_verticalVelocity -= m_gravity * dt; - - if( m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed ) - m_verticalVelocity = m_jumpSpeed; - - if( m_verticalVelocity < 0.0 && btFabs( m_verticalVelocity ) > btFabs( m_fallSpeed ) ) - m_verticalVelocity = -btFabs( m_fallSpeed ); - - m_verticalOffset = m_verticalVelocity * dt; - - // This forced stepping up can cause problems when the character - // walks (jump in fact...) under too low ceilings. - // - btVector3 currentPosition = externalGhostObject->getWorldTransform().getOrigin(); - btScalar currentStepOffset; - - currentPosition = stepUp( collisionWorld, currentPosition, currentStepOffset ); - - // Move in the air and slide against the walls ignoring the stair steps. - // - if( m_useWalkDirection ) - currentPosition = stepForwardAndStrafe( collisionWorld, currentPosition, m_walkDirection ); - - else - { - btScalar dtMoving = ( dt < m_velocityTimeInterval ) ? dt : m_velocityTimeInterval; - m_velocityTimeInterval -= dt; - - // How far will we move while we are moving ? - // - btVector3 moveDirection = m_walkDirection * dtMoving; - - currentPosition = stepForwardAndStrafe( collisionWorld, currentPosition, moveDirection ); - } - - // Finally find the ground. - // - currentStepOffset = addFallOffset( wasOnGround, currentStepOffset, dt ); - - currentPosition = stepDown( collisionWorld, currentPosition, currentStepOffset ); - - // Apply the new position to the collision objects. - // - btTransform tranform; - tranform = externalGhostObject->getWorldTransform(); - tranform.setOrigin( currentPosition ); - - externalGhostObject->setWorldTransform( tranform ); - internalGhostObject->setWorldTransform( tranform ); -} - - -void btKinematicCharacterController::setFallSpeed( btScalar fallSpeed ) -{ - m_fallSpeed = fallSpeed; -} - - -void btKinematicCharacterController::setJumpSpeed( btScalar jumpSpeed ) -{ - m_jumpSpeed = jumpSpeed; -} - - -void btKinematicCharacterController::setMaxJumpHeight( btScalar maxJumpHeight ) -{ - m_maxJumpHeight = maxJumpHeight; -} - - -bool btKinematicCharacterController::canJump() const -{ - return onGround(); -} - - -void btKinematicCharacterController::jump() -{ - if( !canJump() ) - return; - - m_verticalVelocity = m_jumpSpeed; - m_wasJumping = true; -} - - -void btKinematicCharacterController::setGravity( btScalar gravity ) -{ - m_gravity = gravity; -} - - -btScalar btKinematicCharacterController::getGravity() const -{ - return m_gravity; -} - - -void btKinematicCharacterController::setMaxSlope( btScalar slopeRadians ) -{ - m_maxSlopeRadians = slopeRadians; - m_maxSlopeCosine = btCos( slopeRadians ); -} - - -btScalar btKinematicCharacterController::getMaxSlope() const -{ - return m_maxSlopeRadians; -} - - -bool btKinematicCharacterController::onGround() const -{ - return btFabs( m_verticalVelocity ) < btScalar( SIMD_EPSILON ) && - btFabs( m_verticalOffset ) < btScalar( SIMD_EPSILON ); -} - - -btVector3* btKinematicCharacterController::getUpAxisDirections() -{ - static btVector3 sUpAxisDirection[] = - { - btVector3( btScalar( 0.0 ), btScalar( 0.0 ), btScalar( 0.0 ) ), - btVector3( btScalar( 0.0 ), btScalar( 1.0 ), btScalar( 0.0 ) ), - btVector3( btScalar( 0.0 ), btScalar( 0.0 ), btScalar( 1.0 ) ) - }; - - return sUpAxisDirection; -} - - -void btKinematicCharacterController::debugDraw( btIDebugDraw* debugDrawer ) -{ -} diff --git a/libs/openengine/bullet/btKinematicCharacterController.h b/libs/openengine/bullet/btKinematicCharacterController.h deleted file mode 100644 index d24cd97222..0000000000 --- a/libs/openengine/bullet/btKinematicCharacterController.h +++ /dev/null @@ -1,168 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef KINEMATIC_CHARACTER_CONTROLLER_H -#define KINEMATIC_CHARACTER_CONTROLLER_H - -#include "LinearMath/btVector3.h" -#include "LinearMath/btQuickprof.h" - -#include "BulletDynamics/Character/btCharacterControllerInterface.h" - -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" - - -class btCollisionShape; -class btRigidBody; -class btCollisionWorld; -class btCollisionDispatcher; -class btPairCachingGhostObject; - -///btKinematicCharacterController is an object that supports a sliding motion in a world. -///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations. -///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user. -class btKinematicCharacterController : public btCharacterControllerInterface -{ -public: - enum UpAxis - { - X_AXIS = 0, - Y_AXIS = 1, - Z_AXIS = 2 - }; - -private: - btPairCachingGhostObject* externalGhostObject; // use this for querying collisions for sliding and move - btPairCachingGhostObject* internalGhostObject; // and this for recoreving from penetrations - - btScalar m_verticalVelocity; - btScalar m_verticalOffset; - btScalar m_fallSpeed; - btScalar m_jumpSpeed; - btScalar m_maxJumpHeight; - btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value) - btScalar m_maxSlopeCosine; // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization) - btScalar m_gravity; - btScalar m_recoveringFactor; - - btScalar m_stepHeight; - - ///this is the desired walk direction, set by the user - btVector3 m_walkDirection; - - ///keep track of the contact manifolds - btManifoldArray m_manifoldArray; - - ///Gravity attributes - bool m_wasJumping; - - bool m_useGhostObjectSweepTest; - bool m_useWalkDirection; - btScalar m_velocityTimeInterval; - - UpAxis m_upAxis; - - static btVector3* getUpAxisDirections(); - - bool recoverFromPenetration ( btCollisionWorld* collisionWorld ); - - btVector3 stepUp( btCollisionWorld* collisionWorld, const btVector3& currentPosition, btScalar& currentStepOffset ); - btVector3 stepForwardAndStrafe( btCollisionWorld* collisionWorld, const btVector3& currentPosition, const btVector3& walkMove ); - btScalar addFallOffset( bool wasJumping, btScalar currentStepOffset, btScalar dt ); - btVector3 stepDown( btCollisionWorld* collisionWorld, const btVector3& currentPosition, btScalar currentStepOffset ); - -public: - /// externalGhostObject is used for querying the collisions for sliding along the wall, - /// and internalGhostObject is used for querying the collisions for recovering from large penetrations. - /// These parameters can point on the same object. - /// Using a smaller internalGhostObject can help for removing some flickering but create some - /// stopping artefacts when sliding along stairs or small walls. - /// Don't forget to scale gravity and fallSpeed if you scale the world. - btKinematicCharacterController( btPairCachingGhostObject* externalGhostObject, - btPairCachingGhostObject* internalGhostObject, - btScalar stepHeight, - btScalar constantScale = btScalar( 1.0 ), - btScalar gravity = btScalar( 9.8 ), - btScalar fallVelocity = btScalar( 55.0 ), - btScalar jumpVelocity = btScalar( 9.8 ), - btScalar recoveringFactor = btScalar( 0.2 ) ); - - ~btKinematicCharacterController (); - - void setVerticalVelocity(float z); - - ///btActionInterface interface - virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTime ) - { - preStep( collisionWorld ); - playerStep( collisionWorld, deltaTime ); - } - - ///btActionInterface interface - void debugDraw( btIDebugDraw* debugDrawer ); - - void setUpAxis( UpAxis axis ) - { - m_upAxis = axis; - } - - /// This should probably be called setPositionIncrementPerSimulatorStep. - /// This is neither a direction nor a velocity, but the amount to - /// increment the position each simulation iteration, regardless - /// of dt. - /// This call will reset any velocity set by setVelocityForTimeInterval(). - virtual void setWalkDirection(const btVector3& walkDirection); - - /// Caller provides a velocity with which the character should move for - /// the given time period. After the time period, velocity is reset - /// to zero. - /// This call will reset any walk direction set by setWalkDirection(). - /// Negative time intervals will result in no motion. - virtual void setVelocityForTimeInterval(const btVector3& velocity, - btScalar timeInterval); - - void reset(); - void warp( const btVector3& origin ); - - void preStep( btCollisionWorld* collisionWorld ); - void playerStep( btCollisionWorld* collisionWorld, btScalar dt ); - - void setFallSpeed( btScalar fallSpeed ); - void setJumpSpeed( btScalar jumpSpeed ); - void setMaxJumpHeight( btScalar maxJumpHeight ); - bool canJump() const; - - void jump(); - - void setGravity( btScalar gravity ); - btScalar getGravity() const; - - /// The max slope determines the maximum angle that the controller can walk up. - /// The slope angle is measured in radians. - void setMaxSlope( btScalar slopeRadians ); - btScalar getMaxSlope() const; - - void setUseGhostSweepTest( bool useGhostObjectSweepTest ) - { - m_useGhostObjectSweepTest = useGhostObjectSweepTest; - } - - bool onGround() const; - - //if set to false, there will be no collision. - bool mCollision; -}; - -#endif // KINEMATIC_CHARACTER_CONTROLLER_H diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 4e80088bf7..481b99badb 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -4,7 +4,6 @@ #include #include #include "OgreRoot.h" -#include "btKinematicCharacterController.h" #include "BtOgrePG.h" #include "BtOgreGP.h" #include "BtOgreExtras.h" From 3ea1407ed330efbf96a83bf981e55884a7a8386a Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 03:56:59 +0100 Subject: [PATCH 139/168] Closes #1109: Don't reset water level when loading a plugin that does include water level records --- components/esm/loadcell.cpp | 2 -- components/esm/loadcell.hpp | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index c22c1b22b6..f6bc29ae17 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -36,8 +36,6 @@ void Cell::load(ESMReader &esm, bool saveContext) esm.getHNT(mData, "DATA", 12); - // Water level - mWater = -1; mNAM0 = 0; if (mData.mFlags & Interior) diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index 61d586b9d8..b066f497ec 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -77,6 +77,8 @@ struct Cell float mFogDensity; }; + Cell() : mWater(-1) {} + // Interior cells are indexed by this (it's the 'id'), for exterior // cells it is optional. std::string mName; From 79a6ffd21645166ce51d398178b66e95333940b5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 06:41:16 +0100 Subject: [PATCH 140/168] Closes #1107: Do not create box shapes unless the box collision flag is enabled --- components/nifbullet/bulletnifloader.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 9c4fee7a09..65f90c8c1f 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -229,9 +229,12 @@ void ManualBulletShapeLoader::handleNode(btTriangleMesh* mesh, const Nif::Node * { if(node->hasBounds) { - mShape->mBoxTranslation = node->boundPos; - mShape->mBoxRotation = node->boundRot; - mBoundingBox = new btBoxShape(getbtVector(node->boundXYZ)); + if (node->flags & Nif::NiNode::Flag_BBoxCollision) + { + mShape->mBoxTranslation = node->boundPos; + mShape->mBoxRotation = node->boundRot; + mBoundingBox = new btBoxShape(getbtVector(node->boundXYZ)); + } } else if(node->recType == Nif::RC_NiTriShape) { From 03b2e99802e9f214bb130d746796e29b35800518 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 07:06:18 +0100 Subject: [PATCH 141/168] Remove unused Combat stance --- apps/openmw/mwclass/npc.cpp | 14 -------------- apps/openmw/mwworld/class.hpp | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index ef56653975..e6e1e1892c 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -821,10 +821,6 @@ namespace MWClass stats.setMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak, force); break; - - case Combat: - - throw std::runtime_error ("combat stance not enforcable for NPCs"); } } @@ -843,12 +839,6 @@ namespace MWClass stats.setMovementFlag (MWMechanics::NpcStats::Flag_Sneak, set); break; - - case Combat: - - // Combat stance ignored for now; need to be determined based on draw state instead of - // being maunally set. - break; } } @@ -871,10 +861,6 @@ namespace MWClass return true; return stats.getMovementFlag (MWMechanics::NpcStats::Flag_Sneak); - - case Combat: - - return false; } return false; diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index c0b010eae8..a752f76a75 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -70,7 +70,7 @@ namespace MWWorld /// NPC-stances. enum Stance { - Run, Sneak, Combat + Run, Sneak }; virtual ~Class(); From 0a8c61a7fe298b9d7f75490753e4dc3031f92e85 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 07:42:51 +0100 Subject: [PATCH 142/168] Bug #1107: Reverted previous fix, which caused problems with some actors not using a box shape as expected. Instead, do not create a bounding box collision shape for hidden nodes. --- components/nifbullet/bulletnifloader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 65f90c8c1f..cdddb94d0a 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -229,7 +229,8 @@ void ManualBulletShapeLoader::handleNode(btTriangleMesh* mesh, const Nif::Node * { if(node->hasBounds) { - if (node->flags & Nif::NiNode::Flag_BBoxCollision) + // Checking for BBoxCollision flag causes issues with some actors :/ + if (!(node->flags & Nif::NiNode::Flag_Hidden)) { mShape->mBoxTranslation = node->boundPos; mShape->mBoxRotation = node->boundRot; From da3295d69c8b10142d990937ddac874a2cdf1f4a Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 07:47:21 +0100 Subject: [PATCH 143/168] Closes #1106: Move stance to CreatureStats, since creatures also have separate run/walk animations. --- apps/openmw/mwclass/npc.cpp | 73 ++----------------- apps/openmw/mwclass/npc.hpp | 10 --- apps/openmw/mwmechanics/aicombat.cpp | 8 +- apps/openmw/mwmechanics/character.cpp | 4 +- apps/openmw/mwmechanics/creaturestats.cpp | 29 +++++++- apps/openmw/mwmechanics/creaturestats.hpp | 20 +++++ .../mwmechanics/mechanicsmanagerimp.cpp | 2 +- apps/openmw/mwmechanics/npcstats.cpp | 20 +---- apps/openmw/mwmechanics/npcstats.hpp | 17 ----- apps/openmw/mwrender/renderingmanager.cpp | 2 +- apps/openmw/mwscript/controlextensions.cpp | 42 +++++------ apps/openmw/mwworld/class.cpp | 15 ---- apps/openmw/mwworld/class.hpp | 9 --- apps/openmw/mwworld/player.cpp | 4 +- 14 files changed, 88 insertions(+), 167 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e6e1e1892c..c89822843c 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -775,7 +775,7 @@ namespace MWClass } if(getCreatureStats(ptr).isDead()) return boost::shared_ptr(new MWWorld::ActionOpen(ptr, true)); - if(get(actor).getStance(actor, MWWorld::Class::Sneak)) + if(getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak)) return boost::shared_ptr(new MWWorld::ActionOpen(ptr)); // stealing if(get(ptr).getCreatureStats(ptr).isHostile()) return boost::shared_ptr(new MWWorld::FailedAction("#{sActorInCombat}")); @@ -806,66 +806,6 @@ namespace MWClass return ref->mBase->mScript; } - void Npc::setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const - { - MWMechanics::NpcStats& stats = getNpcStats (ptr); - - switch (stance) - { - case Run: - - stats.setMovementFlag (MWMechanics::NpcStats::Flag_ForceRun, force); - break; - - case Sneak: - - stats.setMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak, force); - break; - } - } - - void Npc::setStance (const MWWorld::Ptr& ptr, Stance stance, bool set) const - { - MWMechanics::NpcStats& stats = getNpcStats (ptr); - - switch (stance) - { - case Run: - - stats.setMovementFlag (MWMechanics::NpcStats::Flag_Run, set); - break; - - case Sneak: - - stats.setMovementFlag (MWMechanics::NpcStats::Flag_Sneak, set); - break; - } - } - - bool Npc::getStance (const MWWorld::Ptr& ptr, Stance stance, bool ignoreForce) const - { - MWMechanics::NpcStats& stats = getNpcStats (ptr); - - switch (stance) - { - case Run: - - if (!ignoreForce && stats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)) - return true; - - return stats.getMovementFlag (MWMechanics::NpcStats::Flag_Run); - - case Sneak: - - if (!ignoreForce && stats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)) - return true; - - return stats.getMovementFlag (MWMechanics::NpcStats::Flag_Sneak); - } - - return false; - } - float Npc::getSpeed(const MWWorld::Ptr& ptr) const { const MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -874,11 +814,14 @@ namespace MWClass const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr); + bool sneaking = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak); + bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run); + float walkSpeed = fMinWalkSpeed->getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()* (fMaxWalkSpeed->getFloat() - fMinWalkSpeed->getFloat()); walkSpeed *= 1.0f - fEncumberedMoveEffect->getFloat()*normalizedEncumbrance; walkSpeed = std::max(0.0f, walkSpeed); - if(Npc::getStance(ptr, Sneak, false)) + if(sneaking) walkSpeed *= fSneakSpeedMultiplier->getFloat(); float runSpeed = walkSpeed*(0.01f * npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified() * @@ -902,14 +845,14 @@ namespace MWClass else if(world->isSwimming(ptr)) { float swimSpeed = walkSpeed; - if(Npc::getStance(ptr, Run, false)) + if(running) swimSpeed = runSpeed; swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude; swimSpeed *= fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()* fSwimRunAthleticsMult->getFloat(); moveSpeed = swimSpeed; } - else if(Npc::getStance(ptr, Run, false) && !Npc::getStance(ptr, Sneak, false)) + else if(running && !sneaking) moveSpeed = runSpeed; else moveSpeed = walkSpeed; @@ -941,7 +884,7 @@ namespace MWClass x += mageffects.get(ESM::MagicEffect::Jump).mMagnitude * 64; x *= encumbranceTerm; - if(Npc::getStance(ptr, Run, false)) + if(ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run)) x *= fJumpRunMultiplier->getFloat(); x *= npcdata->mNpcStats.getFatigueTerm(); x -= -627.2f;/*gravity constant*/ diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 22a9632e85..9977866cdf 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -84,16 +84,6 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr - virtual void setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const; - ///< Force or unforce a stance. - - virtual void setStance (const MWWorld::Ptr& ptr, Stance stance, bool set) const; - ///< Set or unset a stance. - - virtual bool getStance (const MWWorld::Ptr& ptr, Stance stance, bool ignoreForce = false) - const; - ///< Check if a stance is active or not. - virtual float getSpeed (const MWWorld::Ptr& ptr) const; ///< Return movement speed. diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 62158fb121..42b6181434 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -40,13 +40,13 @@ namespace MWMechanics if(MWWorld::Class::get(actor).getCreatureStats(actor).getHealth().getCurrent() <= 0) return true; + actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); + if(actor.getTypeName() == typeid(ESM::NPC).name()) { - MWWorld::Class::get(actor). - MWWorld::Class::get(actor).setStance(actor, MWWorld::Class::Run,true); - MWMechanics::DrawState_ state = MWWorld::Class::get(actor).getNpcStats(actor).getDrawState(); + MWMechanics::DrawState_ state = actor.getClass().getNpcStats(actor).getDrawState(); if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) - MWWorld::Class::get(actor).getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon); + actor.getClass().getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon); //MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true); } ESM::Position pos = actor.getRefData().getPosition(); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 07859d57c5..580b71731a 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -859,8 +859,8 @@ void CharacterController::update(float duration) { 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); + bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run); + bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak); bool flying = world->isFlying(mPtr); Ogre::Vector3 vec = cls.getMovementVector(mPtr); vec.normalise(); diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index ba6f0ba047..8d37e34c83 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -15,7 +15,8 @@ namespace MWMechanics mAttacked (false), mHostile (false), mAttackingOrSpell(false), mAttackType(AT_Chop), mIsWerewolf(false), - mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mHitRecovery(false) + mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mHitRecovery(false), + mMovementFlags(0) { for (int i=0; i<4; ++i) mAiSettings[i] = 0; @@ -425,4 +426,30 @@ namespace MWMechanics { return mHitRecovery; } + + bool CreatureStats::getMovementFlag (Flag flag) const + { + return mMovementFlags & flag; + } + + void CreatureStats::setMovementFlag (Flag flag, bool state) + { + if (state) + mMovementFlags |= flag; + else + mMovementFlags &= ~flag; + } + + bool CreatureStats::getStance(Stance flag) const + { + switch (flag) + { + case Stance_Run: + return getMovementFlag (Flag_Run) || getMovementFlag (Flag_ForceRun); + case Stance_Sneak: + return getMovementFlag (Flag_Sneak) || getMovementFlag (Flag_ForceSneak); + } + return false; // shut up, compiler + } + } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 1f82a9b5c0..26856c966d 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -37,6 +37,7 @@ namespace MWMechanics bool mAttackingOrSpell; bool mKnockdown; bool mHitRecovery; + unsigned int mMovementFlags; float mFallHeight; @@ -47,6 +48,7 @@ namespace MWMechanics // Do we need to recalculate stats derived from attributes or other factors? bool mRecalcDynamicStats; + std::map mUsedPowers; protected: bool mIsWerewolf; @@ -193,6 +195,24 @@ namespace MWMechanics void setHitRecovery(bool value); bool getHitRecovery() const; + enum Flag + { + Flag_ForceRun = 1, + Flag_ForceSneak = 2, + Flag_Run = 4, + Flag_Sneak = 8 + }; + enum Stance + { + Stance_Run, + Stance_Sneak + }; + + bool getMovementFlag (Flag flag) const; + void setMovementFlag (Flag flag, bool state); + /// Like getMovementFlag, but also takes into account if the flag is Forced + bool getStance (Stance flag) const; + void setLastHitObject(const std::string &objectid); const std::string &getLastHitObject() const; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 79a038dffe..4514c077c7 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -896,7 +896,7 @@ namespace MWMechanics return false; float sneakTerm = 0; - if (ptr.getClass().getStance(ptr, MWWorld::Class::Sneak) + if (ptr.getClass().getCreatureStats(ptr).getStance(CreatureStats::Stance_Sneak) && !MWBase::Environment::get().getWorld()->isSwimming(ptr) && MWBase::Environment::get().getWorld()->isOnGround(ptr)) { diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index f77b042716..293b078da0 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -22,8 +22,7 @@ #include "../mwbase/soundmanager.hpp" MWMechanics::NpcStats::NpcStats() -: mMovementFlags (0) -, mDrawState (DrawState_Nothing) +: mDrawState (DrawState_Nothing) , mBounty (0) , mLevelProgress(0) , mDisposition(0) @@ -34,9 +33,7 @@ MWMechanics::NpcStats::NpcStats() , mTimeToStartDrowning(20.0) , mLastDrowningHit(0) { - mSkillIncreases.resize (ESM::Attribute::Length); - for (int i=0; i=ESM::Skill::Length) diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 5fd358c858..b89a2b4b39 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -25,18 +25,6 @@ namespace MWMechanics class NpcStats : public CreatureStats { - public: - - enum Flag - { - Flag_ForceRun = 1, - Flag_ForceSneak = 2, - Flag_Run = 4, - Flag_Sneak = 8 - }; - - private: - /// NPCs other than the player can only have one faction. But for the sake of consistency /// we use the same data structure for the PC and the NPCs. /// \note the faction key must be in lowercase @@ -44,7 +32,6 @@ namespace MWMechanics DrawState_ mDrawState; int mDisposition; - unsigned int mMovementFlags; SkillValue mSkill[27]; SkillValue mWerewolfSkill[27]; int mBounty; @@ -89,10 +76,6 @@ namespace MWMechanics void setReputation(int reputation); - bool getMovementFlag (Flag flag) const; - - void setMovementFlag (Flag flag, bool state); - const SkillValue& getSkill (int index) const; SkillValue& getSkill (int index); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 0c5e053c9e..47cf3ee41b 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -347,7 +347,7 @@ void RenderingManager::update (float duration, bool paused) } // Sink the camera while sneaking - bool isSneaking = MWWorld::Class::get(player).getStance(player, MWWorld::Class::Sneak); + bool isSneaking = player.getClass().getCreatureStats(player).getStance(MWMechanics::CreatureStats::Stance_Sneak); bool isInAir = !world->isOnGround(player); bool isSwimming = world->isSwimming(player); diff --git a/apps/openmw/mwscript/controlextensions.cpp b/apps/openmw/mwscript/controlextensions.cpp index 7697ab6199..d2e7748598 100644 --- a/apps/openmw/mwscript/controlextensions.cpp +++ b/apps/openmw/mwscript/controlextensions.cpp @@ -76,34 +76,34 @@ namespace MWScript template class OpClearMovementFlag : public Interpreter::Opcode0 { - MWMechanics::NpcStats::Flag mFlag; + MWMechanics::CreatureStats::Flag mFlag; public: - OpClearMovementFlag (MWMechanics::NpcStats::Flag flag) : mFlag (flag) {} + OpClearMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {} virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); - MWWorld::Class::get (ptr).getNpcStats (ptr).setMovementFlag (mFlag, false); + ptr.getClass().getCreatureStats(ptr).setMovementFlag (mFlag, false); } }; template class OpSetMovementFlag : public Interpreter::Opcode0 { - MWMechanics::NpcStats::Flag mFlag; + MWMechanics::CreatureStats::Flag mFlag; public: - OpSetMovementFlag (MWMechanics::NpcStats::Flag flag) : mFlag (flag) {} + OpSetMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {} virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); - MWWorld::Class::get (ptr).getNpcStats (ptr).setMovementFlag (mFlag, true); + ptr.getClass().getCreatureStats(ptr).setMovementFlag (mFlag, true); } }; @@ -116,9 +116,8 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWMechanics::NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats (ptr); - - runtime.push (npcStats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); + runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); } }; @@ -131,9 +130,8 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWMechanics::NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats (ptr); - - runtime.push (npcStats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); } }; @@ -144,7 +142,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - runtime.push (MWWorld::Class::get(ptr).getStance (ptr, MWWorld::Class::Run)); + runtime.push (ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run)); } }; @@ -155,7 +153,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - runtime.push (MWWorld::Class::get(ptr).getStance (ptr, MWWorld::Class::Sneak)); + runtime.push (ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak)); } }; @@ -172,22 +170,22 @@ namespace MWScript interpreter.installSegment5 (Compiler::Control::opcodeToggleCollision, new OpToggleCollision); interpreter.installSegment5 (Compiler::Control::opcodeClearForceRun, - new OpClearMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + new OpClearMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); interpreter.installSegment5 (Compiler::Control::opcodeForceRun, - new OpSetMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + new OpSetMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneak, - new OpClearMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + new OpClearMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); interpreter.installSegment5 (Compiler::Control::opcodeForceSneak, - new OpSetMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + new OpSetMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); interpreter.installSegment5 (Compiler::Control::opcodeClearForceRunExplicit, - new OpClearMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + new OpClearMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); interpreter.installSegment5 (Compiler::Control::opcodeForceRunExplicit, - new OpSetMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + new OpSetMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneakExplicit, - new OpClearMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + new OpClearMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); interpreter.installSegment5 (Compiler::Control::opcodeForceSneakExplicit, - new OpSetMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + new OpSetMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); interpreter.installSegment5 (Compiler::Control::opcodeGetPcRunning, new OpGetPcRunning); interpreter.installSegment5 (Compiler::Control::opcodeGetPcSneaking, new OpGetPcSneaking); interpreter.installSegment5 (Compiler::Control::opcodeGetForceRun, new OpGetForceRun); diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 934dae015f..07bd905717 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -147,21 +147,6 @@ namespace MWWorld return ""; } - void Class::setForceStance (const Ptr& ptr, Stance stance, bool force) const - { - throw std::runtime_error ("stance not supported by class"); - } - - void Class::setStance (const Ptr& ptr, Stance stance, bool set) const - { - throw std::runtime_error ("stance not supported by class"); - } - - bool Class::getStance (const Ptr& ptr, Stance stance, bool ignoreForce) const - { - return false; - } - float Class::getSpeed (const Ptr& ptr) const { return 0; diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index a752f76a75..5c1c063a34 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -168,15 +168,6 @@ namespace MWWorld ///< Return name of the script attached to ptr (default implementation: return an empty /// string). - virtual void setForceStance (const Ptr& ptr, Stance stance, bool force) const; - ///< Force or unforce a stance. - - virtual void setStance (const Ptr& ptr, Stance stance, bool set) const; - ///< Set or unset a stance. - - virtual bool getStance (const Ptr& ptr, Stance stance, bool ignoreForce = false) const; - ///< Check if a stance is active or not. - virtual float getSpeed (const Ptr& ptr) const; ///< Return movement speed. diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index c594454028..3ea6c62f89 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -114,14 +114,14 @@ namespace MWWorld void Player::setRunState(bool run) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get(ptr).setStance(ptr, MWWorld::Class::Run, run); + ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, run); } void Player::setSneak(bool sneak) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Sneak, sneak); + ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak); // TODO show sneak indicator only when the player is not detected by any actor MWBase::Environment::get().getWindowManager()->setSneakVisibility(sneak); From dff67bb0b6b7a16c8fb8cae05ad4eae1b2285210 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 08:16:44 +0100 Subject: [PATCH 144/168] StopCombat: mark as non-hostile --- apps/openmw/mwscript/aiextensions.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 7d05627671..09b1ed4477 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -451,6 +451,7 @@ namespace MWScript MWWorld::Ptr actor = R()(runtime); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); creatureStats.getAiSequence().stopCombat(); + creatureStats.setHostile(false); } }; From 28a2585106af29d510e709c3cce2704d5ada0c80 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 08:44:35 +0100 Subject: [PATCH 145/168] Unsheath weapon in AiWander --- apps/openmw/mwmechanics/aiwander.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 915595c25d..bf6c1dc38e 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -6,6 +6,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwmechanics/npcstats.hpp" #include @@ -64,6 +65,8 @@ namespace MWMechanics bool AiWander::execute (const MWWorld::Ptr& actor,float duration) { + if (actor.getClass().isNpc()) + actor.getClass().getNpcStats(actor).setDrawState(DrawState_Nothing); MWBase::World *world = MWBase::Environment::get().getWorld(); if(mDuration) { From 7534fc968dcdee874377826a1a475dbb74f12d71 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 12:08:12 +0100 Subject: [PATCH 146/168] Minor acrobatics fixes --- apps/openmw/mwmechanics/character.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 580b71731a..39c4219079 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1017,14 +1017,16 @@ void CharacterController::update(float duration) cls.getCreatureStats(mPtr).setHealth(health); cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), true); - // report acrobatics progression - if (mPtr.getRefData().getHandle() == "player") - cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); - const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified(); if (healthLost > (acrobaticsSkill * fatigueTerm)) { - //TODO: actor falls over + cls.getCreatureStats(mPtr).setKnockedDown(true); + } + else + { + // report acrobatics progression + if (mPtr.getRefData().getHandle() == "player") + cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); } } } From d544551f61f51605d59ddc0bc1bbefbb320dcaa0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 15:50:45 +0100 Subject: [PATCH 147/168] Added getSkill to Class interface, since creatures also have skills (which are provided by generalized Combat, Magic and Stealth attributes which substitute for the specific skills, in the same way as specialization) Information provided by Hrnchamd. --- apps/openmw/mwclass/creature.cpp | 20 +++++++++++++++++++ apps/openmw/mwclass/creature.hpp | 2 ++ apps/openmw/mwclass/npc.cpp | 5 +++++ apps/openmw/mwclass/npc.hpp | 2 ++ apps/openmw/mwgui/pickpocketitemmodel.cpp | 2 +- apps/openmw/mwgui/tradewindow.cpp | 4 ++-- apps/openmw/mwmechanics/character.cpp | 2 +- .../mwmechanics/mechanicsmanagerimp.cpp | 11 ++-------- apps/openmw/mwmechanics/pickpocket.cpp | 5 ++--- apps/openmw/mwmechanics/spellcasting.hpp | 11 +++++----- apps/openmw/mwscript/statsextensions.cpp | 4 +--- apps/openmw/mwworld/class.cpp | 5 +++++ apps/openmw/mwworld/class.hpp | 2 ++ apps/openmw/mwworld/inventorystore.cpp | 16 +++++++-------- components/esm/loadcrea.hpp | 4 +++- 15 files changed, 60 insertions(+), 35 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 480c335c2a..ac8f85d134 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -461,6 +461,26 @@ namespace MWClass throw std::runtime_error(std::string("Unexpected soundgen type: ")+name); } + int Creature::getSkill(const MWWorld::Ptr &ptr, int skill) const + { + MWWorld::LiveCellRef *ref = + ptr.get(); + + const ESM::Skill* skillRecord = MWBase::Environment::get().getWorld()->getStore().get().find(skill); + + switch (skillRecord->mData.mSpecialization) + { + case ESM::Class::Combat: + return ref->mBase->mData.mCombat; + case ESM::Class::Magic: + return ref->mBase->mData.mMagic; + case ESM::Class::Stealth: + return ref->mBase->mData.mStealth; + default: + throw std::runtime_error("invalid specialisation"); + } + } + const ESM::GameSetting* Creature::fMinWalkSpeedCreature; const ESM::GameSetting* Creature::fMaxWalkSpeedCreature; } diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 34e19ebdc7..461410a491 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -101,6 +101,8 @@ namespace MWClass } virtual bool isFlying (const MWWorld::Ptr &ptr) const; + + virtual int getSkill(const MWWorld::Ptr &ptr, int skill) const; }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index c89822843c..8d51fd1cf9 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1211,6 +1211,11 @@ namespace MWClass return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell); } + int Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const + { + return ptr.getClass().getNpcStats(ptr).getSkill(skill).getModified(); + } + const ESM::GameSetting *Npc::fMinWalkSpeed; const ESM::GameSetting *Npc::fMaxWalkSpeed; const ESM::GameSetting *Npc::fEncumberedMoveEffect; diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 9977866cdf..b729d01514 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -140,6 +140,8 @@ namespace MWClass virtual std::string getModel(const MWWorld::Ptr &ptr) const; + virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const; + virtual bool isActor() const { return true; } diff --git a/apps/openmw/mwgui/pickpocketitemmodel.cpp b/apps/openmw/mwgui/pickpocketitemmodel.cpp index 13ee4396d0..0196bf02d3 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.cpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.cpp @@ -9,7 +9,7 @@ namespace MWGui PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel) { mSourceModel = sourceModel; - int chance = MWWorld::Class::get(thief).getNpcStats(thief).getSkill(ESM::Skill::Sneak).getModified(); + int chance = thief.getClass().getSkill(thief, ESM::Skill::Sneak); mSourceModel->update(); for (size_t i = 0; igetItemCount(); ++i) diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 14024dec6b..f86044841a 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -296,10 +296,10 @@ namespace MWGui const MWMechanics::NpcStats &sellerStats = mPtr.getClass().getNpcStats(mPtr); const MWMechanics::NpcStats &playerStats = player.getClass().getNpcStats(player); - float a1 = std::min(playerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100); + float a1 = std::min(player.getClass().getSkill(player, ESM::Skill::Mercantile), 100); float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); float c1 = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); - float d1 = std::min(sellerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100); + float d1 = std::min(mPtr.getClass().getSkill(mPtr, ESM::Skill::Mercantile), 100); float e1 = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 39c4219079..5104a0f57f 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1017,7 +1017,7 @@ void CharacterController::update(float duration) cls.getCreatureStats(mPtr).setHealth(health); cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), true); - const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified(); + const float acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics); if (healthLost > (acrobaticsSkill * fatigueTerm)) { cls.getCreatureStats(mPtr).setKnockedDown(true); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 4514c077c7..0dee4706aa 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -902,12 +902,7 @@ namespace MWMechanics { static float fSneakSkillMult = store.find("fSneakSkillMult")->getFloat(); static float fSneakBootMult = store.find("fSneakBootMult")->getFloat(); - float sneak = 0; - // TODO: According to Hrnchamd Research:Movement, "Creatures have generalized combat, magic and stealth - // stats which substitute for the specific skills (in the same way as specializations)." - // This probably applies to a large part of the code base. - if (ptr.getClass().isNpc()) - sneak = ptr.getClass().getNpcStats(ptr).getSkill(ESM::Skill::Sneak).getModified(); + float sneak = ptr.getClass().getSkill(ptr, ESM::Skill::Sneak); int agility = stats.getAttribute(ESM::Attribute::Agility).getModified(); int luck = stats.getAttribute(ESM::Attribute::Luck).getModified(); float bootWeight = 0; @@ -935,9 +930,7 @@ namespace MWMechanics int obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified(); int obsLuck = observerStats.getAttribute(ESM::Attribute::Luck).getModified(); float obsBlind = observerStats.getMagicEffects().get(ESM::MagicEffect::Blind).mMagnitude; - int obsSneak = 0; - if (observer.getClass().isNpc()) - obsSneak = observer.getClass().getNpcStats(observer).getSkill(ESM::Skill::Sneak).getModified(); + int obsSneak = observer.getClass().getSkill(observer, ESM::Skill::Sneak); float obsTerm = obsSneak + 0.2 * obsAgility + 0.1 * obsLuck - obsBlind; diff --git a/apps/openmw/mwmechanics/pickpocket.cpp b/apps/openmw/mwmechanics/pickpocket.cpp index 8e8a70d885..53681caf8b 100644 --- a/apps/openmw/mwmechanics/pickpocket.cpp +++ b/apps/openmw/mwmechanics/pickpocket.cpp @@ -19,7 +19,7 @@ namespace MWMechanics NpcStats& stats = ptr.getClass().getNpcStats(ptr); float agility = stats.getAttribute(ESM::Attribute::Agility).getModified(); float luck = stats.getAttribute(ESM::Attribute::Luck).getModified(); - float sneak = stats.getSkill(ESM::Skill::Sneak).getModified(); + float sneak = ptr.getClass().getSkill(ptr, ESM::Skill::Sneak); return (add + 0.2 * agility + 0.1 * luck + sneak) * stats.getFatigueTerm(); } @@ -30,8 +30,7 @@ namespace MWMechanics float t = 2*x - y; - NpcStats& pcStats = mThief.getClass().getNpcStats(mThief); - float pcSneak = pcStats.getSkill(ESM::Skill::Sneak).getModified(); + float pcSneak = mThief.getClass().getSkill(mThief, ESM::Skill::Sneak); int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get() .find("iPickMinChance")->getInt(); int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get() diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index a1ae254f61..52af26ad13 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -16,9 +16,9 @@ namespace MWMechanics { - inline int spellSchoolToSkill(int school) + inline ESM::Skill::SkillEnum spellSchoolToSkill(int school) { - std::map schoolSkillMap; // maps spell school to skill id + std::map schoolSkillMap; // maps spell school to skill id schoolSkillMap[0] = ESM::Skill::Alteration; schoolSkillMap[1] = ESM::Skill::Conjuration; schoolSkillMap[3] = ESM::Skill::Illusion; @@ -38,10 +38,9 @@ namespace MWMechanics */ inline float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool = NULL) { - NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor); - CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + CreatureStats& stats = actor.getClass().getCreatureStats(actor); - if (creatureStats.getMagicEffects().get(ESM::MagicEffect::Silence).mMagnitude) + if (stats.getMagicEffects().get(ESM::MagicEffect::Silence).mMagnitude) return 0; float y = FLT_MAX; @@ -63,7 +62,7 @@ namespace MWMechanics "fEffectCostMult")->getFloat(); x *= fEffectCostMult; - float s = 2 * stats.getSkill(spellSchoolToSkill(magicEffect->mData.mSchool)).getModified(); + float s = 2 * actor.getClass().getSkill(actor, spellSchoolToSkill(magicEffect->mData.mSchool)); if (s - x < y) { y = s - x; diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 095fad7ab5..7a59e96893 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -306,9 +306,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = - MWWorld::Class::get (ptr).getNpcStats (ptr).getSkill (mIndex). - getModified(); + Interpreter::Type_Integer value = ptr.getClass().getSkill(ptr, mIndex); runtime.push (value); } diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 07bd905717..f3128780b8 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -358,4 +358,9 @@ namespace MWWorld return false; } + int Class::getSkill(const MWWorld::Ptr& ptr, int skill) const + { + throw std::runtime_error("class does not support skills"); + } + } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 5c1c063a34..bbc74323cb 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -294,6 +294,8 @@ namespace MWWorld virtual bool isFlying(const MWWorld::Ptr& ptr) const; + virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const; + static const Class& get (const std::string& key); ///< If there is no class for this \a key, an exception is thrown. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index e8938b2c0e..82b827e755 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -164,8 +164,6 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) { - const MWMechanics::NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor); - TSlots slots_; initSlots (slots_); @@ -190,10 +188,10 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) !actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion"))) continue; - int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test); + int testSkill = test.getClass().getEquipmentSkill (test); std::pair, bool> itemsSlots = - MWWorld::Class::get (*iter).getEquipmentSlots (*iter); + iter->getClass().getEquipmentSlots (*iter); for (std::vector::const_iterator iter2 (itemsSlots.first.begin()); iter2!=itemsSlots.first.end(); ++iter2) @@ -210,16 +208,16 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) { // check skill int oldSkill = - MWWorld::Class::get (old).getEquipmentSkill (old); + old.getClass().getEquipmentSkill (old); if (testSkill!=-1 && oldSkill==-1) use = true; else if (testSkill!=-1 && oldSkill!=-1 && testSkill!=oldSkill) { - if (stats.getSkill (oldSkill).getModified()>stats.getSkill (testSkill).getModified()) + if (actor.getClass().getSkill(actor, oldSkill) > actor.getClass().getSkill (actor, testSkill)) continue; // rejected, because old item better matched the NPC's skills. - if (stats.getSkill (oldSkill).getModified()= - MWWorld::Class::get (test).getValue (test)) + if (old.getClass().getValue (old)>= + test.getClass().getValue (test)) { continue; } diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index b5ea495081..c0523025bd 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -63,7 +63,9 @@ struct Creature int mHealth, mMana, mFatigue; // Stats int mSoul; // The creatures soul value (used with soul gems.) - int mCombat, mMagic, mStealth; // Don't know yet. + // Creatures have generalized combat, magic and stealth stats which substitute for + // the specific skills (in the same way as specializations). + int mCombat, mMagic, mStealth; int mAttack[6]; // AttackMin1, AttackMax1, ditto2, ditto3 int mGold; }; // 96 byte From ea8f60eddf614c04330a5befdf310a98eea28c6a Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 16:30:16 +0100 Subject: [PATCH 148/168] Implement movement speed formula for creatures. Still moving a bit too slow. --- apps/openmw/mwclass/creature.cpp | 62 ++++++++++++++++++++++++++++++-- apps/openmw/mwclass/creature.hpp | 8 +++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index ac8f85d134..a18df6d9f6 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -61,6 +61,14 @@ namespace MWClass fMinWalkSpeedCreature = gmst.find("fMinWalkSpeedCreature"); fMaxWalkSpeedCreature = gmst.find("fMaxWalkSpeedCreature"); + fEncumberedMoveEffect = gmst.find("fEncumberedMoveEffect"); + fSneakSpeedMultiplier = gmst.find("fSneakSpeedMultiplier"); + fAthleticsRunBonus = gmst.find("fAthleticsRunBonus"); + fBaseRunMultiplier = gmst.find("fBaseRunMultiplier"); + fMinFlySpeed = gmst.find("fMinFlySpeed"); + fMaxFlySpeed = gmst.find("fMaxFlySpeed"); + fSwimRunBase = gmst.find("fSwimRunBase"); + fSwimRunAthleticsMult = gmst.find("fSwimRunAthleticsMult"); inited = true; } @@ -286,10 +294,51 @@ namespace MWClass float Creature::getSpeed(const MWWorld::Ptr &ptr) const { MWMechanics::CreatureStats& stats = getCreatureStats(ptr); + float walkSpeed = fMinWalkSpeedCreature->getFloat() + 0.01 * stats.getAttribute(ESM::Attribute::Speed).getModified() * (fMaxWalkSpeedCreature->getFloat() - fMinWalkSpeedCreature->getFloat()); - /// \todo what about the rest? - return walkSpeed; + + const MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects(); + + const float normalizedEncumbrance = 0; //getEncumbrance(ptr) / getCapacity(ptr); + + bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run); + + float runSpeed = walkSpeed*(0.01f * getSkill(ptr, ESM::Skill::Athletics) * + fAthleticsRunBonus->getFloat() + fBaseRunMultiplier->getFloat()); + + float moveSpeed; + if(normalizedEncumbrance >= 1.0f) + moveSpeed = 0.0f; + else if(mageffects.get(ESM::MagicEffect::Levitate).mMagnitude > 0 && + world->isLevitationEnabled()) + { + float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() + + mageffects.get(ESM::MagicEffect::Levitate).mMagnitude); + flySpeed = fMinFlySpeed->getFloat() + flySpeed*(fMaxFlySpeed->getFloat() - fMinFlySpeed->getFloat()); + flySpeed *= 1.0f - fEncumberedMoveEffect->getFloat() * normalizedEncumbrance; + flySpeed = std::max(0.0f, flySpeed); + moveSpeed = flySpeed; + } + else if(world->isSwimming(ptr)) + { + float swimSpeed = walkSpeed; + if(running) + swimSpeed = runSpeed; + swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude; + swimSpeed *= fSwimRunBase->getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics) * + fSwimRunAthleticsMult->getFloat(); + moveSpeed = swimSpeed; + } + else if(running) + moveSpeed = runSpeed; + else + moveSpeed = walkSpeed; + if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0) + moveSpeed *= 0.75f; + + return moveSpeed; } MWMechanics::Movement& Creature::getMovementSettings (const MWWorld::Ptr& ptr) const @@ -483,4 +532,13 @@ namespace MWClass const ESM::GameSetting* Creature::fMinWalkSpeedCreature; const ESM::GameSetting* Creature::fMaxWalkSpeedCreature; + const ESM::GameSetting *Creature::fEncumberedMoveEffect; + const ESM::GameSetting *Creature::fSneakSpeedMultiplier; + const ESM::GameSetting *Creature::fAthleticsRunBonus; + const ESM::GameSetting *Creature::fBaseRunMultiplier; + const ESM::GameSetting *Creature::fMinFlySpeed; + const ESM::GameSetting *Creature::fMaxFlySpeed; + const ESM::GameSetting *Creature::fSwimRunBase; + const ESM::GameSetting *Creature::fSwimRunAthleticsMult; + } diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 461410a491..7d2f95fae0 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -16,6 +16,14 @@ namespace MWClass static const ESM::GameSetting *fMinWalkSpeedCreature; static const ESM::GameSetting *fMaxWalkSpeedCreature; + static const ESM::GameSetting *fEncumberedMoveEffect; + static const ESM::GameSetting *fSneakSpeedMultiplier; + static const ESM::GameSetting *fAthleticsRunBonus; + static const ESM::GameSetting *fBaseRunMultiplier; + static const ESM::GameSetting *fMinFlySpeed; + static const ESM::GameSetting *fMaxFlySpeed; + static const ESM::GameSetting *fSwimRunBase; + static const ESM::GameSetting *fSwimRunAthleticsMult; public: From 278876d6fb9df8ae1d48063647af508b87d06213 Mon Sep 17 00:00:00 2001 From: nobrakal Date: Thu, 16 Jan 2014 08:41:29 +0100 Subject: [PATCH 149/168] Update opencs.desktop Fix bad output of desktop-file-validate for opencs.dektop --- files/opencs.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/opencs.desktop b/files/opencs.desktop index 80afa26bce..638de6ebf4 100644 --- a/files/opencs.desktop +++ b/files/opencs.desktop @@ -3,7 +3,7 @@ Type=Application Name=OpenMW Content Editor GenericName=Content Editor Comment=A replacement for the Morrowind Construction Set. -Keywords=Morrowind;Construction Set;Creation Kit Editor;Set;Kit +Keywords=Morrowind;Construction Set;Creation Kit Editor;Set;Kit; TryExec=opencs Exec=opencs Icon=opencs From e638b8b8cbeb5bdbc57cb01ba8526f426d3ef70b Mon Sep 17 00:00:00 2001 From: nobrakal Date: Thu, 16 Jan 2014 08:44:56 +0100 Subject: [PATCH 150/168] Update openmw.desktop Fix bad output of desktop-file-validate for openmw.dektop --- files/openmw.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/openmw.desktop b/files/openmw.desktop index 3e26018d0c..4a3a76f52d 100644 --- a/files/openmw.desktop +++ b/files/openmw.desktop @@ -3,7 +3,7 @@ Type=Application Name=OpenMW Launcher GenericName=Role Playing Game Comment=An engine replacement for The Elder Scrolls III: Morrowind -Keywords=Morrowind;Reimplementation Mods;esm;bsa +Keywords=Morrowind;Reimplementation Mods;esm;bsa; TryExec=omwlauncher Exec=omwlauncher Icon=openmw From ddf72c06deb64c89622b2483ebdb92c4effbe3f6 Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Thu, 16 Jan 2014 12:09:50 +0100 Subject: [PATCH 151/168] Update statswindow.cpp Fixes a build issue on MSVC ('floor' : ambiguous call to overloaded function) --- apps/openmw/mwgui/statswindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 37128c43f3..40eb2d3b15 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -186,7 +186,7 @@ namespace MWGui if (widget) { int modified = value.getModified(), base = value.getBase(); - std::string text = boost::lexical_cast(std::floor(modified)); + std::string text = boost::lexical_cast(modified); std::string state = "normal"; if (modified > base) state = "increased"; From f070d9966db366d5c4364d0dc95f102cae20d3d5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Jan 2014 16:30:16 +0100 Subject: [PATCH 152/168] Implement movement speed formula for creatures. Still moving a bit too slow. --- apps/openmw/mwclass/creature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index a18df6d9f6..f2a4f9ccde 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -301,7 +301,7 @@ namespace MWClass const MWBase::World *world = MWBase::Environment::get().getWorld(); const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects(); - const float normalizedEncumbrance = 0; //getEncumbrance(ptr) / getCapacity(ptr); + const float normalizedEncumbrance = getEncumbrance(ptr) / getCapacity(ptr); bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run); From fe66012bcda70a3d1f61bdf726f9b6abc5133ee4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 16 Jan 2014 06:57:50 +0100 Subject: [PATCH 153/168] Closes #1115: Fix a bug causing number of AI packages to grow exponentially when adding an AI package. Not sure if adding the same package twice should even be allowed. --- apps/openmw/mwmechanics/aisequence.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index 79a953e385..73caa6ca76 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -109,7 +109,10 @@ void MWMechanics::AiSequence::stack (const AiPackage& package) for(std::list::iterator it = mPackages.begin(); it != mPackages.end(); it++) { if(mPackages.front()->getPriority() <= package.getPriority()) + { mPackages.insert(it,package.clone()); + return; + } } if(mPackages.empty()) From 2836c7c927ede12d6d993831fae3410ba07c7449 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 16 Jan 2014 07:11:34 +0100 Subject: [PATCH 154/168] Do not set owner when adding items to a container, as opposed to NPC/creatures --- apps/openmw/mwworld/containerstore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 154fa1999d..0c4226f9bf 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -149,7 +149,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr item.getCellRef().mPos.pos[1] = 0; item.getCellRef().mPos.pos[2] = 0; - if (setOwner) + if (setOwner && actorPtr.getClass().isActor()) item.getCellRef().mOwner = actorPtr.getCellRef().mRefID; std::string script = MWWorld::Class::get(item).getScript(item); From e410eb527310b8ca13a121248e1f09e3f77a5081 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 16 Jan 2014 13:49:26 +0100 Subject: [PATCH 155/168] Play 'Idle' voiced dialogue entries in AIWander. Tweak voice max distance. --- apps/openmw/mwmechanics/aiwander.cpp | 9 +++++++++ apps/openmw/mwsound/soundmanagerimp.cpp | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index bf6c1dc38e..853d0ff7b7 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -6,6 +6,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/dialoguemanager.hpp" #include "../mwmechanics/npcstats.hpp" #include @@ -185,6 +186,14 @@ namespace MWMechanics playIdle(actor, mPlayedIdle); mChooseAction = false; mIdleNow = true; + + // Play idle voiced dialogue entries randomly + const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + float chance = store.get().find("fVoiceIdleOdds")->getFloat(); + int roll = std::rand()/ (static_cast (RAND_MAX) + 1) * 100; // [0, 99] + // TODO: do not show subtitle messagebox if player is too far away? or do not say at all? + if (roll < chance) + MWBase::Environment::get().getDialogueManager()->say(actor, "idle"); } } diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index a7ee968314..bdd03a8b46 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -248,14 +248,13 @@ namespace MWSound return; try { - // The range values are not tested float basevol = volumeFromType(Play_TypeVoice); std::string filePath = "Sound/"+filename; const ESM::Position &pos = ptr.getRefData().getPosition(); const Ogre::Vector3 objpos(pos.pos); MWBase::SoundPtr sound = mOutput->playSound3D(filePath, objpos, 1.0f, basevol, 1.0f, - 20.0f, 12750.0f, Play_Normal|Play_TypeVoice, 0); + 20.0f, 1500.0f, Play_Normal|Play_TypeVoice, 0); mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound")); } catch(std::exception &e) From ddc432c7ef8c49c6d380ce7b229ab27c098f1c53 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 06:18:37 +0100 Subject: [PATCH 156/168] Fix stealing bug --- apps/openmw/mwclass/npc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 8d51fd1cf9..57de523386 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -775,10 +775,10 @@ namespace MWClass } if(getCreatureStats(ptr).isDead()) return boost::shared_ptr(new MWWorld::ActionOpen(ptr, true)); - if(getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak)) - return boost::shared_ptr(new MWWorld::ActionOpen(ptr)); // stealing if(get(ptr).getCreatureStats(ptr).isHostile()) return boost::shared_ptr(new MWWorld::FailedAction("#{sActorInCombat}")); + if(getCreatureStats(actor).getStance(MWMechanics::CreatureStats::Stance_Sneak)) + return boost::shared_ptr(new MWWorld::ActionOpen(ptr)); // stealing return boost::shared_ptr(new MWWorld::ActionTalk(ptr)); } From 11394d83c5006efe11c1a43484f532dec25938ee Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 08:54:24 +0100 Subject: [PATCH 157/168] Feature #1086: Import blood models/textures in MWIniImporter --- apps/mwiniimporter/importer.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index cf15891144..648ab3ebee 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -623,6 +623,17 @@ MwIniImporter::MwIniImporter() "Moons:Masser Fade Out Finish", "Moons:Script Color", + // blood + "Blood:Model 0", + "Blood:Model 1", + "Blood:Model 2", + "Blood:Texture 0", + "Blood:Texture 1", + "Blood:Texture 2", + "Blood:Texture Name 0", + "Blood:Texture Name 1", + "Blood:Texture Name 2", + 0 }; From 240d96a0f139d77a74e54635586600b20be2356a Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 09:41:23 +0100 Subject: [PATCH 158/168] Renamed AnimationValue to AnimationTime --- apps/openmw/mwrender/animation.cpp | 34 +++++++++++++-------------- apps/openmw/mwrender/animation.hpp | 14 +++++------ apps/openmw/mwrender/npcanimation.cpp | 9 +++---- apps/openmw/mwrender/npcanimation.hpp | 6 ++--- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index d4a3533a19..f0650fd82f 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -30,7 +30,7 @@ namespace MWRender { -Ogre::Real Animation::AnimationValue::getValue() const +Ogre::Real Animation::AnimationTime::getValue() const { AnimStateMap::const_iterator iter = mAnimation->mStates.find(mAnimationName); if(iter != mAnimation->mStates.end()) @@ -38,16 +38,16 @@ Ogre::Real Animation::AnimationValue::getValue() const return 0.0f; } -void Animation::AnimationValue::setValue(Ogre::Real) +void Animation::AnimationTime::setValue(Ogre::Real) { } -Ogre::Real Animation::EffectAnimationValue::getValue() const +Ogre::Real Animation::EffectAnimationTime::getValue() const { return mTime; } -void Animation::EffectAnimationValue::setValue(Ogre::Real) +void Animation::EffectAnimationTime::setValue(Ogre::Real) { } @@ -60,10 +60,10 @@ Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node) , mNonAccumRoot(NULL) , mNonAccumCtrl(NULL) , mAccumulate(0.0f) - , mNullAnimationValuePtr(OGRE_NEW NullAnimationValue) + , mNullAnimationTimePtr(OGRE_NEW NullAnimationTime) { for(size_t i = 0;i < sNumGroups;i++) - mAnimationValuePtr[i].bind(OGRE_NEW AnimationValue(this)); + mAnimationTimePtr[i].bind(OGRE_NEW AnimationTime(this)); } Animation::~Animation() @@ -139,7 +139,7 @@ void Animation::setObjectRoot(const std::string &model, bool baseonly) for(size_t i = 0;i < mObjectRoot->mControllers.size();i++) { if(mObjectRoot->mControllers[i].getSource().isNull()) - mObjectRoot->mControllers[i].setSource(mAnimationValuePtr[0]); + mObjectRoot->mControllers[i].setSource(mAnimationTimePtr[0]); } } @@ -286,7 +286,7 @@ void Animation::addAnimSource(const std::string &model) } } - ctrls[i].setSource(mAnimationValuePtr[grp]); + ctrls[i].setSource(mAnimationTimePtr[grp]); grpctrls[grp].push_back(ctrls[i]); } } @@ -296,7 +296,7 @@ void Animation::clearAnimSources() mStates.clear(); for(size_t i = 0;i < sNumGroups;i++) - mAnimationValuePtr[i]->setAnimName(std::string()); + mAnimationTimePtr[i]->setAnimName(std::string()); mNonAccumCtrl = NULL; @@ -789,7 +789,7 @@ void Animation::resetActiveGroups() active = state; } - mAnimationValuePtr[grp]->setAnimName((active == mStates.end()) ? + mAnimationTimePtr[grp]->setAnimName((active == mStates.end()) ? std::string() : active->first); } mNonAccumCtrl = NULL; @@ -797,7 +797,7 @@ void Animation::resetActiveGroups() if(!mNonAccumRoot || mAccumulate == Ogre::Vector3(0.0f)) return; - AnimStateMap::const_iterator state = mStates.find(mAnimationValuePtr[0]->getAnimName()); + AnimStateMap::const_iterator state = mStates.find(mAnimationTimePtr[0]->getAnimName()); if(state == mStates.end()) return; @@ -869,13 +869,13 @@ Ogre::Vector3 Animation::runAnimation(float duration) targetTime = state.mTime + timepassed; if(textkey == textkeys.end() || textkey->first > targetTime) { - if(mNonAccumCtrl && stateiter->first == mAnimationValuePtr[0]->getAnimName()) + if(mNonAccumCtrl && stateiter->first == mAnimationTimePtr[0]->getAnimName()) updatePosition(state.mTime, targetTime, movement); state.mTime = std::min(targetTime, state.mStopTime); } else { - if(mNonAccumCtrl && stateiter->first == mAnimationValuePtr[0]->getAnimName()) + if(mNonAccumCtrl && stateiter->first == mAnimationTimePtr[0]->getAnimName()) updatePosition(state.mTime, textkey->first, movement); state.mTime = textkey->first; } @@ -926,7 +926,7 @@ Ogre::Vector3 Animation::runAnimation(float duration) // Apply group controllers for(size_t grp = 0;grp < sNumGroups;grp++) { - const std::string &name = mAnimationValuePtr[grp]->getAnimName(); + const std::string &name = mAnimationTimePtr[grp]->getAnimName(); if(!name.empty() && (stateiter=mStates.find(name)) != mStates.end()) { const Ogre::SharedPtr &src = stateiter->second.mSource; @@ -1052,7 +1052,7 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con for(size_t i = 0;i < params.mObjects->mControllers.size();i++) { if(params.mObjects->mControllers[i].getSource().isNull()) - params.mObjects->mControllers[i].setSource(Ogre::SharedPtr (new EffectAnimationValue())); + params.mObjects->mControllers[i].setSource(Ogre::SharedPtr (new EffectAnimationTime())); } if (!texture.empty()) @@ -1110,7 +1110,7 @@ void Animation::updateEffects(float duration) NifOgre::ObjectScenePtr objects = it->mObjects; for(size_t i = 0; i < objects->mControllers.size() ;i++) { - EffectAnimationValue* value = dynamic_cast(objects->mControllers[i].getSource().get()); + EffectAnimationTime* value = dynamic_cast(objects->mControllers[i].getSource().get()); if (value) value->addTime(duration); @@ -1125,7 +1125,7 @@ void Animation::updateEffects(float duration) float remainder = objects->mControllers[0].getSource()->getValue() - objects->mMaxControllerLength; for(size_t i = 0; i < objects->mControllers.size() ;i++) { - EffectAnimationValue* value = dynamic_cast(objects->mControllers[i].getSource().get()); + EffectAnimationTime* value = dynamic_cast(objects->mControllers[i].getSource().get()); if (value) value->resetTime(remainder); } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 1400cb9a28..22f2e5df94 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -32,14 +32,14 @@ protected: /* This is the number of *discrete* groups. */ static const size_t sNumGroups = 4; - class AnimationValue : public Ogre::ControllerValue + class AnimationTime : public Ogre::ControllerValue { private: Animation *mAnimation; std::string mAnimationName; public: - AnimationValue(Animation *anim) + AnimationTime(Animation *anim) : mAnimation(anim) { } @@ -52,12 +52,12 @@ protected: virtual void setValue(Ogre::Real value); }; - class EffectAnimationValue : public Ogre::ControllerValue + class EffectAnimationTime : public Ogre::ControllerValue { private: float mTime; public: - EffectAnimationValue() : mTime(0) { } + EffectAnimationTime() : mTime(0) { } void addTime(float time) { mTime += time; } void resetTime(float value) { mTime = value; } @@ -67,7 +67,7 @@ protected: - class NullAnimationValue : public Ogre::ControllerValue + class NullAnimationTime : public Ogre::ControllerValue { public: virtual Ogre::Real getValue() const @@ -134,8 +134,8 @@ protected: AnimStateMap mStates; - Ogre::SharedPtr mAnimationValuePtr[sNumGroups]; - Ogre::SharedPtr mNullAnimationValuePtr; + Ogre::SharedPtr mAnimationTimePtr[sNumGroups]; + Ogre::SharedPtr mNullAnimationTimePtr; ObjectAttachMap mAttachedObjects; diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 497279bd8f..bcb6a374cb 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -61,8 +61,9 @@ std::string getVampireHead(const std::string& race, bool female) namespace MWRender { -float SayAnimationValue::getValue() const +float HeadAnimationTime::getValue() const { + // TODO: Handle eye blinking (time is in the text keys) if (MWBase::Environment::get().getSoundManager()->sayDone(mReference)) return 0; else @@ -124,7 +125,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v { mNpc = mPtr.get()->mBase; - mSayAnimationValue = Ogre::SharedPtr(new SayAnimationValue(mPtr)); + mHeadAnimationTime = Ogre::SharedPtr(new HeadAnimationTime(mPtr)); for(size_t i = 0;i < ESM::PRT_Count;i++) { @@ -595,10 +596,10 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g { if(ctrl->getSource().isNull()) { - ctrl->setSource(mNullAnimationValuePtr); + ctrl->setSource(mNullAnimationTimePtr); if (type == ESM::PRT_Head) - ctrl->setSource(mSayAnimationValue); + ctrl->setSource(mHeadAnimationTime); } } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 6f0403b9d4..e86ec7d4e1 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -13,12 +13,12 @@ namespace ESM namespace MWRender { -class SayAnimationValue : public Ogre::ControllerValue +class HeadAnimationTime : public Ogre::ControllerValue { private: MWWorld::Ptr mReference; public: - SayAnimationValue(MWWorld::Ptr reference) : mReference(reference) {} + HeadAnimationTime(MWWorld::Ptr reference) : mReference(reference) {} virtual Ogre::Real getValue() const; virtual void setValue(Ogre::Real value) @@ -70,7 +70,7 @@ private: Ogre::Vector3 mFirstPersonOffset; - Ogre::SharedPtr mSayAnimationValue; + Ogre::SharedPtr mHeadAnimationTime; float mAlpha; From 805843d7ff8cb15dbe1fb039037e6ae79d34e3d9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 10:52:44 +0100 Subject: [PATCH 159/168] Closes #1086: Implement blood effects --- apps/esmtool/labels.cpp | 4 +- apps/opencs/model/world/refidcollection.cpp | 2 +- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/world.hpp | 3 + apps/openmw/mwclass/creature.cpp | 11 ++ apps/openmw/mwclass/creature.hpp | 3 + apps/openmw/mwclass/npc.cpp | 17 ++- apps/openmw/mwclass/npc.hpp | 3 + apps/openmw/mwrender/animation.cpp | 1 + apps/openmw/mwrender/animation.hpp | 10 +- apps/openmw/mwrender/creatureanimation.cpp | 2 +- apps/openmw/mwrender/effectmanager.cpp | 117 ++++++++++++++++++++ apps/openmw/mwrender/effectmanager.hpp | 31 ++++++ apps/openmw/mwrender/renderingmanager.cpp | 19 +++- apps/openmw/mwrender/renderingmanager.hpp | 8 +- apps/openmw/mwworld/class.cpp | 4 + apps/openmw/mwworld/class.hpp | 3 + apps/openmw/mwworld/worldimp.cpp | 27 +++++ apps/openmw/mwworld/worldimp.hpp | 3 + components/esm/loadcrea.hpp | 16 ++- 20 files changed, 263 insertions(+), 23 deletions(-) create mode 100644 apps/openmw/mwrender/effectmanager.cpp create mode 100644 apps/openmw/mwrender/effectmanager.hpp diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp index d270a9534c..7a42e6900f 100644 --- a/apps/esmtool/labels.cpp +++ b/apps/esmtool/labels.cpp @@ -680,7 +680,7 @@ std::string creatureFlags(int flags) if (flags & ESM::Creature::Walks) properties += "Walks "; if (flags & ESM::Creature::Swims) properties += "Swims "; if (flags & ESM::Creature::Flies) properties += "Flies "; - if (flags & ESM::Creature::Biped) properties += "Biped "; + if (flags & ESM::Creature::Bipedal) properties += "Bipedal "; if (flags & ESM::Creature::Respawn) properties += "Respawn "; if (flags & ESM::Creature::Weapon) properties += "Weapon "; if (flags & ESM::Creature::Skeleton) properties += "Skeleton "; @@ -691,7 +691,7 @@ std::string creatureFlags(int flags) ESM::Creature::Walks| ESM::Creature::Swims| ESM::Creature::Flies| - ESM::Creature::Biped| + ESM::Creature::Bipedal| ESM::Creature::Respawn| ESM::Creature::Weapon| ESM::Creature::Skeleton| diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 9ed5268183..176a19f2f0 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -181,7 +181,7 @@ CSMWorld::RefIdCollection::RefIdCollection() unsigned int mFlag; } sCreatureFlagTable[] = { - { Columns::ColumnId_Biped, ESM::Creature::Biped }, + { Columns::ColumnId_Biped, ESM::Creature::Bipedal }, { Columns::ColumnId_HasWeapon, ESM::Creature::Weapon }, { Columns::ColumnId_NoMovement, ESM::Creature::None }, { Columns::ColumnId_Swims, ESM::Creature::Swims }, diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 4da5e29970..3b533b4168 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -20,7 +20,7 @@ add_openmw_dir (mwrender renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation actors objects renderinginterface localmap occlusionquery water shadows characterpreview globalmap videoplayer ripplesimulation refraction - terrainstorage renderconst + terrainstorage renderconst effectmanager ) add_openmw_dir (mwinput diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 83fcba87cc..3ad716b72f 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -463,6 +463,9 @@ namespace MWBase /// Spawn a random creature from a levelled list next to the player virtual void spawnRandomCreature(const std::string& creatureList) = 0; + + /// Spawn a blood effect for \a ptr at \a worldPosition + virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const Ogre::Vector3& worldPosition) = 0; }; } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index f2a4f9ccde..0fc26950d5 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -530,6 +530,17 @@ namespace MWClass } } + int Creature::getBloodTexture(const MWWorld::Ptr &ptr) const + { + MWWorld::LiveCellRef *ref = ptr.get(); + + if (ref->mBase->mFlags & ESM::Creature::Skeleton) + return 1; + if (ref->mBase->mFlags & ESM::Creature::Metal) + return 2; + return 0; + } + const ESM::GameSetting* Creature::fMinWalkSpeedCreature; const ESM::GameSetting* Creature::fMaxWalkSpeedCreature; const ESM::GameSetting *Creature::fEncumberedMoveEffect; diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 7d2f95fae0..708999ef04 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -111,6 +111,9 @@ namespace MWClass virtual bool isFlying (const MWWorld::Ptr &ptr) const; virtual int getSkill(const MWWorld::Ptr &ptr, int skill) const; + + /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) + virtual int getBloodTexture (const MWWorld::Ptr& ptr) const; }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 57de523386..93a7ddcf6e 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -455,7 +455,9 @@ namespace MWClass weapon.get()->mBase->mData.mReach : gmst.find("fHandToHandReach")->getFloat()); // TODO: Use second to work out the hit angle and where to spawn the blood effect - MWWorld::Ptr victim = world->getHitContact(ptr, dist).first; + std::pair result = world->getHitContact(ptr, dist); + MWWorld::Ptr victim = result.first; + Ogre::Vector3 hitPosition = result.second; if(victim.isEmpty()) // Didn't hit anything return; @@ -602,6 +604,8 @@ namespace MWClass } } + MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); + othercls.onHit(victim, damage, healthdmg, weapon, ptr, true); } @@ -1216,6 +1220,17 @@ namespace MWClass return ptr.getClass().getNpcStats(ptr).getSkill(skill).getModified(); } + int Npc::getBloodTexture(const MWWorld::Ptr &ptr) const + { + MWWorld::LiveCellRef *ref = ptr.get(); + + if (ref->mBase->mFlags & ESM::NPC::Skeleton) + return 1; + if (ref->mBase->mFlags & ESM::NPC::Metal) + return 2; + return 0; + } + const ESM::GameSetting *Npc::fMinWalkSpeed; const ESM::GameSetting *Npc::fMaxWalkSpeed; const ESM::GameSetting *Npc::fEncumberedMoveEffect; diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index b729d01514..497d0ced85 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -142,6 +142,9 @@ namespace MWClass virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const; + /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) + virtual int getBloodTexture (const MWWorld::Ptr& ptr) const; + virtual bool isActor() const { return true; } diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index f0650fd82f..de89b0207d 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -1042,6 +1042,7 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con else params.mObjects = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, model); + // TODO: turn off shadow casting setRenderProperties(params.mObjects, RV_Misc, RQG_Main, RQG_Alpha, 0.f, false, NULL); diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 22f2e5df94..da1c1628cd 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -189,16 +189,18 @@ protected: /** Adds an additional light to the given object list using the specified ESM record. */ void addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectScenePtr objlist, const ESM::Light *light); - static void setRenderProperties(NifOgre::ObjectScenePtr objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, - Ogre::uint8 transqueue, Ogre::Real dist=0.0f, - bool enchantedGlow=false, Ogre::Vector3* glowColor=NULL); - void clearAnimSources(); // TODO: Should not be here Ogre::Vector3 getEnchantmentColor(MWWorld::Ptr item); public: + // FIXME: Move outside of this class + static void setRenderProperties(NifOgre::ObjectScenePtr objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, + Ogre::uint8 transqueue, Ogre::Real dist=0.0f, + bool enchantedGlow=false, Ogre::Vector3* glowColor=NULL); + + Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node); virtual ~Animation(); diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index c3ad512ddd..20e5ff8efc 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -24,7 +24,7 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr) setObjectRoot(model, false); setRenderProperties(mObjectRoot, RV_Actors, RQG_Main, RQG_Alpha); - if((ref->mBase->mFlags&ESM::Creature::Biped)) + if((ref->mBase->mFlags&ESM::Creature::Bipedal)) addAnimSource("meshes\\base_anim.nif"); addAnimSource(model); } diff --git a/apps/openmw/mwrender/effectmanager.cpp b/apps/openmw/mwrender/effectmanager.cpp new file mode 100644 index 0000000000..eb4525a4fc --- /dev/null +++ b/apps/openmw/mwrender/effectmanager.cpp @@ -0,0 +1,117 @@ +#include "effectmanager.hpp" + +#include +#include + +#include "animation.hpp" +#include "renderconst.hpp" + +namespace MWRender +{ + +class EffectAnimationTime : public Ogre::ControllerValue +{ +private: + float mTime; +public: + EffectAnimationTime() : mTime(0) { } + void addTime(float time) { mTime += time; } + + virtual Ogre::Real getValue() const { return mTime; } + virtual void setValue(Ogre::Real value) {} +}; + +EffectManager::EffectManager(Ogre::SceneManager *sceneMgr) + : mSceneMgr(sceneMgr) +{ +} + +void EffectManager::addEffect(const std::string &model, std::string textureOverride, const Ogre::Vector3 &worldPosition) +{ + Ogre::SceneNode* sceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(worldPosition); + + // fix texture extension to .dds + if (textureOverride.size() > 4) + { + textureOverride[textureOverride.size()-3] = 'd'; + textureOverride[textureOverride.size()-2] = 'd'; + textureOverride[textureOverride.size()-1] = 's'; + } + + + NifOgre::ObjectScenePtr scene = NifOgre::Loader::createObjects(sceneNode, model); + + // TODO: turn off shadow casting + MWRender::Animation::setRenderProperties(scene, RV_Misc, + RQG_Main, RQG_Alpha, 0.f, false, NULL); + + for(size_t i = 0;i < scene->mControllers.size();i++) + { + if(scene->mControllers[i].getSource().isNull()) + scene->mControllers[i].setSource(Ogre::SharedPtr (new EffectAnimationTime())); + } + + if (!textureOverride.empty()) + { + for(size_t i = 0;i < scene->mParticles.size(); ++i) + { + Ogre::ParticleSystem* partSys = scene->mParticles[i]; + + Ogre::MaterialPtr mat = scene->mMaterialControllerMgr.getWritableMaterial(partSys); + + for (int t=0; tgetNumTechniques(); ++t) + { + Ogre::Technique* tech = mat->getTechnique(t); + for (int p=0; pgetNumPasses(); ++p) + { + Ogre::Pass* pass = tech->getPass(p); + for (int tex=0; texgetNumTextureUnitStates(); ++tex) + { + Ogre::TextureUnitState* tus = pass->getTextureUnitState(tex); + tus->setTextureName("textures\\" + textureOverride); + } + } + } + } + } + + mEffects.push_back(std::make_pair(sceneNode, scene)); +} + +void EffectManager::update(float dt) +{ + for (std::vector >::iterator it = mEffects.begin(); it != mEffects.end(); ) + { + NifOgre::ObjectScenePtr objects = it->second; + for(size_t i = 0; i < objects->mControllers.size() ;i++) + { + EffectAnimationTime* value = dynamic_cast(objects->mControllers[i].getSource().get()); + if (value) + value->addTime(dt); + + objects->mControllers[i].update(); + } + + // Finished playing? + if (objects->mControllers[0].getSource()->getValue() >= objects->mMaxControllerLength) + { + Ogre::SceneNode* node = it->first; + it = mEffects.erase(it); + mSceneMgr->destroySceneNode(node); + continue; + } + ++it; + } +} + +void EffectManager::clear() +{ + for (std::vector >::iterator it = mEffects.begin(); it != mEffects.end(); ) + { + Ogre::SceneNode* node = it->first; + it = mEffects.erase(it); + mSceneMgr->destroySceneNode(node); + } +} + +} diff --git a/apps/openmw/mwrender/effectmanager.hpp b/apps/openmw/mwrender/effectmanager.hpp new file mode 100644 index 0000000000..0c8bc3857c --- /dev/null +++ b/apps/openmw/mwrender/effectmanager.hpp @@ -0,0 +1,31 @@ +#ifndef OPENMW_MWRENDER_EFFECTMANAGER_H +#define OPENMW_MWRENDER_EFFECTMANAGER_H + +#include + +namespace MWRender +{ + // Note: effects attached to another object should be managed by MWRender::Animation::addEffect. + // This class manages "free" effects, i.e. attached to a dedicated scene node in the world. + class EffectManager + { + public: + EffectManager(Ogre::SceneManager* sceneMgr); + ~EffectManager() { clear(); } + + /// Add an effect. When it's finished playing, it will be removed automatically. + void addEffect (const std::string& model, std::string textureOverride, const Ogre::Vector3& worldPosition); + + void update(float dt); + + /// Remove all effects + void clear(); + + private: + std::vector > mEffects; + Ogre::SceneManager* mSceneMgr; + }; + +} + +#endif diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 47cf3ee41b..8a2ab1c7a1 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -41,6 +41,7 @@ #include "globalmap.hpp" #include "videoplayer.hpp" #include "terrainstorage.hpp" +#include "effectmanager.hpp" using namespace MWRender; using namespace Ogre; @@ -57,9 +58,11 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b , mSunEnabled(0) , mPhysicsEngine(engine) , mTerrain(NULL) + , mEffectManager(NULL) { mActors = new MWRender::Actors(mRendering, this); mObjects = new MWRender::Objects(mRendering); + mEffectManager = new EffectManager(mRendering.getScene()); // select best shader mode bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); bool glES = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL ES") != std::string::npos); @@ -193,6 +196,7 @@ RenderingManager::~RenderingManager () delete mVideoPlayer; delete mActors; delete mObjects; + delete mEffectManager; delete mFactory; } @@ -374,6 +378,8 @@ void RenderingManager::update (float duration, bool paused) if(paused) return; + mEffectManager->update(duration); + mActors->update (mRendering.getCamera()); mPlayerAnimation->preRender(mRendering.getCamera()); mObjects->update (duration, mRendering.getCamera()); @@ -675,14 +681,14 @@ Shadows* RenderingManager::getShadows() void RenderingManager::switchToInterior() { - // causes light flicker in opengl when moving.. - //mRendering.getScene()->setCameraRelativeRendering(false); + // TODO: also do this when switching worldspace + mEffectManager->clear(); } void RenderingManager::switchToExterior() { - // causes light flicker in opengl when moving.. - //mRendering.getScene()->setCameraRelativeRendering(true); + // TODO: also do this when switching worldspace + mEffectManager->clear(); } Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds) @@ -1020,4 +1026,9 @@ float RenderingManager::getCameraDistance() const return mCamera->getCameraDistance(); } +void RenderingManager::spawnEffect(const std::string &model, const std::string &texture, const Vector3 &worldPosition) +{ + mEffectManager->addEffect(model, texture, worldPosition); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 9f77f0a3c9..b6379bee44 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -21,10 +21,7 @@ namespace Ogre { - class SceneManager; class SceneNode; - class Quaternion; - class Vector3; } namespace MWWorld @@ -51,6 +48,7 @@ namespace MWRender class GlobalMap; class VideoPlayer; class Animation; + class EffectManager; class RenderingManager: private RenderingInterface, public Ogre::RenderTargetListener, public OEngine::Render::WindowSizeListener { @@ -209,6 +207,8 @@ public: void stopVideo(); void frameStarted(float dt, bool paused); + void spawnEffect (const std::string& model, const std::string& texture, const Ogre::Vector3& worldPosition); + protected: virtual void windowResized(int x, int y); @@ -239,6 +239,8 @@ private: MWRender::Objects* mObjects; MWRender::Actors* mActors; + MWRender::EffectManager* mEffectManager; + MWRender::NpcAnimation *mPlayerAnimation; // 0 normal, 1 more bright, 2 max diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index f3128780b8..6c00b949cf 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -363,4 +363,8 @@ namespace MWWorld throw std::runtime_error("class does not support skills"); } + int Class::getBloodTexture (const MWWorld::Ptr& ptr) const + { + throw std::runtime_error("class does not support gore"); + } } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index bbc74323cb..ec22d03066 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -278,6 +278,9 @@ namespace MWWorld virtual bool isKey (const MWWorld::Ptr& ptr) const { return false; } + /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) + virtual int getBloodTexture (const MWWorld::Ptr& ptr) const; + virtual Ptr copyToCell(const Ptr &ptr, CellStore &cell) const; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index ebc1044bc4..a40f20696d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2610,4 +2610,31 @@ namespace MWWorld safePlaceObject(ref.getPtr(),*cell,ipos); } } + + void World::spawnBloodEffect(const Ptr &ptr, const Vector3 &worldPosition) + { + int type = ptr.getClass().getBloodTexture(ptr); + std::string texture; + switch (type) + { + case 2: + texture = getFallback()->getFallbackString("Blood_Texture_2"); + break; + case 1: + texture = getFallback()->getFallbackString("Blood_Texture_1"); + break; + case 0: + default: + texture = getFallback()->getFallbackString("Blood_Texture_0"); + break; + } + + std::stringstream modelName; + modelName << "Blood_Model_"; + int roll = std::rand()/ (static_cast (RAND_MAX) + 1) * 3; // [0, 2] + modelName << roll; + std::string model = "meshes\\" + getFallback()->getFallbackString(modelName.str()); + + mRendering->spawnEffect(model, texture, worldPosition); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 92975400a4..38766e74f1 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -549,6 +549,9 @@ namespace MWWorld /// Spawn a random creature from a levelled list next to the player virtual void spawnRandomCreature(const std::string& creatureList); + + /// Spawn a blood effect for \a ptr at \a worldPosition + virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const Ogre::Vector3& worldPosition); }; } diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index c0523025bd..817c0e43c5 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -25,16 +25,20 @@ struct Creature // Default is 0x48? enum Flags { - Biped = 0x001, - Respawn = 0x002, - Weapon = 0x004, // Has weapon and shield - None = 0x008, // ?? + // Movement types + Bipedal = 0x001, Swims = 0x010, Flies = 0x020, // Don't know what happens if several Walks = 0x040, // of these are set + + Respawn = 0x002, + Weapon = 0x004, // Has weapon and shield + None = 0x008, // ?? Essential = 0x080, - Skeleton = 0x400, // Does not have normal blood - Metal = 0x800 // Has 'golden' blood + + // Blood types + Skeleton = 0x400, + Metal = 0x800 }; enum Type From c548dcee13e6262a32148a4892178d9429456dc8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 13:13:58 +0100 Subject: [PATCH 160/168] Quick keys menu: make sure selected spell still exists --- apps/openmw/mwgui/quickkeysmenu.cpp | 6 ++++++ apps/openmw/mwmechanics/character.cpp | 6 ++++-- apps/openmw/mwmechanics/spells.hpp | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index 61e414fc4e..e1d430307d 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -301,6 +301,12 @@ namespace MWGui if (type == Type_Magic) { std::string spellId = button->getChildAt(0)->getUserString("Spell"); + + // Make sure the player still has this spell + MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); + MWMechanics::Spells& spells = stats.getSpells(); + if (!spells.hasSpell(spellId)) + return; store.setSelectedEnchantItem(store.end()); MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player))); } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 5104a0f57f..755dbc0932 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -583,8 +583,10 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun // This has to be done at the start of the casting animation, // *not* when selecting a spell in the GUI (otherwise you could change the spell mid-animation) if (mPtr.getRefData().getHandle() == "player") - stats.getSpells().setSelectedSpell(MWBase::Environment::get().getWindowManager()->getSelectedSpell()); - + { + std::string selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); + stats.getSpells().setSelectedSpell(selectedSpell); + } std::string spellid = stats.getSpells().getSelectedSpell(); if(!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr)) diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index cf9b660915..facf02da84 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -44,6 +44,8 @@ namespace MWMechanics TIterator end() const; + bool hasSpell(const std::string& spell) { return mSpells.find(Misc::StringUtils::lowerCase(spell)) != mSpells.end(); } + void add (const std::string& spell); ///< Adding a spell that is already listed in *this is a no-op. From 659d790048adf5643d15419fd8a250d7a5663f64 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 13:14:50 +0100 Subject: [PATCH 161/168] uuid is not used --- CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b365e162f5..fd5de4c394 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,8 +186,6 @@ if (WIN32) add_definitions(-DSDL_MAIN_HANDLED) else (WIN32) set(PLATFORM_INCLUDE_DIR "") - find_path (UUID_INCLUDE_DIR uuid/uuid.h) - include_directories(${UUID_INCLUDE_DIR}) endif (WIN32) if (MSVC10) set(PLATFORM_INCLUDE_DIR "") @@ -239,7 +237,6 @@ include_directories("." ${MYGUI_INCLUDE_DIRS} ${MYGUI_PLATFORM_INCLUDE_DIRS} ${OPENAL_INCLUDE_DIR} - ${UUID_INCLUDE_DIR} ${LIBDIR} ) @@ -434,7 +431,7 @@ IF(NOT WIN32 AND NOT APPLE) SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW opencs;OpenCS bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libqtgui4 (>= 4.7.0)") SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") From 5fc38e7ac480d2b9b922391126d31f17adecee44 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 13:20:41 +0100 Subject: [PATCH 162/168] Don't use blood effects for fatigue damage --- apps/openmw/mwclass/npc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 93a7ddcf6e..cfd981088d 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -604,7 +604,8 @@ namespace MWClass } } - MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); + if (healthdmg) + MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); othercls.onHit(victim, damage, healthdmg, weapon, ptr, true); } From 37a59a37c6d2c6c227b7b9fd029d0d1a618d8028 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 14:11:46 +0100 Subject: [PATCH 163/168] Remove cpack (no longer used, according to BrotherBrick) --- CMakeLists.txt | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fd5de4c394..8eb8b44c28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -406,46 +406,6 @@ IF(NOT WIN32 AND NOT APPLE) # Install resources INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "Resources") INSTALL(DIRECTORY DESTINATION "${DATADIR}/data" COMPONENT "Resources") - - IF (DPKG_PROGRAM) - ## Debian Specific - IF(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") - EXEC_PROGRAM("git" ${CMAKE_CURRENT_SOURCE_DIR} ARGS "describe" OUTPUT_VARIABLE GIT_VERSION ) - STRING(REGEX REPLACE "openmw-" "" VERSION_STRING "${GIT_VERSION}") - EXEC_PROGRAM("git" ARGS "config --get user.name" OUTPUT_VARIABLE GIT_NAME ) - EXEC_PROGRAM("git" ARGS "config --get user.email" OUTPUT_VARIABLE GIT_EMAIL) - SET(PACKAGE_MAINTAINER "${GIT_NAME} <${GIT_EMAIL}>") - ELSE() - SET(VERSION_STRING "${OPENMW_VERSION}") - SET(PACKAGE_MAINTAINER "unknown") - ENDIF() - - SET(CPACK_GENERATOR "DEB") - SET(CPACK_PACKAGE_NAME "openmw") - SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://openmw.org") - SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") - SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "${PACKAGE_MAINTAINER}") - SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "A reimplementation of The Elder Scrolls III: Morrowind - OpenMW is a reimplementation of the Bethesda Game Studios game The Elder Scrolls III: Morrowind. - Data files from the original game is required to run it.") - SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") - SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") - SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW opencs;OpenCS bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libqtgui4 (>= 4.7.0)") - - SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") - - STRING(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_PACKAGE_NAME_LOWERCASE) - EXECUTE_PROCESS( - COMMAND ${DPKG_PROGRAM} --print-architecture - OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}_${CPACK_DEBIAN_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") - - - INCLUDE(CPack) - ENDIF(DPKG_PROGRAM) ENDIF(NOT WIN32 AND NOT APPLE) if(WIN32) From 27d0d9c592a22448c64a129824f9bbcc268ee4b4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 15:27:59 +0100 Subject: [PATCH 164/168] Fix exception when clicking on statics when in the inventory window --- apps/openmw/mwgui/hud.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 7cd9e22569..a6ad43ce58 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -267,7 +267,8 @@ namespace MWGui else if ((mode == GM_Container) || (mode == GM_Inventory)) { // pick up object - MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object); + if (!object.isEmpty()) + MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object); } } } From c76a0448a3f6e9ad9954cc879b6164aba2f54e8f Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 15:47:34 +0100 Subject: [PATCH 165/168] Closes #1123: Implement SlowFall magic effect --- apps/openmw/mwworld/physicssystem.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 2a7f5948e4..a7103b9911 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -108,7 +108,7 @@ namespace MWWorld } static Ogre::Vector3 move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time, - bool isFlying, float waterlevel, OEngine::Physic::PhysicEngine *engine) + bool isFlying, float waterlevel, float slowFall, OEngine::Physic::PhysicEngine *engine) { const ESM::Position &refpos = ptr.getRefData().getPosition(); Ogre::Vector3 position(refpos.pos); @@ -229,7 +229,10 @@ namespace MWWorld physicActor->setInertialForce(Ogre::Vector3(0.0f)); else { - inertia.z += time*-627.2f; + float diff = time*-627.2f; + if (inertia.z < 0) + diff *= slowFall; + inertia.z += diff; physicActor->setInertialForce(inertia); } physicActor->setOnGround(isOnGround); @@ -577,9 +580,10 @@ namespace MWWorld float oldHeight = iter->first.getRefData().getPosition().pos[2]; + const MWMechanics::MagicEffects& effects = iter->first.getClass().getCreatureStats(iter->first).getMagicEffects(); + bool waterCollision = false; - if (iter->first.getClass().getCreatureStats(iter->first).getMagicEffects() - .get(ESM::MagicEffect::WaterWalking).mMagnitude + if (effects.get(ESM::MagicEffect::WaterWalking).mMagnitude && cell->hasWater() && !world->isUnderwater(iter->first.getCell(), Ogre::Vector3(iter->first.getRefData().getPosition().pos))) @@ -592,9 +596,12 @@ namespace MWWorld if (waterCollision) mEngine->dynamicsWorld->addCollisionObject(&object); + // 100 points of slowfall reduce gravity by 90% (this is just a guess) + float slowFall = 1-std::min(std::max(0.f, (effects.get(ESM::MagicEffect::SlowFall).mMagnitude / 100.f) * 0.9f), 0.9f); + Ogre::Vector3 newpos = MovementSolver::move(iter->first, iter->second, mTimeAccum, world->isFlying(iter->first), - waterlevel, mEngine); + waterlevel, slowFall, mEngine); if (waterCollision) mEngine->dynamicsWorld->removeCollisionObject(&object); From 228254c890e6b90f1bcb2070b3e356c854efeeb1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 16:31:27 +0100 Subject: [PATCH 166/168] Handle creature attack animations in character controller --- apps/openmw/mwmechanics/character.cpp | 46 +++++++++++++++++++++++++-- apps/openmw/mwmechanics/character.hpp | 3 +- apps/openmw/mwworld/worldimp.cpp | 3 +- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 755dbc0932..fe650237ac 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -479,9 +479,47 @@ void CharacterController::updatePtr(const MWWorld::Ptr &ptr) mPtr = ptr; } -bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrunning, bool sneak) +bool CharacterController::updateCreatureState() { - const MWWorld::Class &cls = MWWorld::Class::get(mPtr); + const MWWorld::Class &cls = mPtr.getClass(); + CreatureStats &stats = cls.getCreatureStats(mPtr); + + if(stats.getAttackingOrSpell()) + { + if(mUpperBodyState == UpperCharState_Nothing && mHitState == CharState_None) + { + MWBase::Environment::get().getWorld()->breakInvisibility(mPtr); + + switch (stats.getAttackType()) + { + case CreatureStats::AT_Chop: + mCurrentWeapon = "attack1"; + break; + case CreatureStats::AT_Thrust: + mCurrentWeapon = "attack2"; + break; + case CreatureStats::AT_Slash: + mCurrentWeapon = "attack3"; + break; + } + + mAnimation->play(mCurrentWeapon, Priority_Weapon, + MWRender::Animation::Group_UpperBody, true, + 1, "start", "stop", + 0.0f, 0); + mUpperBodyState = UpperCharState_StartToMinAttack; + } + } + + bool animPlaying = mAnimation->getInfo(mCurrentWeapon); + if (!animPlaying) + mUpperBodyState = UpperCharState_Nothing; + return false; +} + +bool CharacterController::updateNpcState(bool inwater, bool isrunning) +{ + const MWWorld::Class &cls = MWWorld::Class::get(mPtr); NpcStats &stats = cls.getNpcStats(mPtr); WeaponType weaptype = WeapType_None; MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); @@ -1091,7 +1129,9 @@ void CharacterController::update(float duration) } if(cls.isNpc()) - forcestateupdate = updateNpcState(onground, inwater, isrunning, sneak) || forcestateupdate; + forcestateupdate = updateNpcState(inwater, isrunning) || forcestateupdate; + else + forcestateupdate = updateCreatureState() || forcestateupdate; refreshCurrentAnims(idlestate, movestate, forcestateupdate); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 438f542f02..d3d4b44355 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -176,7 +176,8 @@ class CharacterController void clearAnimQueue(); - bool updateNpcState(bool onground, bool inwater, bool isrunning, bool sneak); + bool updateNpcState(bool inwater, bool isrunning); + bool updateCreatureState(); void updateVisibility(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a40f20696d..0d78020817 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2282,7 +2282,8 @@ namespace MWWorld void World::breakInvisibility(const Ptr &actor) { actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Invisibility); - actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Invisibility); + if (actor.getClass().isNpc()) + actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Invisibility); } bool World::isDark() const From 9b32b1403ba63c63ef5d9261a2c641f78eff7e36 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 17:19:08 +0100 Subject: [PATCH 167/168] Feature #960: Implement Creature::hit --- apps/openmw/mwclass/creature.cpp | 56 +++++++++++++++++++++++ apps/openmw/mwclass/npc.cpp | 3 +- apps/openmw/mwmechanics/character.cpp | 4 +- apps/openmw/mwmechanics/creaturestats.hpp | 4 +- apps/openmw/mwrender/animation.cpp | 17 +++++-- 5 files changed, 75 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 0fc26950d5..e6d2965faf 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -173,6 +173,62 @@ namespace MWClass void Creature::hit(const MWWorld::Ptr& ptr, int type) const { + MWWorld::LiveCellRef *ref = + ptr.get(); + + // TODO: where is the distance defined? + std::pair result = MWBase::Environment::get().getWorld()->getHitContact(ptr, 100); + if (result.first.isEmpty()) + return; // Didn't hit anything + + MWWorld::Ptr victim = result.first; + + if (!victim.getClass().isActor()) + return; // Can't hit non-actors + + Ogre::Vector3 hitPosition = result.second; + + MWMechanics::CreatureStats &stats = getCreatureStats(ptr); + MWMechanics::CreatureStats &otherstats = victim.getClass().getCreatureStats(victim); + const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects(); + float hitchance = ref->mBase->mData.mCombat + + (stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) + + (stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f); + hitchance *= stats.getFatigueTerm(); + hitchance += mageffects.get(ESM::MagicEffect::FortifyAttack).mMagnitude - + mageffects.get(ESM::MagicEffect::Blind).mMagnitude; + hitchance -= otherstats.getEvasion(); + + if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f) + { + victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, false); + return; + } + + int min,max; + switch (type) + { + case 0: + min = ref->mBase->mData.mAttack[0]; + max = ref->mBase->mData.mAttack[1]; + break; + case 1: + min = ref->mBase->mData.mAttack[2]; + max = ref->mBase->mData.mAttack[3]; + break; + case 2: + default: + min = ref->mBase->mData.mAttack[4]; + max = ref->mBase->mData.mAttack[5]; + break; + } + + float damage = min + (max - min) * ::rand()/(RAND_MAX+1.0); + + // TODO: do not do this if the attack is blocked + MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); + + victim.getClass().onHit(victim, damage, true, MWWorld::Ptr(), ptr, true); } void Creature::onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index cfd981088d..f93a3e342d 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -454,7 +454,7 @@ namespace MWClass float dist = 100.0f * (!weapon.isEmpty() ? weapon.get()->mBase->mData.mReach : gmst.find("fHandToHandReach")->getFloat()); - // TODO: Use second to work out the hit angle and where to spawn the blood effect + // TODO: Use second to work out the hit angle std::pair result = world->getHitContact(ptr, dist); MWWorld::Ptr victim = result.first; Ogre::Vector3 hitPosition = result.second; @@ -604,6 +604,7 @@ namespace MWClass } } + // TODO: do not do this if the attack is blocked if (healthdmg) MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index fe650237ac..013af5b3a1 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -495,10 +495,10 @@ bool CharacterController::updateCreatureState() case CreatureStats::AT_Chop: mCurrentWeapon = "attack1"; break; - case CreatureStats::AT_Thrust: + case CreatureStats::AT_Slash: mCurrentWeapon = "attack2"; break; - case CreatureStats::AT_Slash: + case CreatureStats::AT_Thrust: mCurrentWeapon = "attack3"; break; } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 26856c966d..308883fc53 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -116,9 +116,9 @@ namespace MWMechanics enum AttackType { + AT_Chop, AT_Slash, - AT_Thrust, - AT_Chop + AT_Thrust }; void setAttackType(int attackType) { mAttackType = attackType; } int getAttackType() { return mAttackType; } diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index de89b0207d..a7623efea6 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -660,13 +660,22 @@ void Animation::handleTextKey(AnimState &state, const std::string &groupname, co else if(evt.compare(off, len, "unequip detach") == 0) showWeapons(false); else if(evt.compare(off, len, "chop hit") == 0) - MWWorld::Class::get(mPtr).hit(mPtr, MWMechanics::CreatureStats::AT_Chop); + mPtr.getClass().hit(mPtr, MWMechanics::CreatureStats::AT_Chop); else if(evt.compare(off, len, "slash hit") == 0) - MWWorld::Class::get(mPtr).hit(mPtr, MWMechanics::CreatureStats::AT_Slash); + mPtr.getClass().hit(mPtr, MWMechanics::CreatureStats::AT_Slash); else if(evt.compare(off, len, "thrust hit") == 0) - MWWorld::Class::get(mPtr).hit(mPtr, MWMechanics::CreatureStats::AT_Thrust); + mPtr.getClass().hit(mPtr, MWMechanics::CreatureStats::AT_Thrust); else if(evt.compare(off, len, "hit") == 0) - MWWorld::Class::get(mPtr).hit(mPtr); + { + if (groupname == "attack1") + mPtr.getClass().hit(mPtr, MWMechanics::CreatureStats::AT_Chop); + else if (groupname == "attack2") + mPtr.getClass().hit(mPtr, MWMechanics::CreatureStats::AT_Slash); + else if (groupname == "attack3") + mPtr.getClass().hit(mPtr, MWMechanics::CreatureStats::AT_Thrust); + else + mPtr.getClass().hit(mPtr); + } else if (groupname == "spellcast" && evt.substr(evt.size()-7, 7) == "release") MWBase::Environment::get().getWorld()->castSpell(mPtr); From 149d77dedf4cb89a46db80248c6f16b73f3a345c Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 17:40:58 +0100 Subject: [PATCH 168/168] Feature #960: Add knockdown and hit recovery for creatures --- apps/openmw/mwclass/creature.cpp | 19 +++++++++++++++++++ apps/openmw/mwclass/creature.hpp | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index e6d2965faf..a972683181 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -69,6 +69,9 @@ namespace MWClass fMaxFlySpeed = gmst.find("fMaxFlySpeed"); fSwimRunBase = gmst.find("fSwimRunBase"); fSwimRunAthleticsMult = gmst.find("fSwimRunAthleticsMult"); + fKnockDownMult = gmst.find("fKnockDownMult"); + iKnockDownOddsMult = gmst.find("iKnockDownOddsMult"); + iKnockDownOddsBase = gmst.find("iKnockDownOddsBase"); inited = true; } @@ -255,6 +258,19 @@ namespace MWClass ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1); } + // Check for knockdown + float agilityTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() * fKnockDownMult->getFloat(); + float knockdownTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() + * iKnockDownOddsMult->getInt() * 0.01 + iKnockDownOddsBase->getInt(); + int roll = std::rand()/ (static_cast (RAND_MAX) + 1) * 100; // [0, 99] + if (ishealth && agilityTerm <= damage && knockdownTerm <= roll) + { + getCreatureStats(ptr).setKnockedDown(true); + + } + else + getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur? + if(ishealth) { if(damage > 0.0f) @@ -607,5 +623,8 @@ namespace MWClass const ESM::GameSetting *Creature::fMaxFlySpeed; const ESM::GameSetting *Creature::fSwimRunBase; const ESM::GameSetting *Creature::fSwimRunAthleticsMult; + const ESM::GameSetting *Creature::fKnockDownMult; + const ESM::GameSetting *Creature::iKnockDownOddsMult; + const ESM::GameSetting *Creature::iKnockDownOddsBase; } diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 708999ef04..d518d0056b 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -24,6 +24,10 @@ namespace MWClass static const ESM::GameSetting *fMaxFlySpeed; static const ESM::GameSetting *fSwimRunBase; static const ESM::GameSetting *fSwimRunAthleticsMult; + static const ESM::GameSetting *fKnockDownMult; + static const ESM::GameSetting *iKnockDownOddsMult; + static const ESM::GameSetting *iKnockDownOddsBase; + public: