From 8dd930cf97fc4a0fee398a31209fabf24ad7fcb1 Mon Sep 17 00:00:00 2001 From: mrcheko Date: Fri, 13 Dec 2013 22:43:58 +0200 Subject: [PATCH 001/223] bug fix http://bugs.openmw.org/issues/428 --- apps/openmw/mwbase/windowmanager.hpp | 2 ++ apps/openmw/mwbase/world.hpp | 3 ++ apps/openmw/mwgui/mainmenu.cpp | 13 +++++++- apps/openmw/mwgui/mainmenu.hpp | 4 +++ apps/openmw/mwgui/windowmanagerimp.cpp | 5 +++ apps/openmw/mwgui/windowmanagerimp.hpp | 3 ++ apps/openmw/mwinput/inputmanagerimp.cpp | 37 ++++++++++++----------- apps/openmw/mwmechanics/actors.cpp | 14 ++++----- apps/openmw/mwmechanics/character.cpp | 22 ++++++++++++-- apps/openmw/mwmechanics/character.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 5 +++ apps/openmw/mwrender/renderingmanager.hpp | 2 ++ apps/openmw/mwworld/worldimp.cpp | 9 +++++- apps/openmw/mwworld/worldimp.hpp | 2 ++ 14 files changed, 92 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index c47ad066b..4ffb44615 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -202,6 +202,8 @@ namespace MWBase virtual void setSpellVisibility(bool visible) = 0; virtual void setSneakVisibility(bool visible) = 0; + void virtual setMainMenuNoReturn(bool noreturn) = 0; + virtual void activateQuickKey (int index) = 0; virtual void setSelectedSpell(const std::string& spellId, int successChancePercent) = 0; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 8141af712..b1f236bd1 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -40,6 +40,7 @@ namespace ESM namespace MWRender { + class Camera; class ExternalRendering; class Animation; } @@ -115,6 +116,8 @@ namespace MWBase virtual MWWorld::Player& getPlayer() = 0; + virtual MWRender::Camera* getCamera() const = 0; + virtual const MWWorld::ESMStore& getStore() const = 0; virtual std::vector& getEsmReader() = 0; diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index fa7ed2ace..e1c72193b 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -17,6 +17,7 @@ namespace MWGui MainMenu::MainMenu(int w, int h) : OEngine::GUI::Layout("openmw_mainmenu.layout") , mButtonBox(0) + , mNoReturn(false) { onResChange(w,h); } @@ -33,7 +34,8 @@ namespace MWGui int curH = 0; std::vector buttons; - buttons.push_back("return"); + if(!mNoReturn) + buttons.push_back("return"); buttons.push_back("newgame"); //buttons.push_back("loadgame"); //buttons.push_back("savegame"); @@ -68,6 +70,15 @@ namespace MWGui mButtonBox->setCoord (w/2 - maxwidth/2, h/2 - curH/2, maxwidth, curH); } + void MainMenu::setNoReturn(bool bNoReturn) + { + if (mNoReturn != bNoReturn) + { + mNoReturn = bNoReturn; + onResChange( Settings::Manager::getInt("resolution x", "Video"), Settings::Manager::getInt("resolution y", "Video") ); + } + } + void MainMenu::onButtonClicked(MyGUI::Widget *sender) { MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f); diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index 4e76a64df..a686cb020 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -12,9 +12,13 @@ namespace MWGui void onResChange(int w, int h); + void setNoReturn(bool bNoReturn); + private: MyGUI::Widget* mButtonBox; + bool mNoReturn; + std::map mButtons; void onButtonClicked (MyGUI::Widget* sender); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 78986a052..69ec11ccc 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -880,6 +880,11 @@ namespace MWGui mHud->setSneakVisible(visible); } + void WindowManager::setMainMenuNoReturn(bool noreturn) + { + mMenu->setNoReturn(noreturn); + } + void WindowManager::setDragDrop(bool dragDrop) { mToolTips->setEnabled(!dragDrop); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 4f1960295..3d6972718 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -198,6 +198,9 @@ namespace MWGui virtual void setSpellVisibility(bool visible); virtual void setSneakVisibility(bool visible); + //disables 'return' button in the main menu (used when player is dead) + void virtual setMainMenuNoReturn(bool noreturn); + virtual void activateQuickKey (int index); virtual void setSelectedSpell(const std::string& spellId, int successChancePercent); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index ab2569635..9b7fe98bd 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -367,24 +367,27 @@ namespace MWInput } } - if (mControlSwitch["playerviewswitch"]) { - - // work around preview mode toggle when pressing Alt+Tab - if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { - if (mPreviewPOVDelay <= 0.5 && - (mPreviewPOVDelay += dt) > 0.5) - { - mPreviewPOVDelay = 1.f; - MWBase::Environment::get().getWorld()->togglePreviewMode(true); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + if ( !player.getClass().getCreatureStats(player).isDead() ) { + if (mControlSwitch["playerviewswitch"]) { + // work around preview mode toggle when pressing Alt+Tab + if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { + + if (mPreviewPOVDelay <= 0.5 && + (mPreviewPOVDelay += dt) > 0.5) + { + mPreviewPOVDelay = 1.f; + MWBase::Environment::get().getWorld()->togglePreviewMode(true); + } + } else { + if (mPreviewPOVDelay > 0.5) { + //disable preview mode + MWBase::Environment::get().getWorld()->togglePreviewMode(false); + } else if (mPreviewPOVDelay > 0.f) { + MWBase::Environment::get().getWorld()->togglePOV(); + } + mPreviewPOVDelay = 0.f; } - } else { - if (mPreviewPOVDelay > 0.5) { - //disable preview mode - MWBase::Environment::get().getWorld()->togglePreviewMode(false); - } else if (mPreviewPOVDelay > 0.f) { - MWBase::Environment::get().getWorld()->togglePOV(); - } - mPreviewPOVDelay = 0.f; } } } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 22a641b34..5dd294f90 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -570,15 +570,13 @@ namespace MWMechanics continue; } - if(iter->second->isDead()) - continue; + if (iter->second->kill()) + { + ++mDeathCount[cls.getId(iter->first)]; - iter->second->kill(); - - ++mDeathCount[cls.getId(iter->first)]; - - if(cls.isEssential(iter->first)) - MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}"); + if(cls.isEssential(iter->first)) + MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}"); + } } } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index da3ed2523..c8eba20d6 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -27,6 +27,7 @@ #include "security.hpp" #include "../mwrender/animation.hpp" +#include "../mwrender/camera.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -1055,10 +1056,19 @@ void CharacterController::forceStateUpdate() } } -void CharacterController::kill() +bool CharacterController::kill() { - if(mDeathState != CharState_None) - return; + if( isDead() ) + { + //player death animation is over: toggle game menu without 'return' option + if( mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() + && !isAnimPlaying(mCurrentDeath) ) + { + MWBase::Environment::get().getWindowManager()->setMainMenuNoReturn(true); + MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + } + return false; + } if(mPtr.getTypeName() == typeid(ESM::NPC).name()) { @@ -1096,6 +1106,10 @@ void CharacterController::kill() if(mAnimation) { + if (mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() + && MWBase::Environment::get().getWorld()->getCamera()->isFirstPerson() ) + MWBase::Environment::get().getWorld()->togglePOV(); + mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->disable(mCurrentIdle); @@ -1103,6 +1117,8 @@ void CharacterController::kill() mIdleState = CharState_None; mCurrentIdle.clear(); + + return true; } void CharacterController::resurrect() diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 9e07fca7d..2a5c7bb03 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -190,7 +190,7 @@ public: void skipAnim(); bool isAnimPlaying(const std::string &groupName); - void kill(); + bool kill(); void resurrect(); bool isDead() const { return mDeathState != CharState_None; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index b216c789f..7d5162747 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -211,6 +211,11 @@ MWRender::SkyManager* RenderingManager::getSkyManager() return mSkyManager; } +MWRender::Camera* RenderingManager::getCamera() const +{ + return mCamera; +} + MWRender::Objects& RenderingManager::getObjects(){ return *mObjects; } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index e5dcf0aeb..d6c1ef6c1 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -98,6 +98,8 @@ public: SkyManager* getSkyManager(); Compositors* getCompositors(); + MWRender::Camera* getCamera() const; + void toggleLight(); bool toggleRenderMode(int mode); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f64d22122..a900d27ab 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -312,6 +312,8 @@ namespace MWWorld mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback); MWBase::Environment::get().getScriptManager()->resetGlobalScripts(); + + MWBase::Environment::get().getWindowManager()->setMainMenuNoReturn(false); } @@ -403,6 +405,11 @@ namespace MWWorld return *mPlayer; } + MWRender::Camera* World::getCamera() const + { + return mRendering->getCamera(); + } + const MWWorld::ESMStore& World::getStore() const { return mStore; @@ -1304,7 +1311,7 @@ namespace MWWorld // inform the GUI about focused object MWWorld::Ptr object = getFacedObject (); - MWBase::Environment::get().getWindowManager()->setFocusObject(object); + MWBase::Environment::get().getWindowManager()->setFocusObject(object); // retrieve object dimensions so we know where to place the floating label if (!object.isEmpty ()) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index c8133441d..2e572d0bb 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -187,6 +187,8 @@ namespace MWWorld virtual Player& getPlayer(); + virtual MWRender::Camera* getCamera() const; + virtual const MWWorld::ESMStore& getStore() const; virtual std::vector& getEsmReader(); From c0d07fbdc9023b76853e2a0b20d9649e9eca1f0a Mon Sep 17 00:00:00 2001 From: mrcheko Date: Sat, 14 Dec 2013 15:07:00 +0200 Subject: [PATCH 002/223] improvement to bug fix http://bugs.openmw.org/issues/428 --- apps/openmw/mwinput/inputmanagerimp.cpp | 45 +++++++++++++------------ apps/openmw/mwmechanics/character.cpp | 19 ++++++----- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 9b7fe98bd..efa326a98 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -180,7 +180,9 @@ namespace MWInput switch (action) { case A_GameMenu: - toggleMainMenu (); + if(!(MWWorld::Class::get(mPlayer->getPlayer()).getCreatureStats(mPlayer->getPlayer()).isDead() + && MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_MainMenu ) ) + toggleMainMenu (); break; case A_Screenshot: screenshot(); @@ -300,7 +302,9 @@ namespace MWInput return; // Disable movement in Gui mode - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + if (MWBase::Environment::get().getWindowManager()->isGuiMode() + || MWWorld::Class::get(mPlayer->getPlayer()).getCreatureStats(mPlayer->getPlayer()).isDead() ) + return; // Configure player movement according to keyboard input. Actual movement will @@ -367,29 +371,28 @@ namespace MWInput } } - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); - if ( !player.getClass().getCreatureStats(player).isDead() ) { - if (mControlSwitch["playerviewswitch"]) { - // work around preview mode toggle when pressing Alt+Tab - if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { + + if (mControlSwitch["playerviewswitch"]) { + // work around preview mode toggle when pressing Alt+Tab + if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { - if (mPreviewPOVDelay <= 0.5 && - (mPreviewPOVDelay += dt) > 0.5) - { - mPreviewPOVDelay = 1.f; - MWBase::Environment::get().getWorld()->togglePreviewMode(true); - } - } else { - if (mPreviewPOVDelay > 0.5) { - //disable preview mode - MWBase::Environment::get().getWorld()->togglePreviewMode(false); - } else if (mPreviewPOVDelay > 0.f) { - MWBase::Environment::get().getWorld()->togglePOV(); - } - mPreviewPOVDelay = 0.f; + if (mPreviewPOVDelay <= 0.5 && + (mPreviewPOVDelay += dt) > 0.5) + { + mPreviewPOVDelay = 1.f; + MWBase::Environment::get().getWorld()->togglePreviewMode(true); } + } else { + if (mPreviewPOVDelay > 0.5) { + //disable preview mode + MWBase::Environment::get().getWorld()->togglePreviewMode(false); + } else if (mPreviewPOVDelay > 0.f) { + MWBase::Environment::get().getWorld()->togglePOV(); + } + mPreviewPOVDelay = 0.f; } } + } if (actionIsActive(A_MoveForward) || actionIsActive(A_MoveBackward) || diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c8eba20d6..1c4979e37 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1061,11 +1061,11 @@ bool CharacterController::kill() if( isDead() ) { //player death animation is over: toggle game menu without 'return' option - if( mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() - && !isAnimPlaying(mCurrentDeath) ) + if( mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() + && !isAnimPlaying(mCurrentDeath) && MWBase::Environment::get().getWindowManager()->getMode () != MWGui::GM_MainMenu ) { - MWBase::Environment::get().getWindowManager()->setMainMenuNoReturn(true); - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + MWWorld::Class::get(mPtr).getCreatureStats(mPtr).setHealth(0); + MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); } return false; } @@ -1106,10 +1106,13 @@ bool CharacterController::kill() if(mAnimation) { - if (mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() - && MWBase::Environment::get().getWorld()->getCamera()->isFirstPerson() ) - MWBase::Environment::get().getWorld()->togglePOV(); - + if (mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() ) + { + MWBase::Environment::get().getWindowManager()->setMainMenuNoReturn(true); + if (MWBase::Environment::get().getWorld()->getCamera()->isFirstPerson() ) + MWBase::Environment::get().getWorld()->togglePOV(); + } + mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->disable(mCurrentIdle); From 8085fcc792a72087d9402ae570623d2842d16b1b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 20 Dec 2013 20:02:42 +0100 Subject: [PATCH 003/223] 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 1197e2014..baf677f8d 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 000000000..01c8d30a7 --- /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 000000000..509e8d8c0 --- /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 cd4653280..bca9f6fb7 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 86a542c5c..9ed526818 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 5ff4a70bf..70cae53c8 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 8f59b0fe7..0fbfef4f1 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 9595ab23b..1590b58df 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 e480e31d1ebcc02771eea694098477511069893f Mon Sep 17 00:00:00 2001 From: mrcheko Date: Fri, 20 Dec 2013 22:37:18 +0200 Subject: [PATCH 004/223] Revert "improvement to bug fix http://bugs.openmw.org/issues/428" This reverts commit c0d07fbdc9023b76853e2a0b20d9649e9eca1f0a. --- apps/openmw/mwinput/inputmanagerimp.cpp | 45 ++++++++++++------------- apps/openmw/mwmechanics/character.cpp | 19 +++++------ 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index efa326a98..9b7fe98bd 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -180,9 +180,7 @@ namespace MWInput switch (action) { case A_GameMenu: - if(!(MWWorld::Class::get(mPlayer->getPlayer()).getCreatureStats(mPlayer->getPlayer()).isDead() - && MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_MainMenu ) ) - toggleMainMenu (); + toggleMainMenu (); break; case A_Screenshot: screenshot(); @@ -302,9 +300,7 @@ namespace MWInput return; // Disable movement in Gui mode - if (MWBase::Environment::get().getWindowManager()->isGuiMode() - || MWWorld::Class::get(mPlayer->getPlayer()).getCreatureStats(mPlayer->getPlayer()).isDead() ) - return; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; // Configure player movement according to keyboard input. Actual movement will @@ -371,28 +367,29 @@ namespace MWInput } } - - if (mControlSwitch["playerviewswitch"]) { - // work around preview mode toggle when pressing Alt+Tab - if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + if ( !player.getClass().getCreatureStats(player).isDead() ) { + if (mControlSwitch["playerviewswitch"]) { + // work around preview mode toggle when pressing Alt+Tab + if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { - if (mPreviewPOVDelay <= 0.5 && - (mPreviewPOVDelay += dt) > 0.5) - { - mPreviewPOVDelay = 1.f; - MWBase::Environment::get().getWorld()->togglePreviewMode(true); + if (mPreviewPOVDelay <= 0.5 && + (mPreviewPOVDelay += dt) > 0.5) + { + mPreviewPOVDelay = 1.f; + MWBase::Environment::get().getWorld()->togglePreviewMode(true); + } + } else { + if (mPreviewPOVDelay > 0.5) { + //disable preview mode + MWBase::Environment::get().getWorld()->togglePreviewMode(false); + } else if (mPreviewPOVDelay > 0.f) { + MWBase::Environment::get().getWorld()->togglePOV(); + } + mPreviewPOVDelay = 0.f; } - } else { - if (mPreviewPOVDelay > 0.5) { - //disable preview mode - MWBase::Environment::get().getWorld()->togglePreviewMode(false); - } else if (mPreviewPOVDelay > 0.f) { - MWBase::Environment::get().getWorld()->togglePOV(); - } - mPreviewPOVDelay = 0.f; } } - } if (actionIsActive(A_MoveForward) || actionIsActive(A_MoveBackward) || diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 1c4979e37..c8eba20d6 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1061,11 +1061,11 @@ bool CharacterController::kill() if( isDead() ) { //player death animation is over: toggle game menu without 'return' option - if( mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() - && !isAnimPlaying(mCurrentDeath) && MWBase::Environment::get().getWindowManager()->getMode () != MWGui::GM_MainMenu ) + if( mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() + && !isAnimPlaying(mCurrentDeath) ) { - MWWorld::Class::get(mPtr).getCreatureStats(mPtr).setHealth(0); - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + MWBase::Environment::get().getWindowManager()->setMainMenuNoReturn(true); + MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); } return false; } @@ -1106,13 +1106,10 @@ bool CharacterController::kill() if(mAnimation) { - if (mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() ) - { - MWBase::Environment::get().getWindowManager()->setMainMenuNoReturn(true); - if (MWBase::Environment::get().getWorld()->getCamera()->isFirstPerson() ) - MWBase::Environment::get().getWorld()->togglePOV(); - } - + if (mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() + && MWBase::Environment::get().getWorld()->getCamera()->isFirstPerson() ) + MWBase::Environment::get().getWorld()->togglePOV(); + mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->disable(mCurrentIdle); From b98cfe2d1b887a8c305945fd40e2d0ee7b34bebf Mon Sep 17 00:00:00 2001 From: mrcheko Date: Fri, 20 Dec 2013 22:39:02 +0200 Subject: [PATCH 005/223] Revert "bug fix http://bugs.openmw.org/issues/428" This reverts commit 8dd930cf97fc4a0fee398a31209fabf24ad7fcb1. --- apps/openmw/mwbase/windowmanager.hpp | 2 -- apps/openmw/mwbase/world.hpp | 3 -- apps/openmw/mwgui/mainmenu.cpp | 13 +------- apps/openmw/mwgui/mainmenu.hpp | 4 --- apps/openmw/mwgui/windowmanagerimp.cpp | 5 --- apps/openmw/mwgui/windowmanagerimp.hpp | 3 -- apps/openmw/mwinput/inputmanagerimp.cpp | 37 +++++++++++------------ apps/openmw/mwmechanics/actors.cpp | 14 +++++---- apps/openmw/mwmechanics/character.cpp | 22 ++------------ apps/openmw/mwmechanics/character.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 5 --- apps/openmw/mwrender/renderingmanager.hpp | 2 -- apps/openmw/mwworld/worldimp.cpp | 9 +----- apps/openmw/mwworld/worldimp.hpp | 2 -- 14 files changed, 31 insertions(+), 92 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 4ffb44615..c47ad066b 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -202,8 +202,6 @@ namespace MWBase virtual void setSpellVisibility(bool visible) = 0; virtual void setSneakVisibility(bool visible) = 0; - void virtual setMainMenuNoReturn(bool noreturn) = 0; - virtual void activateQuickKey (int index) = 0; virtual void setSelectedSpell(const std::string& spellId, int successChancePercent) = 0; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index b1f236bd1..8141af712 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -40,7 +40,6 @@ namespace ESM namespace MWRender { - class Camera; class ExternalRendering; class Animation; } @@ -116,8 +115,6 @@ namespace MWBase virtual MWWorld::Player& getPlayer() = 0; - virtual MWRender::Camera* getCamera() const = 0; - virtual const MWWorld::ESMStore& getStore() const = 0; virtual std::vector& getEsmReader() = 0; diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index e1c72193b..fa7ed2ace 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -17,7 +17,6 @@ namespace MWGui MainMenu::MainMenu(int w, int h) : OEngine::GUI::Layout("openmw_mainmenu.layout") , mButtonBox(0) - , mNoReturn(false) { onResChange(w,h); } @@ -34,8 +33,7 @@ namespace MWGui int curH = 0; std::vector buttons; - if(!mNoReturn) - buttons.push_back("return"); + buttons.push_back("return"); buttons.push_back("newgame"); //buttons.push_back("loadgame"); //buttons.push_back("savegame"); @@ -70,15 +68,6 @@ namespace MWGui mButtonBox->setCoord (w/2 - maxwidth/2, h/2 - curH/2, maxwidth, curH); } - void MainMenu::setNoReturn(bool bNoReturn) - { - if (mNoReturn != bNoReturn) - { - mNoReturn = bNoReturn; - onResChange( Settings::Manager::getInt("resolution x", "Video"), Settings::Manager::getInt("resolution y", "Video") ); - } - } - void MainMenu::onButtonClicked(MyGUI::Widget *sender) { MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f); diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index a686cb020..4e76a64df 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -12,13 +12,9 @@ namespace MWGui void onResChange(int w, int h); - void setNoReturn(bool bNoReturn); - private: MyGUI::Widget* mButtonBox; - bool mNoReturn; - std::map mButtons; void onButtonClicked (MyGUI::Widget* sender); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 69ec11ccc..78986a052 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -880,11 +880,6 @@ namespace MWGui mHud->setSneakVisible(visible); } - void WindowManager::setMainMenuNoReturn(bool noreturn) - { - mMenu->setNoReturn(noreturn); - } - void WindowManager::setDragDrop(bool dragDrop) { mToolTips->setEnabled(!dragDrop); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 3d6972718..4f1960295 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -198,9 +198,6 @@ namespace MWGui virtual void setSpellVisibility(bool visible); virtual void setSneakVisibility(bool visible); - //disables 'return' button in the main menu (used when player is dead) - void virtual setMainMenuNoReturn(bool noreturn); - virtual void activateQuickKey (int index); virtual void setSelectedSpell(const std::string& spellId, int successChancePercent); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 9b7fe98bd..ab2569635 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -367,27 +367,24 @@ namespace MWInput } } - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); - if ( !player.getClass().getCreatureStats(player).isDead() ) { - if (mControlSwitch["playerviewswitch"]) { - // work around preview mode toggle when pressing Alt+Tab - if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { - - if (mPreviewPOVDelay <= 0.5 && - (mPreviewPOVDelay += dt) > 0.5) - { - mPreviewPOVDelay = 1.f; - MWBase::Environment::get().getWorld()->togglePreviewMode(true); - } - } else { - if (mPreviewPOVDelay > 0.5) { - //disable preview mode - MWBase::Environment::get().getWorld()->togglePreviewMode(false); - } else if (mPreviewPOVDelay > 0.f) { - MWBase::Environment::get().getWorld()->togglePOV(); - } - mPreviewPOVDelay = 0.f; + if (mControlSwitch["playerviewswitch"]) { + + // work around preview mode toggle when pressing Alt+Tab + if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { + if (mPreviewPOVDelay <= 0.5 && + (mPreviewPOVDelay += dt) > 0.5) + { + mPreviewPOVDelay = 1.f; + MWBase::Environment::get().getWorld()->togglePreviewMode(true); } + } else { + if (mPreviewPOVDelay > 0.5) { + //disable preview mode + MWBase::Environment::get().getWorld()->togglePreviewMode(false); + } else if (mPreviewPOVDelay > 0.f) { + MWBase::Environment::get().getWorld()->togglePOV(); + } + mPreviewPOVDelay = 0.f; } } } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 5dd294f90..22a641b34 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -570,13 +570,15 @@ namespace MWMechanics continue; } - if (iter->second->kill()) - { - ++mDeathCount[cls.getId(iter->first)]; + if(iter->second->isDead()) + continue; - if(cls.isEssential(iter->first)) - MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}"); - } + iter->second->kill(); + + ++mDeathCount[cls.getId(iter->first)]; + + if(cls.isEssential(iter->first)) + MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}"); } } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c8eba20d6..da3ed2523 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -27,7 +27,6 @@ #include "security.hpp" #include "../mwrender/animation.hpp" -#include "../mwrender/camera.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -1056,19 +1055,10 @@ void CharacterController::forceStateUpdate() } } -bool CharacterController::kill() +void CharacterController::kill() { - if( isDead() ) - { - //player death animation is over: toggle game menu without 'return' option - if( mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() - && !isAnimPlaying(mCurrentDeath) ) - { - MWBase::Environment::get().getWindowManager()->setMainMenuNoReturn(true); - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); - } - return false; - } + if(mDeathState != CharState_None) + return; if(mPtr.getTypeName() == typeid(ESM::NPC).name()) { @@ -1106,10 +1096,6 @@ bool CharacterController::kill() if(mAnimation) { - if (mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() - && MWBase::Environment::get().getWorld()->getCamera()->isFirstPerson() ) - MWBase::Environment::get().getWorld()->togglePOV(); - mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->disable(mCurrentIdle); @@ -1117,8 +1103,6 @@ bool CharacterController::kill() mIdleState = CharState_None; mCurrentIdle.clear(); - - return true; } void CharacterController::resurrect() diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 2a5c7bb03..9e07fca7d 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -190,7 +190,7 @@ public: void skipAnim(); bool isAnimPlaying(const std::string &groupName); - bool kill(); + void kill(); void resurrect(); bool isDead() const { return mDeathState != CharState_None; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 7d5162747..b216c789f 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -211,11 +211,6 @@ MWRender::SkyManager* RenderingManager::getSkyManager() return mSkyManager; } -MWRender::Camera* RenderingManager::getCamera() const -{ - return mCamera; -} - MWRender::Objects& RenderingManager::getObjects(){ return *mObjects; } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index d6c1ef6c1..e5dcf0aeb 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -98,8 +98,6 @@ public: SkyManager* getSkyManager(); Compositors* getCompositors(); - MWRender::Camera* getCamera() const; - void toggleLight(); bool toggleRenderMode(int mode); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a900d27ab..f64d22122 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -312,8 +312,6 @@ namespace MWWorld mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback); MWBase::Environment::get().getScriptManager()->resetGlobalScripts(); - - MWBase::Environment::get().getWindowManager()->setMainMenuNoReturn(false); } @@ -405,11 +403,6 @@ namespace MWWorld return *mPlayer; } - MWRender::Camera* World::getCamera() const - { - return mRendering->getCamera(); - } - const MWWorld::ESMStore& World::getStore() const { return mStore; @@ -1311,7 +1304,7 @@ namespace MWWorld // inform the GUI about focused object MWWorld::Ptr object = getFacedObject (); - MWBase::Environment::get().getWindowManager()->setFocusObject(object); + MWBase::Environment::get().getWindowManager()->setFocusObject(object); // retrieve object dimensions so we know where to place the floating label if (!object.isEmpty ()) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 2e572d0bb..c8133441d 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -187,8 +187,6 @@ namespace MWWorld virtual Player& getPlayer(); - virtual MWRender::Camera* getCamera() const; - virtual const MWWorld::ESMStore& getStore() const; virtual std::vector& getEsmReader(); From f69465d7e0ca6a24f445825d6e0768463699fc1f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 20 Dec 2013 22:31:17 +0100 Subject: [PATCH 006/223] 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 01c8d30a7..f8dcd86a4 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 509e8d8c0..dc2913c22 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 0fbfef4f1..2285790be 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 1590b58df..4a8e1e6f5 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 007/223] 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 2285790be..ddbde099e 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 4a8e1e6f5..9f5cf9f9a 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 008/223] 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 f8dcd86a4..eceaf999b 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 ddbde099e..3a9d82630 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 9f5cf9f9a..1a4a41638 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 009/223] 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 eceaf999b..8eff6ed0b 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 010/223] 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 8eff6ed0b..ff2d6e713 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 dc2913c22..fed662e27 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 011/223] 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 ff2d6e713..59591ca02 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 fed662e27..801a2232b 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 012/223] 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 59591ca02..b299744d6 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 801a2232b..a40ca16a4 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 3a9d82630..6f278cc02 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 1a4a41638..b32b0347a 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 013/223] 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 b299744d6..e86e8db54 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 b12531875..d88361746 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 bca9f6fb7..d8cbb2fc1 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 014/223] 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 e86e8db54..da63dce9f 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 015/223] 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 da63dce9f..b6c99960d 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 a40ca16a4..7e5b761af 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 6f278cc02..98a81c784 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 b32b0347a..f03da9588 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 016/223] 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 b6c99960d..8f871fca2 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 7e5b761af..a4146c4d2 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 98a81c784..28cf28565 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 f03da9588..237c2f30b 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 017/223] 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 28cf28565..0a93d93ec 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 237c2f30b..2f6ea187e 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 018/223] 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 8f871fca2..055244cab 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 a4146c4d2..1c88c8cfe 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 019/223] 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 055244cab..f08aadf86 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 1c88c8cfe..b55db38c6 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 020/223] 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 0a93d93ec..266741155 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 2f6ea187e..6af433be2 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 021/223] 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 f08aadf86..750ef6448 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 b55db38c6..17897fe34 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 022/223] 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 750ef6448..c8a310e9f 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 17897fe34..72af4e0ff 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 99c4f5225..a39a7ebe1 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 023/223] 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 c8a310e9f..03efb59cc 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 72af4e0ff..3a0b2a4b8 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 266741155..83ff79cc8 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 6af433be2..87818c9c9 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 024/223] 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 03efb59cc..589372f8a 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 3a0b2a4b8..c7c418ff6 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 83ff79cc8..8af42703e 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 87818c9c9..6a67ed1c8 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 025/223] 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 589372f8a..12727d49c 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 c7c418ff6..8fd123b06 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 8af42703e..aec20b188 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 6a67ed1c8..02ca53953 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 026/223] 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 12727d49c..0abebc709 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 027/223] 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 0abebc709..e2091de2e 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 8fd123b06..5a0d39ec5 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 aec20b188..7f3e6506b 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 02ca53953..6e7231a24 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 028/223] 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 e2091de2e..d37808810 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 5a0d39ec5..6bffc2b25 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 7f3e6506b..54e2cd12f 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 6e7231a24..6b6e01e01 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 029/223] 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 d37808810..6d06d6151 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 6bffc2b25..d4f7697ae 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 54e2cd12f..9c0a857a5 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 6b6e01e01..8aa3c2522 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 1eac8d64f..08f678b45 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 030/223] 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 6d06d6151..40f7c26d2 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 031/223] 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 40f7c26d2..8ab163fc5 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 032/223] 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 8ab163fc5..44dfbbef7 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 033/223] 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 44dfbbef7..752a57f3e 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 034/223] 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 752a57f3e..abf13ced9 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 d4f7697ae..9e53f2b19 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 d8cbb2fc1..945fa191f 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 035/223] 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 abf13ced9..a6fbe7f80 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 9e53f2b19..c87d80b0f 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 945fa191f..15a7bd181 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 036/223] 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 a6fbe7f80..79f6009da 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 c87d80b0f..1d85dc310 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 037/223] 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 79f6009da..5406ca08e 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 1d85dc310..591e3d335 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 15a7bd181..b5320ff9f 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 038/223] 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 5406ca08e..010fb868c 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 039/223] 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 010fb868c..d2053c1a6 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 040/223] 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 d2053c1a6..ad52c5962 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 041/223] 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 591e3d335..fcf774f14 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 b5320ff9f..c25811ea4 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 70cae53c8..1a21de8f4 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 8aa3c2522..719b4b922 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 042/223] 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 ad52c5962..3ca203bdf 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 c25811ea4..64e39ad2f 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 1a21de8f4..328680d85 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 043/223] 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 9c0a857a5..5af215989 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 044/223] 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 719b4b922..51f548499 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 045/223] 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 3ca203bdf..2b796ccc0 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 d6345bce91e3d65cf69c5f7368e58be348a22763 Mon Sep 17 00:00:00 2001 From: mrcheko Date: Tue, 31 Dec 2013 13:24:20 +0200 Subject: [PATCH 046/223] added npc hit reactions --- apps/openmw/mwclass/npc.cpp | 1 + apps/openmw/mwmechanics/character.cpp | 134 ++++++++++++++------------ apps/openmw/mwmechanics/character.hpp | 11 ++- 3 files changed, 86 insertions(+), 60 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 4187aa8c1..87d98a578 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -604,6 +604,7 @@ namespace MWClass // something, alert the character controller, scripts, etc. MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); + getCreatureStats(ptr).setAttacked(true); if(object.isEmpty()) { diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 17eff3d02..f4d6feab6 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -65,15 +65,24 @@ struct StateInfo { const char groupname[32]; }; -static const StateInfo sDeathList[] = { - { CharState_Death1, "death1" }, - { CharState_Death2, "death2" }, - { CharState_Death3, "death3" }, - { CharState_Death4, "death4" }, - { CharState_Death5, "death5" }, - { CharState_SwimDeath, "swimdeath" }, +static const std::string sDeathList[] = { + "death1" , + "death2" , + "death3" , + "death4" , + "death5" , + "swimdeath", }; -static const StateInfo *sDeathListEnd = &sDeathList[sizeof(sDeathList)/sizeof(sDeathList[0])]; +static const int sDeathListSize = sizeof(sDeathList)/sizeof(sDeathList[0]); + +static const std::string sHitList[] = { + "hit1" , + "hit2" , + "hit3" , + "hit4" , + "hit5" , +}; +static const int sHitListSize = sizeof(sHitList)/sizeof(sHitList[0]); static const StateInfo sMovementList[] = { { CharState_WalkForward, "walkforward" }, @@ -150,6 +159,38 @@ public: void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force) { + if(MWWorld::Class::get(mPtr).getCreatureStats(mPtr).getAttacked()) + { + mHitState = CharState_Hit; + MWWorld::Class::get(mPtr).getCreatureStats(mPtr).setAttacked(false); + + if(!mAnimation->isPlaying(mCurrentHit)) + { + mAnimation->disable(mCurrentHit); + if(mJumpState != JumpState_None && !MWBase::Environment::get().getWorld()->isFlying(mPtr) + && !MWBase::Environment::get().getWorld()->isSwimming(mPtr) ) + mCurrentHit = "knockdown"; + else + { + int iHit = rand() % sHitListSize; + mCurrentHit = sHitList[iHit]; + } + mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::Group_All, false, 1, "start", "stop", 0.0f, 0); + if(mUpperBodyState == UpperCharState_WeapEquiped) + mUpdateAfterHit = false; + else + mUpdateAfterHit = true; + } + return; + } + else if(!mAnimation->isPlaying(mCurrentHit)) + { + mAnimation->disable(mCurrentHit); + mCurrentHit.erase(); + mHitState = CharState_None; + mUpdateAfterHit = true; + } + const WeaponInfo *weap = std::find_if(sWeaponTypeList, sWeaponTypeListEnd, FindWeaponType(mWeaponType)); if(force || idle != mIdleState) @@ -338,6 +379,23 @@ MWWorld::ContainerStoreIterator CharacterController::getActiveWeapon(NpcStats &s return inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); } +void CharacterController::playRandomDeath(float startpoint) +{ + if(MWBase::Environment::get().getWorld()->isSwimming(mPtr)) + { + mDeathState = CharState_SwimDeath; + mCurrentDeath = sDeathList[sDeathListSize-1]; //last in the list is 'swimdeath' + } + else + { + int num = rand() % (sDeathListSize-1); + mDeathState = static_cast(CharState_Death1 + num); + mCurrentDeath = sDeathList[num]; + } + + mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, + false, 1.0f, "start", "stop", 0.0f, 0); +} CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim) : mPtr(ptr) @@ -346,6 +404,8 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim , mMovementState(CharState_None) , mMovementSpeed(0.0f) , mDeathState(CharState_None) + , mHitState(CharState_None) + , mUpdateAfterHit(true) , mUpperBodyState(UpperCharState_Nothing) , mJumpState(JumpState_None) , mWeaponType(WeapType_None) @@ -392,13 +452,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim refreshCurrentAnims(mIdleState, mMovementState, true); if(mDeathState != CharState_None) { - const StateInfo *state = std::find_if(sDeathList, sDeathListEnd, FindCharState(mDeathState)); - if(state == sDeathListEnd) - throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(mDeathState)); - - mCurrentDeath = state->groupname; - mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, - false, 1.0f, "start", "stop", 1.0f, 0); + playRandomDeath(1.0f); } } @@ -766,6 +820,8 @@ void CharacterController::update(float duration) bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); bool flying = world->isFlying(mPtr); Ogre::Vector3 vec = cls.getMovementVector(mPtr); + if(mHitState != CharState_None && mJumpState == JumpState_None) + vec = Ogre::Vector3(0.0f); Ogre::Vector3 rot = cls.getRotationVector(mPtr); mMovementSpeed = cls.getSpeed(mPtr); @@ -778,6 +834,7 @@ void CharacterController::update(float duration) isrunning = isrunning && std::abs(vec[0])+std::abs(vec[1]) > 0.0f; + // advance athletics if(std::abs(vec[0])+std::abs(vec[1]) > 0.0f && mPtr.getRefData().getHandle() == "player") { @@ -951,7 +1008,7 @@ void CharacterController::update(float duration) } } - if(cls.isNpc()) + if(cls.isNpc() && mUpdateAfterHit) forcestateupdate = updateNpcState(onground, inwater, isrunning, sneak) || forcestateupdate; refreshCurrentAnims(idlestate, movestate, forcestateupdate); @@ -1055,14 +1112,7 @@ void CharacterController::forceStateUpdate() refreshCurrentAnims(mIdleState, mMovementState, true); if(mDeathState != CharState_None) { - const StateInfo *state = std::find_if(sDeathList, sDeathListEnd, FindCharState(mDeathState)); - if(state == sDeathListEnd) - throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(mDeathState)); - - mCurrentDeath = state->groupname; - if(!mAnimation->getInfo(mCurrentDeath)) - mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, - false, 1.0f, "start", "stop", 0.0f, 0); + playRandomDeath(0.0f); } } @@ -1071,44 +1121,10 @@ void CharacterController::kill() if(mDeathState != CharState_None) return; - if(mPtr.getTypeName() == typeid(ESM::NPC).name()) - { - const StateInfo *state = NULL; - if(MWBase::Environment::get().getWorld()->isSwimming(mPtr)) - { - mDeathState = CharState_SwimDeath; - state = std::find_if(sDeathList, sDeathListEnd, FindCharState(mDeathState)); - if(state == sDeathListEnd) - throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(mDeathState)); - } - - static const CharacterState deathstates[5] = { - CharState_Death1, CharState_Death2, CharState_Death3, CharState_Death4, CharState_Death5 - }; - std::vector states(&deathstates[0], &deathstates[5]); - - while(states.size() > 1 && (!state || !mAnimation->hasAnimation(state->groupname))) - { - int pos = (int)(rand()/((double)RAND_MAX+1.0)*states.size()); - mDeathState = states[pos]; - states.erase(states.begin()+pos); - - state = std::find_if(sDeathList, sDeathListEnd, FindCharState(mDeathState)); - if(state == sDeathListEnd) - throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(mDeathState)); - } - mCurrentDeath = state->groupname; - } - else - { - mDeathState = CharState_Death1; - mCurrentDeath = "death1"; - } + playRandomDeath(0.0f); if(mAnimation) { - mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, - false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->disable(mCurrentIdle); } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 817fa2fd5..e0b065cec 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -28,6 +28,7 @@ enum Priority { Priority_Default, Priority_Jump, Priority_Movement, + Priority_Hit, Priority_Weapon, Priority_Torch, @@ -87,7 +88,9 @@ enum CharacterState { CharState_Death3, CharState_Death4, CharState_Death5, - CharState_SwimDeath + CharState_SwimDeath, + + CharState_Hit }; enum WeaponType { @@ -142,6 +145,10 @@ class CharacterController CharacterState mDeathState; std::string mCurrentDeath; + CharacterState mHitState; + std::string mCurrentHit; + bool mUpdateAfterHit;//don't allow attack if it hadn't been started before actor got hit + UpperBodyCharacterState mUpperBodyState; JumpingState mJumpState; @@ -172,6 +179,8 @@ class CharacterController void updateVisibility(); + void playRandomDeath(float startpoint); + public: CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim); virtual ~CharacterController(); From a8fb1ae51c89c21aadaf2e4a3c263a2c6efa8f49 Mon Sep 17 00:00:00 2001 From: mrcheko Date: Tue, 31 Dec 2013 17:55:04 +0200 Subject: [PATCH 047/223] improved, added knockdown after falling --- apps/openmw/mwmechanics/character.cpp | 27 ++++++++++++++------------- apps/openmw/mwmechanics/character.hpp | 1 - 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index f4d6feab6..a7ae29824 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -166,7 +166,6 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat if(!mAnimation->isPlaying(mCurrentHit)) { - mAnimation->disable(mCurrentHit); if(mJumpState != JumpState_None && !MWBase::Environment::get().getWorld()->isFlying(mPtr) && !MWBase::Environment::get().getWorld()->isSwimming(mPtr) ) mCurrentHit = "knockdown"; @@ -175,20 +174,13 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat int iHit = rand() % sHitListSize; mCurrentHit = sHitList[iHit]; } - mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::Group_All, false, 1, "start", "stop", 0.0f, 0); - if(mUpperBodyState == UpperCharState_WeapEquiped) - mUpdateAfterHit = false; - else - mUpdateAfterHit = true; + mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::Group_All, true, 1, "start", "stop", 0.0f, 0); } - return; } else if(!mAnimation->isPlaying(mCurrentHit)) { - mAnimation->disable(mCurrentHit); mCurrentHit.erase(); mHitState = CharState_None; - mUpdateAfterHit = true; } const WeaponInfo *weap = std::find_if(sWeaponTypeList, sWeaponTypeListEnd, FindWeaponType(mWeaponType)); @@ -405,7 +397,6 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim , mMovementSpeed(0.0f) , mDeathState(CharState_None) , mHitState(CharState_None) - , mUpdateAfterHit(true) , mUpperBodyState(UpperCharState_Nothing) , mJumpState(JumpState_None) , mWeaponType(WeapType_None) @@ -554,7 +545,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun bool animPlaying; if(stats.getAttackingOrSpell()) { - if(mUpperBodyState == UpperCharState_WeapEquiped) + if(mUpperBodyState == UpperCharState_WeapEquiped && mHitState == CharState_None) { MWBase::Environment::get().getWorld()->breakInvisibility(mPtr); mAttackType.clear(); @@ -718,9 +709,18 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun if(mUpperBodyState == UpperCharState_EquipingWeap || mUpperBodyState == UpperCharState_FollowStartToFollowStop || mUpperBodyState == UpperCharState_CastingSpell) + { mUpperBodyState = UpperCharState_WeapEquiped; + //don't allow to continue playing hit animation after actor had attacked during it + if(mHitState != CharState_None) + { + mAnimation->disable(mCurrentHit); + mCurrentHit.clear(); + mHitState = CharState_None; + } + } else if(mUpperBodyState == UpperCharState_UnEquipingWeap) - mUpperBodyState = UpperCharState_Nothing; + mUpperBodyState = UpperCharState_Nothing; } else if(complete >= 1.0f) { @@ -938,6 +938,7 @@ void CharacterController::update(float duration) int realHealthLost = healthLost * (1.0f - 0.25 * fatigueTerm); health.setCurrent(health.getCurrent() - realHealthLost); cls.getCreatureStats(mPtr).setHealth(health); + cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), true); // report acrobatics progression if (mPtr.getRefData().getHandle() == "player") @@ -1008,7 +1009,7 @@ void CharacterController::update(float duration) } } - if(cls.isNpc() && mUpdateAfterHit) + if(cls.isNpc()) forcestateupdate = updateNpcState(onground, inwater, isrunning, sneak) || forcestateupdate; refreshCurrentAnims(idlestate, movestate, forcestateupdate); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index e0b065cec..4974b7c08 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -147,7 +147,6 @@ class CharacterController CharacterState mHitState; std::string mCurrentHit; - bool mUpdateAfterHit;//don't allow attack if it hadn't been started before actor got hit UpperBodyCharacterState mUpperBodyState; From 09a0a69b04cf80645dc1bb708f19b11c2bdb715f Mon Sep 17 00:00:00 2001 From: mrcheko Date: Wed, 1 Jan 2014 21:40:31 +0200 Subject: [PATCH 048/223] more improvements --- apps/openmw/mwmechanics/character.cpp | 159 +++++++++++++++++--------- apps/openmw/mwmechanics/character.hpp | 3 + apps/openmw/mwrender/animation.cpp | 15 ++- apps/openmw/mwrender/animation.hpp | 1 + 4 files changed, 124 insertions(+), 54 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index a7ae29824..4a8cf5ea8 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -81,6 +81,7 @@ static const std::string sHitList[] = { "hit3" , "hit4" , "hit5" , + "knockdown" , }; static const int sHitListSize = sizeof(sHitList)/sizeof(sHitList[0]); @@ -161,23 +162,23 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat { if(MWWorld::Class::get(mPtr).getCreatureStats(mPtr).getAttacked()) { - mHitState = CharState_Hit; MWWorld::Class::get(mPtr).getCreatureStats(mPtr).setAttacked(false); - if(!mAnimation->isPlaying(mCurrentHit)) + if(mHitState == CharState_None) { + mHitState = CharState_Hit; if(mJumpState != JumpState_None && !MWBase::Environment::get().getWorld()->isFlying(mPtr) && !MWBase::Environment::get().getWorld()->isSwimming(mPtr) ) - mCurrentHit = "knockdown"; + mCurrentHit = sHitList[sHitListSize-1]; //knockdown animation else { - int iHit = rand() % sHitListSize; + int iHit = rand() % (sHitListSize-1); mCurrentHit = sHitList[iHit]; } mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::Group_All, true, 1, "start", "stop", 0.0f, 0); } } - else if(!mAnimation->isPlaying(mCurrentHit)) + else if(mHitState != CharState_None && !mAnimation->isPlaying(mCurrentHit)) { mCurrentHit.erase(); mHitState = CharState_None; @@ -458,9 +459,27 @@ void CharacterController::updatePtr(const MWWorld::Ptr &ptr) } +void CharacterController::playWeaponAnim(const std::string& start, const std::string& stop, + float speed, bool autoDisable, bool disablePrevious, float startpoint, bool currentWeapon) +{ + std::string weapgroup; + if (currentWeapon) + weapgroup = mCurrentWeapon; + else + getWeaponGroup(mWeaponType, weapgroup); + + if (disablePrevious) + mAnimation->disable(weapgroup); + + mAnimation->play(weapgroup, Priority_Weapon, + MWRender::Animation::Group_All, autoDisable, + speed, start, stop, + startpoint, 0); +} + bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrunning, bool sneak) { - const MWWorld::Class &cls = MWWorld::Class::get(mPtr); + const MWWorld::Class &cls = MWWorld::Class::get(mPtr); NpcStats &stats = cls.getNpcStats(mPtr); WeaponType weaptype = WeapType_None; MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); @@ -490,6 +509,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun { getWeaponGroup(weaptype, weapgroup); mAnimation->showWeapons(false); + mAnimation->play(weapgroup, Priority_Weapon, MWRender::Animation::Group_UpperBody, true, 1.0f, "equip start", "equip stop", 0.0f, 0); @@ -642,7 +662,14 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun { if(mWeaponType == WeapType_Crossbow || mWeaponType == WeapType_BowAndArrow || mWeaponType == WeapType_ThowWeapon) + { mAttackType = "shoot"; + mAnimation->play(mCurrentWeapon, Priority_Weapon, + MWRender::Animation::Group_UpperBody, false, + weapSpeed, mAttackType+" start", mAttackType+" attach", + 0.0f, 0); + mUpperBodyState = UpperCharState_StartToAttach; + } else { int attackType = stats.getAttackType(); @@ -655,13 +682,13 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun mAttackType = "slash"; else mAttackType = "thrust"; - } mAnimation->play(mCurrentWeapon, Priority_Weapon, MWRender::Animation::Group_UpperBody, false, weapSpeed, mAttackType+" start", mAttackType+" min attack", 0.0f, 0); mUpperBodyState = UpperCharState_StartToMinAttack; + } } } animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); @@ -711,79 +738,105 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun mUpperBodyState == UpperCharState_CastingSpell) { mUpperBodyState = UpperCharState_WeapEquiped; - //don't allow to continue playing hit animation after actor had attacked during it - if(mHitState != CharState_None) + + if(mHitState != CharState_None) //don't allow to continue playing hit animation after actor had attacked during it { - mAnimation->disable(mCurrentHit); + mAnimation->changeGroups(mCurrentHit, MWRender::Animation::Group_LowerBody); mCurrentHit.clear(); mHitState = CharState_None; } } else if(mUpperBodyState == UpperCharState_UnEquipingWeap) - mUpperBodyState = UpperCharState_Nothing; + mUpperBodyState = UpperCharState_Nothing; } else if(complete >= 1.0f) { - if(mUpperBodyState == UpperCharState_StartToMinAttack) + std::string start, stop; + switch(mUpperBodyState) { - mAnimation->disable(mCurrentWeapon); - mAnimation->play(mCurrentWeapon, Priority_Weapon, - MWRender::Animation::Group_UpperBody, false, - weapSpeed, mAttackType+" min attack", mAttackType+" max attack", - 0.0f, 0); - mUpperBodyState = UpperCharState_MinAttackToMaxAttack; + case UpperCharState_StartToMinAttack: + start = mAttackType+" min attack"; + stop = mAttackType+" max attack"; + mUpperBodyState = UpperCharState_MinAttackToMaxAttack; + break; + case UpperCharState_StartToAttach: //only bows, crossbows, throwing weapons here + start = mAttackType+" attach"; + stop = mAttackType+" min attack"; + mUpperBodyState = UpperCharState_StartToMinAttack; + break; + case UpperCharState_MaxAttackToMinHit: + if(mAttackType == "shoot") + { + start = mAttackType+" min hit"; + stop = mAttackType+" release"; + } + else + { + start = mAttackType+" min hit"; + stop = mAttackType+" hit"; + } + mUpperBodyState = UpperCharState_MinHitToHit; + break; + case UpperCharState_MinHitToHit: + if(mAttackType == "shoot") + { + start = mAttackType+" follow start"; + stop = mAttackType+" follow stop"; + } + else + { + float str = stats.getAttackStrength(); + start = mAttackType+((str < 0.5f) ? " small follow start" + : (str < 1.0f) ? " medium follow start" + : " large follow start"); + stop = mAttackType+((str < 0.5f) ? " small follow stop" + : (str < 1.0f) ? " medium follow stop" + : " large follow stop"); + } + mUpperBodyState = UpperCharState_FollowStartToFollowStop; + break; + default: + break; } - else if(mUpperBodyState == UpperCharState_MaxAttackToMinHit) + + if(!start.empty()) { mAnimation->disable(mCurrentWeapon); - if(mAttackType == "shoot") - mAnimation->play(mCurrentWeapon, Priority_Weapon, - MWRender::Animation::Group_UpperBody, false, - weapSpeed, mAttackType+" min hit", mAttackType+" follow start", - 0.0f, 0); - else - mAnimation->play(mCurrentWeapon, Priority_Weapon, - MWRender::Animation::Group_UpperBody, false, - weapSpeed, mAttackType+" min hit", mAttackType+" hit", - 0.0f, 0); - mUpperBodyState = UpperCharState_MinHitToHit; - } - else if(mUpperBodyState == UpperCharState_MinHitToHit) - { - mAnimation->disable(mCurrentWeapon); - if(mAttackType == "shoot") - mAnimation->play(mCurrentWeapon, Priority_Weapon, - MWRender::Animation::Group_UpperBody, true, - weapSpeed, mAttackType+" follow start", mAttackType+" follow stop", - 0.0f, 0); - else - { - float str = stats.getAttackStrength(); - std::string start = mAttackType+((str < 0.5f) ? " small follow start" - : (str < 1.0f) ? " medium follow start" - : " large follow start"); - std::string stop = mAttackType+((str < 0.5f) ? " small follow stop" - : (str < 1.0f) ? " medium follow stop" - : " large follow stop"); + if (mUpperBodyState == UpperCharState_FollowStartToFollowStop) mAnimation->play(mCurrentWeapon, Priority_Weapon, MWRender::Animation::Group_UpperBody, true, weapSpeed, start, stop, 0.0f, 0); - } - mUpperBodyState = UpperCharState_FollowStartToFollowStop; + else + mAnimation->play(mCurrentWeapon, Priority_Weapon, + MWRender::Animation::Group_UpperBody, false, + weapSpeed, start, stop, 0.0f, 0); } } + //if playing combat animation and lowerbody is not busy switch to whole body animation + if(weaptype != WeaponType::WeapType_None && complete>0.0f) + { + if( mMovementState != CharState_None || + mJumpState != JumpState_None || + mHitState != CharState_None || + MWBase::Environment::get().getWorld()->isSwimming(mPtr) || + cls.getStance(mPtr, MWWorld::Class::Sneak)) + mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_UpperBody); + else + mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_All); + } + MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name() && mWeaponType != WeapType_Spell && mWeaponType != WeapType_HandToHand) { - mAnimation->play("torch", Priority_Torch, MWRender::Animation::Group_LeftArm, - false, 1.0f, "start", "stop", 0.0f, (~(size_t)0)); + mAnimation->play("torch", Priority_Torch, MWRender::Animation::Group_LeftArm, + false, 1.0f, "start", "stop", 0.0f, (~(size_t)0)); } else if (mAnimation->isPlaying("torch")) { - mAnimation->disable("torch"); + mAnimation->disable("torch"); } return forcestateupdate; diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 4974b7c08..3cf34b747 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -114,6 +114,7 @@ enum UpperBodyCharacterState { UpperCharState_UnEquipingWeap, UpperCharState_WeapEquiped, UpperCharState_StartToMinAttack, + UpperCharState_StartToAttach, UpperCharState_MinAttackToMaxAttack, UpperCharState_MaxAttackToMinHit, UpperCharState_MinHitToHit, @@ -175,6 +176,8 @@ class CharacterController void clearAnimQueue(); bool updateNpcState(bool onground, bool inwater, bool isrunning, bool sneak); + void playWeaponAnim(const std::string& start, const std::string& stop, + float speed = 1.0f, bool autoDisable = true, bool disablePrevious = false, float startpoint = 0.0f, bool currentWeapon = true); void updateVisibility(); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index de86bcfa7..c7537aa90 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -672,7 +672,20 @@ void Animation::handleTextKey(AnimState &state, const std::string &groupname, co MWBase::Environment::get().getWorld()->castSpell(mPtr); } - +void Animation::changeGroups(const std::string &groupname, int groups) +{ + AnimStateMap::iterator stateiter = mStates.begin(); + stateiter = mStates.find(groupname); + if(stateiter != mStates.end()) + { + if(stateiter->second.mGroups != groups) + { + stateiter->second.mGroups = groups; + resetActiveGroups(); + } + return; + } +} void Animation::play(const std::string &groupname, int priority, int groups, bool autodisable, float speedmult, const std::string &start, const std::string &stop, float startpoint, size_t loops) { if(!mSkelBase || mAnimSources.empty()) diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 72d1c100e..f5f79dd72 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -272,6 +272,7 @@ public: * \param groupname Animation group to disable. */ void disable(const std::string &groupname); + void changeGroups(const std::string &groupname, int group); /** Retrieves the velocity (in units per second) that the animation will move. */ float getVelocity(const std::string &groupname) const; From 16e10cc702e8f133172a1bd3570ef2135505c376 Mon Sep 17 00:00:00 2001 From: mrcheko Date: Wed, 1 Jan 2014 22:46:29 +0200 Subject: [PATCH 049/223] error fix --- apps/openmw/mwmechanics/character.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 4a8cf5ea8..aa1a812aa 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -814,7 +814,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun } //if playing combat animation and lowerbody is not busy switch to whole body animation - if(weaptype != WeaponType::WeapType_None && complete>0.0f) + if(weaptype != WeapType_None && complete>0.0f) { if( mMovementState != CharState_None || mJumpState != JumpState_None || From 79e972bdb6b9d5545347a2ef8c2708adebaf34a8 Mon Sep 17 00:00:00 2001 From: mrcheko Date: Thu, 2 Jan 2014 21:54:41 +0200 Subject: [PATCH 050/223] resolved accompanying minor problems --- apps/openmw/mwmechanics/character.cpp | 127 +++++++++++++------------- apps/openmw/mwmechanics/character.hpp | 8 +- 2 files changed, 67 insertions(+), 68 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index aa1a812aa..8e2e348b9 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -160,28 +160,34 @@ public: void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force) { - if(MWWorld::Class::get(mPtr).getCreatureStats(mPtr).getAttacked()) + if(MWWorld::Class::get(mPtr).isActor()) { - MWWorld::Class::get(mPtr).getCreatureStats(mPtr).setAttacked(false); - - if(mHitState == CharState_None) + if(MWWorld::Class::get(mPtr).getCreatureStats(mPtr).getAttacked()) { - mHitState = CharState_Hit; - if(mJumpState != JumpState_None && !MWBase::Environment::get().getWorld()->isFlying(mPtr) - && !MWBase::Environment::get().getWorld()->isSwimming(mPtr) ) - mCurrentHit = sHitList[sHitListSize-1]; //knockdown animation - else + MWWorld::Class::get(mPtr).getCreatureStats(mPtr).setAttacked(false); + + if(mHitState == CharState_None) { - int iHit = rand() % (sHitListSize-1); - mCurrentHit = sHitList[iHit]; + mHitState = CharState_Hit; + if(mJumpState != JumpState_None && !MWBase::Environment::get().getWorld()->isFlying(mPtr) + && !MWBase::Environment::get().getWorld()->isSwimming(mPtr) ) + { + mCurrentHit = sHitList[sHitListSize-1]; //knockdown animation + mHitState = CharState_KnockDown; + } + else + { + int iHit = rand() % (sHitListSize-1); + 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)) - { - mCurrentHit.erase(); - mHitState = CharState_None; + else if(mHitState != CharState_None && !mAnimation->isPlaying(mCurrentHit)) + { + mCurrentHit.erase(); + mHitState = CharState_None; + } } const WeaponInfo *weap = std::find_if(sWeaponTypeList, sWeaponTypeListEnd, FindWeaponType(mWeaponType)); @@ -374,16 +380,24 @@ MWWorld::ContainerStoreIterator CharacterController::getActiveWeapon(NpcStats &s void CharacterController::playRandomDeath(float startpoint) { - if(MWBase::Environment::get().getWorld()->isSwimming(mPtr)) + if(MWWorld::Class::get(mPtr).isNpc()) { - mDeathState = CharState_SwimDeath; - mCurrentDeath = sDeathList[sDeathListSize-1]; //last in the list is 'swimdeath' + if(MWBase::Environment::get().getWorld()->isSwimming(mPtr)) + { + mDeathState = CharState_SwimDeath; + mCurrentDeath = sDeathList[sDeathListSize-1]; //last in the list is 'swimdeath' + } + else + { + int num = rand() % (sDeathListSize-1); + mDeathState = static_cast(CharState_Death1 + num); + mCurrentDeath = sDeathList[num]; + } } else { - int num = rand() % (sDeathListSize-1); - mDeathState = static_cast(CharState_Death1 + num); - mCurrentDeath = sDeathList[num]; + mDeathState = CharState_Death1; + mCurrentDeath = "death1"; } mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, @@ -442,6 +456,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim } refreshCurrentAnims(mIdleState, mMovementState, true); + if(mDeathState != CharState_None) { playRandomDeath(1.0f); @@ -458,25 +473,6 @@ void CharacterController::updatePtr(const MWWorld::Ptr &ptr) mPtr = ptr; } - -void CharacterController::playWeaponAnim(const std::string& start, const std::string& stop, - float speed, bool autoDisable, bool disablePrevious, float startpoint, bool currentWeapon) -{ - std::string weapgroup; - if (currentWeapon) - weapgroup = mCurrentWeapon; - else - getWeaponGroup(mWeaponType, weapgroup); - - if (disablePrevious) - mAnimation->disable(weapgroup); - - mAnimation->play(weapgroup, Priority_Weapon, - MWRender::Animation::Group_All, autoDisable, - speed, start, stop, - startpoint, 0); -} - bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrunning, bool sneak) { const MWWorld::Class &cls = MWWorld::Class::get(mPtr); @@ -662,14 +658,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun { if(mWeaponType == WeapType_Crossbow || mWeaponType == WeapType_BowAndArrow || mWeaponType == WeapType_ThowWeapon) - { mAttackType = "shoot"; - mAnimation->play(mCurrentWeapon, Priority_Weapon, - MWRender::Animation::Group_UpperBody, false, - weapSpeed, mAttackType+" start", mAttackType+" attach", - 0.0f, 0); - mUpperBodyState = UpperCharState_StartToAttach; - } else { int attackType = stats.getAttackType(); @@ -682,13 +671,13 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun mAttackType = "slash"; else mAttackType = "thrust"; + } mAnimation->play(mCurrentWeapon, Priority_Weapon, MWRender::Animation::Group_UpperBody, false, weapSpeed, mAttackType+" start", mAttackType+" min attack", 0.0f, 0); - mUpperBodyState = UpperCharState_StartToMinAttack; - } + mUpperBodyState = UpperCharState_StartToMinAttack; } } animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); @@ -739,11 +728,13 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun { mUpperBodyState = UpperCharState_WeapEquiped; - if(mHitState != CharState_None) //don't allow to continue playing hit animation after actor had attacked during it + //don't allow to continue playing hit animation on UpperBody after actor had attacked during it + if(mHitState != CharState_None) { mAnimation->changeGroups(mCurrentHit, MWRender::Animation::Group_LowerBody); - mCurrentHit.clear(); + //commenting out following 2 lines will give a bit different combat dynamics(slower) mHitState = CharState_None; + mCurrentHit.clear(); } } else if(mUpperBodyState == UpperCharState_UnEquipingWeap) @@ -759,11 +750,6 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun stop = mAttackType+" max attack"; mUpperBodyState = UpperCharState_MinAttackToMaxAttack; break; - case UpperCharState_StartToAttach: //only bows, crossbows, throwing weapons here - start = mAttackType+" attach"; - stop = mAttackType+" min attack"; - mUpperBodyState = UpperCharState_StartToMinAttack; - break; case UpperCharState_MaxAttackToMinHit: if(mAttackType == "shoot") { @@ -813,17 +799,27 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun } } + if(!animPlaying) + { + mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f)); + } //if playing combat animation and lowerbody is not busy switch to whole body animation - if(weaptype != WeapType_None && complete>0.0f) + if(weaptype != WeapType_None && animPlaying) { if( mMovementState != CharState_None || mJumpState != JumpState_None || mHitState != CharState_None || MWBase::Environment::get().getWorld()->isSwimming(mPtr) || cls.getStance(mPtr, MWWorld::Class::Sneak)) + { + mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f)); mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_UpperBody); + } else + { + mAnimation->setAccumulation(Ogre::Vector3(0.0f, 0.0f, 0.0f)); mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_All); + } } MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); @@ -1067,8 +1063,13 @@ void CharacterController::update(float duration) refreshCurrentAnims(idlestate, movestate, forcestateupdate); - rot *= duration * Ogre::Math::RadiansToDegrees(1.0f); - world->rotateObject(mPtr, rot.x, rot.y, rot.z, true); + if(mHitState != CharState_KnockDown) + { + rot *= duration * Ogre::Math::RadiansToDegrees(1.0f); + world->rotateObject(mPtr, rot.x, rot.y, rot.z, true); + } + else + world->rotateObject(mPtr, rot.x, rot.y, 0.0f, true); world->queueMovement(mPtr, vec); movement = vec; @@ -1166,7 +1167,7 @@ void CharacterController::forceStateUpdate() refreshCurrentAnims(mIdleState, mMovementState, true); if(mDeathState != CharState_None) { - playRandomDeath(0.0f); + playRandomDeath(); } } @@ -1175,7 +1176,7 @@ void CharacterController::kill() if(mDeathState != CharState_None) return; - playRandomDeath(0.0f); + playRandomDeath(); if(mAnimation) { diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 3cf34b747..b7c29e9ef 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -90,7 +90,8 @@ enum CharacterState { CharState_Death5, CharState_SwimDeath, - CharState_Hit + CharState_Hit, + CharState_KnockDown }; enum WeaponType { @@ -114,7 +115,6 @@ enum UpperBodyCharacterState { UpperCharState_UnEquipingWeap, UpperCharState_WeapEquiped, UpperCharState_StartToMinAttack, - UpperCharState_StartToAttach, UpperCharState_MinAttackToMaxAttack, UpperCharState_MaxAttackToMinHit, UpperCharState_MinHitToHit, @@ -176,12 +176,10 @@ class CharacterController void clearAnimQueue(); bool updateNpcState(bool onground, bool inwater, bool isrunning, bool sneak); - void playWeaponAnim(const std::string& start, const std::string& stop, - float speed = 1.0f, bool autoDisable = true, bool disablePrevious = false, float startpoint = 0.0f, bool currentWeapon = true); void updateVisibility(); - void playRandomDeath(float startpoint); + void playRandomDeath(float startpoint = 0.0f); public: CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim); From 8201c97abf3a62f662790e556c44877541ad587b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 2 Jan 2014 20:20:18 +0100 Subject: [PATCH 051/223] 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 2b796ccc0..0b09f1f5d 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 fcf774f14..43bb54fa7 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 052/223] 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 0b09f1f5d..65bee314c 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 43bb54fa7..feeb32e6a 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 5af215989..65990c1d4 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 51f548499..f82d151b4 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 053/223] 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 65bee314c..3f4d80db8 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 054/223] 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 3f4d80db8..73f316677 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 18d4cdb2ac56ec7c5929f157ea8e2a34bb8ad618 Mon Sep 17 00:00:00 2001 From: Dmitriy 'Endorph' Shkurskiy Date: Sat, 4 Jan 2014 07:27:50 +0200 Subject: [PATCH 055/223] Fix for VS2010-Debug: manual assignment operator and cctor added for MMWorld::ContainerStoreIterator --- apps/openmw/mwworld/containerstore.cpp | 40 ++++++++++++++++++++++++++ apps/openmw/mwworld/containerstore.hpp | 8 ++++++ 2 files changed, 48 insertions(+) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 686e790a3..39fda7ab9 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -555,6 +555,11 @@ MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *contain MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) : mType(MWWorld::ContainerStore::Type_Weapon), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mWeapon(iterator){} +MWWorld::ContainerStoreIterator::ContainerStoreIterator( const ContainerStoreIterator& src ) +{ + copy(src); +} + void MWWorld::ContainerStoreIterator::incType() { if (mType==0) @@ -807,6 +812,41 @@ const MWWorld::ContainerStore *MWWorld::ContainerStoreIterator::getContainerStor return mContainer; } +void MWWorld::ContainerStoreIterator::copy(const ContainerStoreIterator& src) +{ + mType = src.mType; + mMask = src.mMask; + mContainer = src.mContainer; + mPtr = src.mPtr; + + switch (mType) + { + case MWWorld::ContainerStore::Type_Potion: mPotion = src.mPotion; break; + case MWWorld::ContainerStore::Type_Apparatus: mApparatus = src.mApparatus; break; + case MWWorld::ContainerStore::Type_Armor: mArmor = src.mArmor; break; + case MWWorld::ContainerStore::Type_Book: mBook = src.mBook; break; + case MWWorld::ContainerStore::Type_Clothing: mClothing = src.mClothing; break; + case MWWorld::ContainerStore::Type_Ingredient: mIngredient = src.mIngredient; break; + case MWWorld::ContainerStore::Type_Light: mLight = src.mLight; break; + case MWWorld::ContainerStore::Type_Lockpick: mLockpick = src.mLockpick; break; + case MWWorld::ContainerStore::Type_Miscellaneous: mMiscellaneous = src.mMiscellaneous; break; + case MWWorld::ContainerStore::Type_Probe: mProbe = src.mProbe; break; + case MWWorld::ContainerStore::Type_Repair: mRepair = src.mRepair; break; + case MWWorld::ContainerStore::Type_Weapon: mWeapon = src.mWeapon; break; + case -1: break; + default: assert(0); + } +} + +MWWorld::ContainerStoreIterator& MWWorld::ContainerStoreIterator::operator=( const ContainerStoreIterator& rhs ) +{ + if (this!=&rhs) + { + copy(rhs); + } + return *this; +} + bool MWWorld::operator== (const ContainerStoreIterator& left, const ContainerStoreIterator& right) { return left.isEqual (right); diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index b34c71006..780d46199 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -143,6 +143,10 @@ namespace MWWorld MWWorld::CellRefList::List::iterator mRepair; MWWorld::CellRefList::List::iterator mWeapon; + public: + + ContainerStoreIterator(const ContainerStoreIterator& src); + private: ContainerStoreIterator (ContainerStore *container); @@ -165,6 +169,8 @@ namespace MWWorld ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); + void copy (const ContainerStoreIterator& src); + void incType(); void nextType(); @@ -189,6 +195,8 @@ namespace MWWorld ContainerStoreIterator operator++ (int); + ContainerStoreIterator& operator= (const ContainerStoreIterator& rhs); + bool isEqual (const ContainerStoreIterator& iter) const; int getType() const; From 70233950124f9f53b1809eb565141120b57029ad Mon Sep 17 00:00:00 2001 From: Dmitriy 'Endorph' Shkurskiy Date: Sat, 4 Jan 2014 07:30:43 +0200 Subject: [PATCH 056/223] Windows-specific definition to omit inclusion of unused stuff from Windows.h --- apps/openmw/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 2bf48c1bb..3129e6bd3 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -11,6 +11,7 @@ #include // For OutputDebugString +#define WIN32_LEAN_AND_MEAN #include // makes __argc and __argv available on windows #include From 116f125f05b9fa12f76267068f169b66fa8e15dc Mon Sep 17 00:00:00 2001 From: Dmitriy 'Endorph' Shkurskiy Date: Sat, 4 Jan 2014 07:41:23 +0200 Subject: [PATCH 057/223] Windows-specific definition to deny SDL from providing it's own WinMain() --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 64f8121c4..5cb2fd5b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,6 +183,9 @@ if (WIN32) set(Boost_USE_STATIC_LIBS ON) set(PLATFORM_INCLUDE_DIR "platform") add_definitions(-DBOOST_ALL_NO_LIB) + + # Suppress WinMain(), provided by SDL + add_definitions(-DSDL_MAIN_HANDLED) else (WIN32) set(PLATFORM_INCLUDE_DIR "") find_path (UUID_INCLUDE_DIR uuid/uuid.h) From aa05ffcf60831c2bd020502b8433820d75e982e4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 4 Jan 2014 13:05:19 +0100 Subject: [PATCH 058/223] 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 73f316677..4b610d5d2 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 f82d151b4..a204334b3 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 059/223] 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 4b610d5d2..6c90af694 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 060/223] 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 6c90af694..b9adf81ea 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 061/223] 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 b9adf81ea..e94f0a401 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 92234cf78301348c6423fa8791cf8ee8f3937f50 Mon Sep 17 00:00:00 2001 From: pvdk Date: Sat, 4 Jan 2014 21:46:38 +0100 Subject: [PATCH 062/223] Changed crashcatcher's uname system info retrieval and cleaned indentation --- apps/openmw/crashcatcher.cpp | 599 ++++++++++++++++++----------------- 1 file changed, 302 insertions(+), 297 deletions(-) diff --git a/apps/openmw/crashcatcher.cpp b/apps/openmw/crashcatcher.cpp index 666330666..d7ebc0d47 100644 --- a/apps/openmw/crashcatcher.cpp +++ b/apps/openmw/crashcatcher.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -42,78 +43,78 @@ static char altstack[SIGSTKSZ]; static struct { - int signum; - pid_t pid; - int has_siginfo; - siginfo_t siginfo; - char buf[1024]; + int signum; + pid_t pid; + int has_siginfo; + siginfo_t siginfo; + char buf[1024]; } crash_info; static const struct { - const char *name; - int signum; + const char *name; + int signum; } signals[] = { - { "Segmentation fault", SIGSEGV }, - { "Illegal instruction", SIGILL }, - { "FPU exception", SIGFPE }, - { "System BUS error", SIGBUS }, - { NULL, 0 } +{ "Segmentation fault", SIGSEGV }, +{ "Illegal instruction", SIGILL }, +{ "FPU exception", SIGFPE }, +{ "System BUS error", SIGBUS }, +{ NULL, 0 } }; static const struct { - int code; - const char *name; + int code; + const char *name; } sigill_codes[] = { -#ifndef __FreeBSD__ - { ILL_ILLOPC, "Illegal opcode" }, - { ILL_ILLOPN, "Illegal operand" }, - { ILL_ILLADR, "Illegal addressing mode" }, - { ILL_ILLTRP, "Illegal trap" }, - { ILL_PRVOPC, "Privileged opcode" }, - { ILL_PRVREG, "Privileged register" }, - { ILL_COPROC, "Coprocessor error" }, - { ILL_BADSTK, "Internal stack error" }, -#endif - { 0, NULL } + #ifndef __FreeBSD__ + { ILL_ILLOPC, "Illegal opcode" }, + { ILL_ILLOPN, "Illegal operand" }, + { ILL_ILLADR, "Illegal addressing mode" }, + { ILL_ILLTRP, "Illegal trap" }, + { ILL_PRVOPC, "Privileged opcode" }, + { ILL_PRVREG, "Privileged register" }, + { ILL_COPROC, "Coprocessor error" }, + { ILL_BADSTK, "Internal stack error" }, + #endif + { 0, NULL } }; static const struct { - int code; - const char *name; + int code; + const char *name; } sigfpe_codes[] = { - { FPE_INTDIV, "Integer divide by zero" }, - { FPE_INTOVF, "Integer overflow" }, - { FPE_FLTDIV, "Floating point divide by zero" }, - { FPE_FLTOVF, "Floating point overflow" }, - { FPE_FLTUND, "Floating point underflow" }, - { FPE_FLTRES, "Floating point inexact result" }, - { FPE_FLTINV, "Floating point invalid operation" }, - { FPE_FLTSUB, "Subscript out of range" }, - { 0, NULL } + { FPE_INTDIV, "Integer divide by zero" }, + { FPE_INTOVF, "Integer overflow" }, + { FPE_FLTDIV, "Floating point divide by zero" }, + { FPE_FLTOVF, "Floating point overflow" }, + { FPE_FLTUND, "Floating point underflow" }, + { FPE_FLTRES, "Floating point inexact result" }, + { FPE_FLTINV, "Floating point invalid operation" }, + { FPE_FLTSUB, "Subscript out of range" }, + { 0, NULL } }; static const struct { - int code; - const char *name; + int code; + const char *name; } sigsegv_codes[] = { -#ifndef __FreeBSD__ - { SEGV_MAPERR, "Address not mapped to object" }, - { SEGV_ACCERR, "Invalid permissions for mapped object" }, -#endif - { 0, NULL } + #ifndef __FreeBSD__ + { SEGV_MAPERR, "Address not mapped to object" }, + { SEGV_ACCERR, "Invalid permissions for mapped object" }, + #endif + { 0, NULL } }; static const struct { - int code; - const char *name; + int code; + const char *name; } sigbus_codes[] = { -#ifndef __FreeBSD__ - { BUS_ADRALN, "Invalid address alignment" }, - { BUS_ADRERR, "Non-existent physical address" }, - { BUS_OBJERR, "Object specific hardware error" }, -#endif - { 0, NULL } + #ifndef __FreeBSD__ + { BUS_ADRALN, "Invalid address alignment" }, + { BUS_ADRERR, "Non-existent physical address" }, + { BUS_OBJERR, "Object specific hardware error" }, + #endif + { 0, NULL } }; static int (*cc_user_info)(char*, char*); @@ -121,314 +122,318 @@ static int (*cc_user_info)(char*, char*); static void gdb_info(pid_t pid) { - char respfile[64]; - char cmd_buf[128]; - FILE *f; - int fd; + char respfile[64]; + char cmd_buf[128]; + FILE *f; + int fd; - /* Create a temp file to put gdb commands into */ - strcpy(respfile, "gdb-respfile-XXXXXX"); - if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != NULL) - { - fprintf(f, "attach %d\n" - "shell echo \"\"\n" - "shell echo \"* Loaded Libraries\"\n" - "info sharedlibrary\n" - "shell echo \"\"\n" - "shell echo \"* Threads\"\n" - "info threads\n" - "shell echo \"\"\n" - "shell echo \"* FPU Status\"\n" - "info float\n" - "shell echo \"\"\n" - "shell echo \"* Registers\"\n" - "info registers\n" - "shell echo \"\"\n" - "shell echo \"* Backtrace\"\n" - "thread apply all backtrace full\n" - "detach\n" - "quit\n", pid); - fclose(f); + /* Create a temp file to put gdb commands into */ + strcpy(respfile, "gdb-respfile-XXXXXX"); + if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != NULL) + { + fprintf(f, "attach %d\n" + "shell echo \"\"\n" + "shell echo \"* Loaded Libraries\"\n" + "info sharedlibrary\n" + "shell echo \"\"\n" + "shell echo \"* Threads\"\n" + "info threads\n" + "shell echo \"\"\n" + "shell echo \"* FPU Status\"\n" + "info float\n" + "shell echo \"\"\n" + "shell echo \"* Registers\"\n" + "info registers\n" + "shell echo \"\"\n" + "shell echo \"* Backtrace\"\n" + "thread apply all backtrace full\n" + "detach\n" + "quit\n", pid); + fclose(f); - /* Run gdb and print process info. */ - snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile); - printf("Executing: %s\n", cmd_buf); - fflush(stdout); + /* Run gdb and print process info. */ + snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile); + printf("Executing: %s\n", cmd_buf); + fflush(stdout); - system(cmd_buf); - /* Clean up */ - remove(respfile); - } - else - { - /* Error creating temp file */ - if(fd >= 0) - { - close(fd); - remove(respfile); - } - printf("!!! Could not create gdb command file\n"); - } - fflush(stdout); + system(cmd_buf); + /* Clean up */ + remove(respfile); + } + else + { + /* Error creating temp file */ + if(fd >= 0) + { + close(fd); + remove(respfile); + } + printf("!!! Could not create gdb command file\n"); + } + fflush(stdout); } static void sys_info(void) { #ifdef __unix__ - system("echo \"System: `uname -a`\""); - putchar('\n'); - fflush(stdout); + struct utsname info; + if(!uname(&info)) + printf("!!! Failed to get system information\n"); + else + printf("System: %s %s %s %s %s\n", + info.sysname, info.nodename, info.release, info.version, info.machine); + + fflush(stdout); #endif } - static size_t safe_write(int fd, const void *buf, size_t len) { - size_t ret = 0; - while(ret < len) - { - ssize_t rem; - if((rem=write(fd, (const char*)buf+ret, len-ret)) == -1) - { - if(errno == EINTR) - continue; - break; - } - ret += rem; - } - return ret; + size_t ret = 0; + while(ret < len) + { + ssize_t rem; + if((rem=write(fd, (const char*)buf+ret, len-ret)) == -1) + { + if(errno == EINTR) + continue; + break; + } + ret += rem; + } + return ret; } static void crash_catcher(int signum, siginfo_t *siginfo, void *context) { //ucontext_t *ucontext = (ucontext_t*)context; - pid_t dbg_pid; - int fd[2]; + pid_t dbg_pid; + int fd[2]; - /* Make sure the effective uid is the real uid */ - if(getuid() != geteuid()) - { - raise(signum); - return; - } + /* Make sure the effective uid is the real uid */ + if(getuid() != geteuid()) + { + raise(signum); + return; + } - safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err)-1); - if(pipe(fd) == -1) - { - safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err)-1); - raise(signum); - return; - } + safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err)-1); + if(pipe(fd) == -1) + { + safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err)-1); + raise(signum); + return; + } - crash_info.signum = signum; - crash_info.pid = getpid(); - crash_info.has_siginfo = !!siginfo; - if(siginfo) - crash_info.siginfo = *siginfo; - if(cc_user_info) - cc_user_info(crash_info.buf, crash_info.buf+sizeof(crash_info.buf)); + crash_info.signum = signum; + crash_info.pid = getpid(); + crash_info.has_siginfo = !!siginfo; + if(siginfo) + crash_info.siginfo = *siginfo; + if(cc_user_info) + cc_user_info(crash_info.buf, crash_info.buf+sizeof(crash_info.buf)); - /* Fork off to start a crash handler */ - switch((dbg_pid=fork())) - { - /* Error */ - case -1: - safe_write(STDERR_FILENO, fork_err, sizeof(fork_err)-1); - raise(signum); - return; + /* Fork off to start a crash handler */ + switch((dbg_pid=fork())) + { + /* Error */ + case -1: + safe_write(STDERR_FILENO, fork_err, sizeof(fork_err)-1); + raise(signum); + return; - case 0: - dup2(fd[0], STDIN_FILENO); - close(fd[0]); - close(fd[1]); + case 0: + dup2(fd[0], STDIN_FILENO); + close(fd[0]); + close(fd[1]); - execl(argv0, argv0, crash_switch, NULL); + execl(argv0, argv0, crash_switch, NULL); - safe_write(STDERR_FILENO, exec_err, sizeof(exec_err)-1); - _exit(1); + safe_write(STDERR_FILENO, exec_err, sizeof(exec_err)-1); + _exit(1); - default: + default: #ifdef __linux__ - prctl(PR_SET_PTRACER, dbg_pid, 0, 0, 0); + prctl(PR_SET_PTRACER, dbg_pid, 0, 0, 0); #endif - safe_write(fd[1], &crash_info, sizeof(crash_info)); - close(fd[0]); - close(fd[1]); + safe_write(fd[1], &crash_info, sizeof(crash_info)); + close(fd[0]); + close(fd[1]); - /* Wait; we'll be killed when gdb is done */ - do { - int status; - if(waitpid(dbg_pid, &status, 0) == dbg_pid && - (WIFEXITED(status) || WIFSIGNALED(status))) - { - /* The debug process died before it could kill us */ - raise(signum); - break; - } - } while(1); - } + /* Wait; we'll be killed when gdb is done */ + do { + int status; + if(waitpid(dbg_pid, &status, 0) == dbg_pid && + (WIFEXITED(status) || WIFSIGNALED(status))) + { + /* The debug process died before it could kill us */ + raise(signum); + break; + } + } while(1); + } } static void crash_handler(const char *logfile) { - const char *sigdesc = ""; + const char *sigdesc = ""; int i; - if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1) - { - fprintf(stderr, "!!! Failed to retrieve info from crashed process\n"); - exit(1); - } + if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1) + { + fprintf(stderr, "!!! Failed to retrieve info from crashed process\n"); + exit(1); + } - /* Get the signal description */ - for(i = 0;signals[i].name;++i) - { - if(signals[i].signum == crash_info.signum) - { - sigdesc = signals[i].name; - break; - } - } + /* Get the signal description */ + for(i = 0;signals[i].name;++i) + { + if(signals[i].signum == crash_info.signum) + { + sigdesc = signals[i].name; + break; + } + } - if(crash_info.has_siginfo) - { - switch(crash_info.signum) - { - case SIGSEGV: - for(i = 0;sigsegv_codes[i].name;++i) - { - if(sigsegv_codes[i].code == crash_info.siginfo.si_code) - { - sigdesc = sigsegv_codes[i].name; - break; - } - } - break; + if(crash_info.has_siginfo) + { + switch(crash_info.signum) + { + case SIGSEGV: + for(i = 0;sigsegv_codes[i].name;++i) + { + if(sigsegv_codes[i].code == crash_info.siginfo.si_code) + { + sigdesc = sigsegv_codes[i].name; + break; + } + } + break; - case SIGFPE: - for(i = 0;sigfpe_codes[i].name;++i) - { - if(sigfpe_codes[i].code == crash_info.siginfo.si_code) - { - sigdesc = sigfpe_codes[i].name; - break; - } - } - break; + case SIGFPE: + for(i = 0;sigfpe_codes[i].name;++i) + { + if(sigfpe_codes[i].code == crash_info.siginfo.si_code) + { + sigdesc = sigfpe_codes[i].name; + break; + } + } + break; - case SIGILL: - for(i = 0;sigill_codes[i].name;++i) - { - if(sigill_codes[i].code == crash_info.siginfo.si_code) - { - sigdesc = sigill_codes[i].name; - break; - } - } - break; + case SIGILL: + for(i = 0;sigill_codes[i].name;++i) + { + if(sigill_codes[i].code == crash_info.siginfo.si_code) + { + sigdesc = sigill_codes[i].name; + break; + } + } + break; - case SIGBUS: - for(i = 0;sigbus_codes[i].name;++i) - { - if(sigbus_codes[i].code == crash_info.siginfo.si_code) - { - sigdesc = sigbus_codes[i].name; - break; - } - } - break; - } - } - fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum); - if(crash_info.has_siginfo) - fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr); - fputc('\n', stderr); + case SIGBUS: + for(i = 0;sigbus_codes[i].name;++i) + { + if(sigbus_codes[i].code == crash_info.siginfo.si_code) + { + sigdesc = sigbus_codes[i].name; + break; + } + } + break; + } + } + fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum); + if(crash_info.has_siginfo) + fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr); + fputc('\n', stderr); - if(logfile) - { - /* Create crash log file and redirect shell output to it */ - if(freopen(logfile, "wa", stdout) != stdout) - { - fprintf(stderr, "!!! Could not create %s following signal\n", logfile); - exit(1); - } - fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid); + if(logfile) + { + /* Create crash log file and redirect shell output to it */ + if(freopen(logfile, "wa", stdout) != stdout) + { + fprintf(stderr, "!!! Could not create %s following signal\n", logfile); + exit(1); + } + fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid); - printf("*** Fatal Error ***\n" - "%s (signal %i)\n", sigdesc, crash_info.signum); - if(crash_info.has_siginfo) - printf("Address: %p\n", crash_info.siginfo.si_addr); - fputc('\n', stdout); - fflush(stdout); - } + printf("*** Fatal Error ***\n" + "%s (signal %i)\n", sigdesc, crash_info.signum); + if(crash_info.has_siginfo) + printf("Address: %p\n", crash_info.siginfo.si_addr); + fputc('\n', stdout); + fflush(stdout); + } - sys_info(); + sys_info(); - crash_info.buf[sizeof(crash_info.buf)-1] = '\0'; - printf("%s\n", crash_info.buf); - fflush(stdout); + crash_info.buf[sizeof(crash_info.buf)-1] = '\0'; + printf("%s\n", crash_info.buf); + fflush(stdout); - if(crash_info.pid > 0) - { - gdb_info(crash_info.pid); - kill(crash_info.pid, SIGKILL); - } + if(crash_info.pid > 0) + { + gdb_info(crash_info.pid); + kill(crash_info.pid, SIGKILL); + } - if(logfile) - { + if(logfile) + { char cwd[MAXPATHLEN]; getcwd(cwd, MAXPATHLEN); std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + std::string(cwd) + "/" + std::string(logfile) + "'.\n Please report this to https://bugs.openmw.org !"; SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), NULL); - } - exit(0); + } + exit(0); } int cc_install_handlers(int argc, char **argv, int num_signals, int *signals, const char *logfile, int (*user_info)(char*, char*)) { - struct sigaction sa; - stack_t altss; - int retval; + struct sigaction sa; + stack_t altss; + int retval; - if(argc == 2 && strcmp(argv[1], crash_switch) == 0) - crash_handler(logfile); + if(argc == 2 && strcmp(argv[1], crash_switch) == 0) + crash_handler(logfile); - cc_user_info = user_info; + cc_user_info = user_info; - if(argv[0][0] == '/') - snprintf(argv0, sizeof(argv0), "%s", argv[0]); - else - { - getcwd(argv0, sizeof(argv0)); - retval = strlen(argv0); - snprintf(argv0+retval, sizeof(argv0)-retval, "/%s", argv[0]); - } + if(argv[0][0] == '/') + snprintf(argv0, sizeof(argv0), "%s", argv[0]); + else + { + getcwd(argv0, sizeof(argv0)); + retval = strlen(argv0); + snprintf(argv0+retval, sizeof(argv0)-retval, "/%s", argv[0]); + } - /* Set an alternate signal stack so SIGSEGVs caused by stack overflows - * still run */ - altss.ss_sp = altstack; - altss.ss_flags = 0; - altss.ss_size = sizeof(altstack); - sigaltstack(&altss, NULL); + /* Set an alternate signal stack so SIGSEGVs caused by stack overflows + * still run */ + altss.ss_sp = altstack; + altss.ss_flags = 0; + altss.ss_size = sizeof(altstack); + sigaltstack(&altss, NULL); - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = crash_catcher; - sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_SIGINFO | SA_ONSTACK; - sigemptyset(&sa.sa_mask); + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = crash_catcher; + sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_SIGINFO | SA_ONSTACK; + sigemptyset(&sa.sa_mask); - retval = 0; - while(num_signals--) - { + retval = 0; + while(num_signals--) + { if((*signals != SIGSEGV && *signals != SIGILL && *signals != SIGFPE && *signals != SIGABRT && - *signals != SIGBUS) || sigaction(*signals, &sa, NULL) == -1) - { - *signals = 0; - retval = -1; - } - ++signals; - } - return retval; + *signals != SIGBUS) || sigaction(*signals, &sa, NULL) == -1) + { + *signals = 0; + retval = -1; + } + ++signals; + } + return retval; } From 220d92f865fdf094616d60e3edeb1aa993132e88 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 5 Jan 2014 11:30:03 +0100 Subject: [PATCH 063/223] 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 e94f0a401..0460444c5 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 064/223] 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 0460444c5..187a74627 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 065/223] 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 187a74627..424f29820 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 066/223] 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 424f29820..74a7dbb7f 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 067/223] 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 74a7dbb7f..7d9210593 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 068/223] 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 7d9210593..64260e0a2 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 069/223] 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 64260e0a2..73c88a507 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 feeb32e6a..217e77a05 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 070/223] 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 73c88a507..92d116244 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 071/223] 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 92d116244..12f347afb 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 217e77a05..bc31ad537 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 4ad43fdf92f935c33be9894f52231e13ec287102 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 6 Jan 2014 19:01:05 +0100 Subject: [PATCH 072/223] Closes #1088: Quick&dirty fix for NIF filters not working properly with some mods --- components/nifogre/ogrenifloader.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/components/nifogre/ogrenifloader.cpp b/components/nifogre/ogrenifloader.cpp index 63e905766..0c1fdfbee 100644 --- a/components/nifogre/ogrenifloader.cpp +++ b/components/nifogre/ogrenifloader.cpp @@ -1209,20 +1209,27 @@ ObjectScenePtr Loader::createObjects(Ogre::Entity *parent, const std::string &bo if(isskinned) { + // Apparently both are allowed. Sigh. + // This could also mean that filters are supposed to work on the actual node + // hierarchy, rather than just trishapes, and the 'tri ' should be omitted? std::string filter = "@shape=tri "+bonename; + std::string filter2 = "@shape="+bonename; Misc::StringUtils::toLower(filter); + Misc::StringUtils::toLower(filter2); for(size_t i = 0;i < scene->mEntities.size();i++) { Ogre::Entity *entity = scene->mEntities[i]; if(entity->hasSkeleton()) { if(entity == scene->mSkelBase || - entity->getMesh()->getName().find(filter) != std::string::npos) + entity->getMesh()->getName().find(filter) != std::string::npos + || entity->getMesh()->getName().find(filter2) != std::string::npos) parentNode->attachObject(entity); } else { - if(entity->getMesh()->getName().find(filter) == std::string::npos) + if(entity->getMesh()->getName().find(filter) == std::string::npos + || entity->getMesh()->getName().find(filter2) == std::string::npos) entity->detachFromParent(); } } From 2591ff2d5a4adde5d3e2dc5b80ae1fd94a43bab5 Mon Sep 17 00:00:00 2001 From: mrcheko Date: Mon, 6 Jan 2014 22:00:01 +0200 Subject: [PATCH 073/223] bug repairing --- apps/openmw/mwmechanics/character.cpp | 30 +++++++++++++++++---------- apps/openmw/mwrender/animation.cpp | 15 +++++++++++++- apps/openmw/mwrender/animation.hpp | 1 + 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 299c9dc99..d93ae9519 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -249,7 +249,8 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat else { mAnimation->disable(mCurrentJump); - mCurrentJump.clear(); + //mCurrentJump.clear(); + mCurrentJump = jump; mAnimation->play(jump, Priority_Jump, jumpgroup, true, 1.0f, "loop stop", "stop", 0.0f, 0); } @@ -678,6 +679,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun mUpperBodyState = UpperCharState_StartToMinAttack; } } + animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); } else @@ -708,7 +710,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun } } stats.setAttackStrength(complete); - + mAnimation->disable(mCurrentWeapon); mAnimation->play(mCurrentWeapon, Priority_Weapon, MWRender::Animation::Group_UpperBody, false, @@ -725,7 +727,6 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun mUpperBodyState == UpperCharState_CastingSpell) { mUpperBodyState = UpperCharState_WeapEquiped; - //don't allow to continue playing hit animation on UpperBody after actor had attacked during it if(mHitState != CharState_None) { @@ -748,6 +749,12 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun stop = mAttackType+" max attack"; mUpperBodyState = UpperCharState_MinAttackToMaxAttack; break; + /*case UpperCharState_MinAttackToMaxAttack: + if(!mAnimation->isPlaying(mCurrentWeapon)) + mAnimation->play(mCurrentWeapon, Priority_Weapon, + MWRender::Animation::Group_UpperBody, false, + 1e-9f, mAttackType+" min attack", mAttackType+" max attack", 0.99f, ~0ul); + break;*/ case UpperCharState_MaxAttackToMinHit: if(mAttackType == "shoot") { @@ -797,12 +804,8 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun } } - if(!animPlaying) - { - mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f)); - } //if playing combat animation and lowerbody is not busy switch to whole body animation - if(weaptype != WeapType_None && animPlaying) + if((weaptype != WeapType_None || UpperCharState_UnEquipingWeap) && animPlaying) { if( mMovementState != CharState_None || mJumpState != JumpState_None || @@ -810,15 +813,14 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun MWBase::Environment::get().getWorld()->isSwimming(mPtr) || cls.getStance(mPtr, MWWorld::Class::Sneak)) { - mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f)); mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_UpperBody); } else { - mAnimation->setAccumulation(Ogre::Vector3(0.0f, 0.0f, 0.0f)); mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_All); } } + MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name() @@ -1001,7 +1003,13 @@ void CharacterController::update(float duration) else { if(!(vec.z > 0.0f)) - mJumpState = JumpState_None; + { + if(!mAnimation->isPlaying(mCurrentJump)) + { + mJumpState = JumpState_None; + mCurrentJump.clear(); + } + } vec.z = 0.0f; if(std::abs(vec.x/2.0f) > std::abs(vec.y)) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 664b0343d..3e682399e 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -562,6 +562,7 @@ void Animation::updatePosition(float oldtime, float newtime, Ogre::Vector3 &posi /* Translate the accumulation root back to compensate for the move. */ mAccumRoot->setPosition(-off); + mAccumRootPosUpd=true; } bool Animation::reset(AnimState &state, const NifOgre::TextKeyMap &keys, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint) @@ -851,7 +852,7 @@ void Animation::disable(const std::string &groupname) Ogre::Vector3 Animation::runAnimation(float duration) { Ogre::Vector3 movement(0.0f); - + mAccumRootPosUpd = false; AnimStateMap::iterator stateiter = mStates.begin(); while(stateiter != mStates.end()) { @@ -945,6 +946,18 @@ Ogre::Vector3 Animation::runAnimation(float duration) updateEffects(duration); + if (!mAccumRootPosUpd) + { + for(stateiter = mStates.begin();stateiter != mStates.end(); stateiter++) + { + if(mNonAccumCtrl && stateiter->first == mAnimationValuePtr[0]->getAnimName()) + { + updatePosition(stateiter->second.mTime, stateiter->second.mTime, movement); + break; + } + } + } + return movement; } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index f5f79dd72..013b49400 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -128,6 +128,7 @@ protected: NifOgre::ObjectScenePtr mObjectRoot; AnimSourceList mAnimSources; Ogre::Node *mAccumRoot; + bool mAccumRootPosUpd; Ogre::Node *mNonAccumRoot; NifOgre::NodeTargetValue *mNonAccumCtrl; Ogre::Vector3 mAccumulate; From 68b87714bb41a779b46803f91facbc6b9d6d97cd Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 6 Jan 2014 22:14:11 +0100 Subject: [PATCH 074/223] Addition to 2f35e5a04ef828d: companions should still auto equip --- apps/openmw/mwworld/inventorystore.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 422265c0e..2aee74eee 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -79,13 +79,13 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, { const MWWorld::ContainerStoreIterator& retVal = MWWorld::ContainerStore::add(itemPtr, count, actorPtr, setOwner); - // Auto-equip items if an armor/clothing item is added, but not for the player nor werewolves + // Auto-equip items if an armor/clothing or weapon item is added, but not for the player nor werewolves if ((actorPtr.getRefData().getHandle() != "player") && !(MWWorld::Class::get(actorPtr).getNpcStats(actorPtr).isWerewolf()) && !actorPtr.getClass().getCreatureStats(actorPtr).isDead()) { std::string type = itemPtr.getTypeName(); - if ((type == typeid(ESM::Armor).name()) || (type == typeid(ESM::Clothing).name())) + if ((type == typeid(ESM::Armor).name()) || (type == typeid(ESM::Clothing).name()) || (type == typeid(ESM::Weapon).name())) autoEquip(actorPtr); } @@ -185,7 +185,10 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) // Only autoEquip if we are the original owner of the item. // This stops merchants from auto equipping anything you sell to them. - if (!Misc::StringUtils::ciEqual(test.getCellRef().mOwner, actor.getCellRef().mRefID)) + // ...unless this is a companion, he should always equip items given to him. + if (!Misc::StringUtils::ciEqual(test.getCellRef().mOwner, actor.getCellRef().mRefID) && + (actor.getClass().getScript(actor).empty() || + !actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion"))) continue; int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test); From b85fe2becf57f7c377a0ea66438bfe4bb2c9693c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 6 Jan 2014 23:37:18 +0100 Subject: [PATCH 075/223] 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 12f347afb..6132b3407 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 4a3d148a48f24a61e9d0849d8246b14f3b463cf1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 00:37:52 +0100 Subject: [PATCH 076/223] Fixes #1089 (skill increases) --- apps/openmw/mwmechanics/stat.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index 77b3f6364..e66cf86de 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -231,6 +231,7 @@ namespace MWMechanics { float mProgress; public: + SkillValue() : mProgress(0) {} float getProgress() const { return mProgress; } void setProgress(float progress) { mProgress = progress; } }; From 29c823b9d435ff9b5cb8c2015f0230f209ad164e Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 00:51:09 +0100 Subject: [PATCH 077/223] Implement awareness check function. Use this for combat AI and GetDetected instruction. --- apps/openmw/mwbase/mechanicsmanager.hpp | 3 + apps/openmw/mwmechanics/actors.cpp | 73 +++++++++---------- .../mwmechanics/mechanicsmanagerimp.cpp | 70 ++++++++++++++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 3 + apps/openmw/mwscript/aiextensions.cpp | 16 ++-- apps/openmw/mwworld/worldimp.cpp | 7 -- 6 files changed, 121 insertions(+), 51 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 3ab234de1..90f0caee6 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -88,6 +88,9 @@ namespace MWBase virtual int countDeaths (const std::string& id) const = 0; ///< Return the number of deaths for actors with the given ID. + /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! + virtual bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) = 0; + enum PersuasionType { PT_Admire, diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 2cbfc020e..4c9c73ca1 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -158,50 +158,49 @@ namespace MWMechanics calculateDynamicStats (ptr); calculateCreatureStatModifiers (ptr, duration); - if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) + // AI + if(MWBase::Environment::get().getMechanicsManager()->isAIActive()) { - // AI - if(MWBase::Environment::get().getMechanicsManager()->isAIActive()) + CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); + //engage combat or not? + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + if(ptr != player && !creatureStats.isHostile()) { - CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); - //engage combat or not? - if(ptr != MWBase::Environment::get().getWorld()->getPlayer().getPlayer() && !creatureStats.isHostile()) + ESM::Position playerpos = player.getRefData().getPosition(); + ESM::Position actorpos = ptr.getRefData().getPosition(); + float d = sqrt((actorpos.pos[0] - playerpos.pos[0])*(actorpos.pos[0] - playerpos.pos[0]) + +(actorpos.pos[1] - playerpos.pos[1])*(actorpos.pos[1] - playerpos.pos[1]) + +(actorpos.pos[2] - playerpos.pos[2])*(actorpos.pos[2] - playerpos.pos[2])); + float fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(CreatureStats::AI_Fight).getModified(); + float disp = 100; //creatures don't have disposition, so set it to 100 by default + if(ptr.getTypeName() == typeid(ESM::NPC).name()) { - ESM::Position playerpos = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getRefData().getPosition(); - ESM::Position actorpos = ptr.getRefData().getPosition(); - float d = sqrt((actorpos.pos[0] - playerpos.pos[0])*(actorpos.pos[0] - playerpos.pos[0]) - +(actorpos.pos[1] - playerpos.pos[1])*(actorpos.pos[1] - playerpos.pos[1]) - +(actorpos.pos[2] - playerpos.pos[2])*(actorpos.pos[2] - playerpos.pos[2])); - float fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(CreatureStats::AI_Fight).getModified(); - float disp = 100; //creatures don't have disposition, so set it to 100 by default - if(ptr.getTypeName() == typeid(ESM::NPC).name()) - { - disp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr); - } - bool LOS = MWBase::Environment::get().getWorld()->getLOS(ptr,MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); - if( ( (fight == 100 ) - || (fight >= 95 && d <= 3000) - || (fight >= 90 && d <= 2000) - || (fight >= 80 && d <= 1000) - || (fight >= 80 && disp <= 40) - || (fight >= 70 && disp <= 35 && d <= 1000) - || (fight >= 60 && disp <= 30 && d <= 1000) - || (fight >= 50 && disp == 0) - || (fight >= 40 && disp <= 10 && d <= 500) ) - && LOS - ) - { - creatureStats.getAiSequence().stack(AiCombat("player")); - creatureStats.setHostile(true); - } + disp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr); + } + bool LOS = MWBase::Environment::get().getWorld()->getLOS(ptr,player) + && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr); + if( ( (fight == 100 ) + || (fight >= 95 && d <= 3000) + || (fight >= 90 && d <= 2000) + || (fight >= 80 && d <= 1000) + || (fight >= 80 && disp <= 40) + || (fight >= 70 && disp <= 35 && d <= 1000) + || (fight >= 60 && disp <= 30 && d <= 1000) + || (fight >= 50 && disp == 0) + || (fight >= 40 && disp <= 10 && d <= 500) ) + && LOS + ) + { + creatureStats.getAiSequence().stack(AiCombat("player")); + creatureStats.setHostile(true); } - - creatureStats.getAiSequence().execute (ptr,duration); } - // fatigue restoration - calculateRestoration(ptr, duration); + creatureStats.getAiSequence().execute (ptr,duration); } + + // fatigue restoration + calculateRestoration(ptr, duration); } void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 67f42fe0a..07d41505b 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -12,6 +12,8 @@ #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" +#include + #include "spellcasting.hpp" namespace MWMechanics @@ -725,4 +727,72 @@ namespace MWMechanics { return mAI; } + + bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer) + { + const MWWorld::Store& store = MWBase::Environment::get().getWorld()->getStore().get(); + + CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + + float invisibility = stats.getMagicEffects().get(ESM::MagicEffect::Invisibility).mMagnitude; + if (invisibility > 0) + return false; + + float sneakTerm = 0; + if (ptr.getClass().getStance(ptr, MWWorld::Class::Sneak)) + { + static float fSneakSkillMult = store.find("fSneakSkillMult")->getFloat(); + static float fSneakBootMult = store.find("fSneakBootMult")->getFloat(); + float sneak = 0; + if (ptr.getClass().isNpc()) + sneak = ptr.getClass().getNpcStats(ptr).getSkill(ESM::Skill::Sneak).getModified(); + int agility = stats.getAttribute(ESM::Attribute::Agility).getModified(); + int luck = stats.getAttribute(ESM::Attribute::Luck).getModified(); + float bootWeight = 0; + if (ptr.getClass().isNpc()) + { + MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr); + MWWorld::ContainerStoreIterator it = inv.getSlot(MWWorld::InventoryStore::Slot_Boots); + if (it != inv.end()) + bootWeight = it->getClass().getWeight(*it); + } + sneakTerm = fSneakSkillMult * sneak + 0.2 * agility + 0.1 * luck + bootWeight * fSneakBootMult; + } + + static float fSneakDistBase = store.find("fSneakDistanceBase")->getFloat(); + static float fSneakDistMult = store.find("fSneakDistanceMultiplier")->getFloat(); + + Ogre::Vector3 pos1 (ptr.getRefData().getPosition().pos); + Ogre::Vector3 pos2 (observer.getRefData().getPosition().pos); + float distTerm = fSneakDistBase + fSneakDistMult * pos1.distance(pos2); + + float chameleon = stats.getMagicEffects().get(ESM::MagicEffect::Chameleon).mMagnitude; + float x = sneakTerm * distTerm * stats.getFatigueTerm() + chameleon + invisibility; + + CreatureStats& observerStats = observer.getClass().getCreatureStats(observer); + 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(); + + float obsTerm = obsSneak + 0.2 * obsAgility + 0.1 * obsLuck - obsBlind; + + // is ptr behind the observer? + static float fSneakNoViewMult = store.find("fSneakNoViewMult")->getFloat(); + static float fSneakViewMult = store.find("fSneakViewMult")->getFloat(); + float y = 0; + Ogre::Vector3 vec = pos1 - pos2; + Ogre::Radian angle = observer.getRefData().getBaseNode()->getOrientation().yAxis().angleBetween(vec); + if (angle < Ogre::Degree(90)) + y = obsTerm * observerStats.getFatigueTerm() * fSneakNoViewMult; + else + y = obsTerm * observerStats.getFatigueTerm() * fSneakViewMult; + + float target = x - y; + int roll = std::rand()/ (static_cast (RAND_MAX) + 1) * 100; // [0, 99] + + return (roll >= target); + } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index ec03b457b..63111f1cc 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -98,6 +98,9 @@ namespace MWMechanics void toLower(std::string npcFaction); ///< Perform a persuasion action on NPC + /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! + virtual bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer); + virtual void forceStateUpdate(const MWWorld::Ptr &ptr); virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 966a064c7..213f13882 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -358,19 +358,21 @@ namespace MWScript }; template - class OpGetDetected : public Interpreter::Opcode1 + class OpGetDetected : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + virtual void execute (Interpreter::Runtime& runtime) { - + MWWorld::Ptr observer = R()(runtime); std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - Interpreter::Type_Integer value = false; // TODO replace with implementation + MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true); - std::cout << "AiGetDetected: " << actorID << ", " << value << std::endl; + Interpreter::Type_Integer value = + MWBase::Environment::get().getWorld()->getLOS(observer, actor) && + MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, observer); runtime.push (value); } @@ -432,8 +434,8 @@ namespace MWScript new OpGetAiPackageDone); interpreter.installSegment5 (Compiler::Ai::opcodeGetCurrentAiPackage, new OpGetCurrentAIPackage); interpreter.installSegment5 (Compiler::Ai::opcodeGetCurrentAiPackageExplicit, new OpGetCurrentAIPackage); - interpreter.installSegment3 (Compiler::Ai::opcodeGetDetected, new OpGetDetected); - interpreter.installSegment3 (Compiler::Ai::opcodeGetDetectedExplicit, new OpGetDetected); + interpreter.installSegment5 (Compiler::Ai::opcodeGetDetected, new OpGetDetected); + interpreter.installSegment5 (Compiler::Ai::opcodeGetDetectedExplicit, new OpGetDetected); interpreter.installSegment5 (Compiler::Ai::opcodeGetLineOfSight, new OpGetLineOfSight); interpreter.installSegment5 (Compiler::Ai::opcodeGetLineOfSightExplicit, new OpGetLineOfSight); interpreter.installSegment5 (Compiler::Ai::opcodeToggleAI, new OpToggleAI); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index ba76eee88..2d3d3d07f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1840,13 +1840,6 @@ namespace MWWorld bool World::getLOS(const MWWorld::Ptr& npc,const MWWorld::Ptr& targetNpc) { - // This is a placeholder! Needs to go into an NPC awareness check function (see - // https://wiki.openmw.org/index.php?title=Research:NPC_AI_Behaviour#NPC_Awareness_Check ) - if (targetNpc.getClass().getCreatureStats(targetNpc).getMagicEffects().get(ESM::MagicEffect::Invisibility).mMagnitude) - return false; - if (targetNpc.getClass().getCreatureStats(targetNpc).getMagicEffects().get(ESM::MagicEffect::Chameleon).mMagnitude > 100) - return false; - Ogre::Vector3 halfExt1 = mPhysEngine->getCharacter(npc.getRefData().getHandle())->getHalfExtents(); float* pos1 = npc.getRefData().getPosition().pos; Ogre::Vector3 halfExt2 = mPhysEngine->getCharacter(targetNpc.getRefData().getHandle())->getHalfExtents(); From 887db76ed2084fb7b7d1b3e1a0832f9c20494381 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 01:20:13 +0100 Subject: [PATCH 078/223] Don't consider swimming or in-air characters as sneaking --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 07d41505b..884294df3 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -739,7 +739,9 @@ namespace MWMechanics return false; float sneakTerm = 0; - if (ptr.getClass().getStance(ptr, MWWorld::Class::Sneak)) + if (ptr.getClass().getStance(ptr, MWWorld::Class::Sneak) + && !MWBase::Environment::get().getWorld()->isSwimming(ptr) + && MWBase::Environment::get().getWorld()->isOnGround(ptr)) { static float fSneakSkillMult = store.find("fSneakSkillMult")->getFloat(); static float fSneakBootMult = store.find("fSneakBootMult")->getFloat(); From 5c7e39a92f0a59c108d87141b1715c741f9f98e3 Mon Sep 17 00:00:00 2001 From: Sergey Shambir Date: Tue, 7 Jan 2014 04:12:37 +0400 Subject: [PATCH 079/223] 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 cc09452c9..a041bb2de 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 ee0dcf96e..531ba5568 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 6f643aa68..3ce366580 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 fa71e261f..82efc043b 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 5099625c0..d91e02be2 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 73bf9259a..c5b1f1bf3 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 5832198da..74c77bf97 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 6d461e5f6..5d0686084 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 0976ef099..d65c31616 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 f56c75996..db577a32f 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 93c94a3f4..e1f65a509 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 966a064c7..3c95e9ca1 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 6194be532..4ad9dfc5e 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 46524c7cd..f84614c37 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 b06cb529a..8a31aadf5 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 080/223] 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 a041bb2de..a5664c1c8 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 081/223] 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 504a8638b..3dc5492bf 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 f84614c37..6f8f26e97 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 ea3ee4407fa3d6600e967f1d440984fce7d4bb73 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 02:48:44 +0100 Subject: [PATCH 082/223] oops, didn't mean to commit this --- 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 9d3002dfd..8a32f58b9 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -613,7 +613,7 @@ 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, "thief"); + MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); if(object.isEmpty()) { From 780bf5a2cdcc0bdb642901685165f6882c4bbec8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 03:01:33 +0100 Subject: [PATCH 083/223] Implement pickpocket detection. Play a voiced dialogue entry when detected. --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/container.cpp | 57 +++++++++++++++++- apps/openmw/mwgui/container.hpp | 6 ++ apps/openmw/mwmechanics/pickpocket.cpp | 67 ++++++++++++++++++++++ apps/openmw/mwmechanics/pickpocket.hpp | 30 ++++++++++ files/mygui/openmw_container_window.layout | 1 + 6 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 apps/openmw/mwmechanics/pickpocket.cpp create mode 100644 apps/openmw/mwmechanics/pickpocket.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 8c8a1b324..77d442eef 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 + disease pickpocket ) add_openmw_dir (mwbase diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index b7c6e3367..31cfd8bc9 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -6,10 +6,13 @@ #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/dialoguemanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" +#include "../mwmechanics/pickpocket.hpp" + #include "countdialog.hpp" #include "tradewindow.hpp" #include "inventorywindow.hpp" @@ -123,6 +126,7 @@ namespace MWGui , mSelectedItem(-1) , mModel(NULL) , mSortModel(NULL) + , mPickpocketDetected(false) { getWidget(mDisposeCorpseButton, "DisposeCorpseButton"); getWidget(mTakeButton, "TakeButton"); @@ -171,6 +175,9 @@ namespace MWGui void ContainerWindow::dragItem(MyGUI::Widget* sender, int count) { + if (!onTakeItem(mModel->getItem(mSelectedItem), count)) + return; + mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count); } @@ -208,6 +215,7 @@ namespace MWGui void ContainerWindow::open(const MWWorld::Ptr& container, bool loot) { + mPickpocketDetected = false; mPtr = container; if (mPtr.getTypeName() == typeid(ESM::NPC).name() && !loot) @@ -230,6 +238,28 @@ namespace MWGui setTitle(MWWorld::Class::get(container).getName(container)); } + void ContainerWindow::close() + { + WindowBase::close(); + + // Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened) + if (!MWBase::Environment::get().getWindowManager()->containsMode(GM_Container) + && !mPickpocketDetected // If it was already detected while taking an item, no need to check now + ) + { + MWMechanics::Pickpocket pickpocket(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), + mPtr); + if (pickpocket.finish()) + { + // TODO: crime + MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); + MWBase::Environment::get().getDialogueManager()->say(mPtr, "Thief"); + mPickpocketDetected = true; + return; + } + } + } + void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) { if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop) @@ -255,8 +285,13 @@ namespace MWGui MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); } - playerModel->copyItem(mModel->getItem(i), mModel->getItem(i).mCount); - mModel->removeItem(mModel->getItem(i), mModel->getItem(i).mCount); + const ItemStack& item = mModel->getItem(i); + + if (!onTakeItem(item, item.mCount)) + break; + + playerModel->copyItem(item, item.mCount); + mModel->removeItem(item, item.mCount); } MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); @@ -283,4 +318,22 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); } + bool ContainerWindow::onTakeItem(const ItemStack &item, int count) + { + if (dynamic_cast(mModel)) + { + MWMechanics::Pickpocket pickpocket(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), + mPtr); + if (pickpocket.pick(item.mBase, count)) + { + // TODO: crime + MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); + MWBase::Environment::get().getDialogueManager()->say(mPtr, "Thief"); + mPickpocketDetected = true; + return false; + } + } + return true; + } + } diff --git a/apps/openmw/mwgui/container.hpp b/apps/openmw/mwgui/container.hpp index 243f77aa5..f934d8828 100644 --- a/apps/openmw/mwgui/container.hpp +++ b/apps/openmw/mwgui/container.hpp @@ -52,10 +52,13 @@ namespace MWGui ContainerWindow(DragAndDrop* dragAndDrop); void open(const MWWorld::Ptr& container, bool loot=false); + virtual void close(); private: DragAndDrop* mDragAndDrop; + bool mPickpocketDetected; + MWGui::ItemView* mItemView; SortFilterItemModel* mSortModel; ItemModel* mModel; @@ -73,6 +76,9 @@ namespace MWGui void onTakeAllButtonClicked(MyGUI::Widget* _sender); void onDisposeCorpseButtonClicked(MyGUI::Widget* sender); + /// @return is taking the item allowed? + bool onTakeItem(const ItemStack& item, int count); + virtual void onReferenceUnavailable(); }; } diff --git a/apps/openmw/mwmechanics/pickpocket.cpp b/apps/openmw/mwmechanics/pickpocket.cpp new file mode 100644 index 000000000..8e8a70d88 --- /dev/null +++ b/apps/openmw/mwmechanics/pickpocket.cpp @@ -0,0 +1,67 @@ +#include "pickpocket.hpp" + +#include "../mwworld/class.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "npcstats.hpp" + +namespace MWMechanics +{ + + Pickpocket::Pickpocket(const MWWorld::Ptr &thief, const MWWorld::Ptr &victim) + : mThief(thief) + , mVictim(victim) + { + } + + float Pickpocket::getChanceModifier(const MWWorld::Ptr &ptr, float add) + { + 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(); + return (add + 0.2 * agility + 0.1 * luck + sneak) * stats.getFatigueTerm(); + } + + bool Pickpocket::getDetected(float valueTerm) + { + float x = getChanceModifier(mThief); + float y = getChanceModifier(mVictim, valueTerm); + + float t = 2*x - y; + + NpcStats& pcStats = mThief.getClass().getNpcStats(mThief); + float pcSneak = pcStats.getSkill(ESM::Skill::Sneak).getModified(); + int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get() + .find("iPickMinChance")->getInt(); + int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get() + .find("iPickMaxChance")->getInt(); + + int roll = std::rand()/ (static_cast (RAND_MAX) + 1) * 100; // [0, 99] + if (t < pcSneak / iPickMinChance) + { + return (roll > int(pcSneak / iPickMinChance)); + } + else + { + t = std::min(float(iPickMaxChance), t); + return (roll > int(t)); + } + } + + bool Pickpocket::pick(MWWorld::Ptr item, int count) + { + float stackValue = item.getClass().getValue(item) * count; + float fPickPocketMod = MWBase::Environment::get().getWorld()->getStore().get() + .find("fPickPocketMod")->getFloat(); + float valueTerm = 10 * fPickPocketMod * stackValue; + + return getDetected(valueTerm); + } + + bool Pickpocket::finish() + { + return getDetected(0.f); + } + +} diff --git a/apps/openmw/mwmechanics/pickpocket.hpp b/apps/openmw/mwmechanics/pickpocket.hpp new file mode 100644 index 000000000..4de1e37f8 --- /dev/null +++ b/apps/openmw/mwmechanics/pickpocket.hpp @@ -0,0 +1,30 @@ +#ifndef OPENMW_MECHANICS_PICKPOCKET_H +#define OPENMW_MECHANICS_PICKPOCKET_H + +#include "../mwworld/ptr.hpp" + +namespace MWMechanics +{ + + class Pickpocket + { + public: + Pickpocket (const MWWorld::Ptr& thief, const MWWorld::Ptr& victim); + + /// Steal some items + /// @return Was the thief detected? + bool pick (MWWorld::Ptr item, int count); + /// End the pickpocketing process + /// @return Was the thief detected? + bool finish (); + + private: + bool getDetected(float valueTerm); + float getChanceModifier(const MWWorld::Ptr& ptr, float add=0); + MWWorld::Ptr mThief; + MWWorld::Ptr mVictim; + }; + +} + +#endif diff --git a/files/mygui/openmw_container_window.layout b/files/mygui/openmw_container_window.layout index 06cc04ebe..87651b0f2 100644 --- a/files/mygui/openmw_container_window.layout +++ b/files/mygui/openmw_container_window.layout @@ -3,6 +3,7 @@ + From 9afa8e952e1d54f77c8f5506646ec1de95e51d27 Mon Sep 17 00:00:00 2001 From: Dmitriy 'Endorph' Shkurskiy Date: Tue, 7 Jan 2014 14:32:14 +0200 Subject: [PATCH 084/223] tabs -> spaces --- apps/openmw/mwworld/containerstore.cpp | 54 +++++++++++++------------- apps/openmw/mwworld/containerstore.hpp | 8 ++-- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 39fda7ab9..f86ccfb54 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -557,7 +557,7 @@ MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *contain MWWorld::ContainerStoreIterator::ContainerStoreIterator( const ContainerStoreIterator& src ) { - copy(src); + copy(src); } void MWWorld::ContainerStoreIterator::incType() @@ -814,37 +814,37 @@ const MWWorld::ContainerStore *MWWorld::ContainerStoreIterator::getContainerStor void MWWorld::ContainerStoreIterator::copy(const ContainerStoreIterator& src) { - mType = src.mType; - mMask = src.mMask; - mContainer = src.mContainer; - mPtr = src.mPtr; + mType = src.mType; + mMask = src.mMask; + mContainer = src.mContainer; + mPtr = src.mPtr; - switch (mType) - { - case MWWorld::ContainerStore::Type_Potion: mPotion = src.mPotion; break; - case MWWorld::ContainerStore::Type_Apparatus: mApparatus = src.mApparatus; break; - case MWWorld::ContainerStore::Type_Armor: mArmor = src.mArmor; break; - case MWWorld::ContainerStore::Type_Book: mBook = src.mBook; break; - case MWWorld::ContainerStore::Type_Clothing: mClothing = src.mClothing; break; - case MWWorld::ContainerStore::Type_Ingredient: mIngredient = src.mIngredient; break; - case MWWorld::ContainerStore::Type_Light: mLight = src.mLight; break; - case MWWorld::ContainerStore::Type_Lockpick: mLockpick = src.mLockpick; break; - case MWWorld::ContainerStore::Type_Miscellaneous: mMiscellaneous = src.mMiscellaneous; break; - case MWWorld::ContainerStore::Type_Probe: mProbe = src.mProbe; break; - case MWWorld::ContainerStore::Type_Repair: mRepair = src.mRepair; break; - case MWWorld::ContainerStore::Type_Weapon: mWeapon = src.mWeapon; break; - case -1: break; - default: assert(0); - } + switch (mType) + { + case MWWorld::ContainerStore::Type_Potion: mPotion = src.mPotion; break; + case MWWorld::ContainerStore::Type_Apparatus: mApparatus = src.mApparatus; break; + case MWWorld::ContainerStore::Type_Armor: mArmor = src.mArmor; break; + case MWWorld::ContainerStore::Type_Book: mBook = src.mBook; break; + case MWWorld::ContainerStore::Type_Clothing: mClothing = src.mClothing; break; + case MWWorld::ContainerStore::Type_Ingredient: mIngredient = src.mIngredient; break; + case MWWorld::ContainerStore::Type_Light: mLight = src.mLight; break; + case MWWorld::ContainerStore::Type_Lockpick: mLockpick = src.mLockpick; break; + case MWWorld::ContainerStore::Type_Miscellaneous: mMiscellaneous = src.mMiscellaneous; break; + case MWWorld::ContainerStore::Type_Probe: mProbe = src.mProbe; break; + case MWWorld::ContainerStore::Type_Repair: mRepair = src.mRepair; break; + case MWWorld::ContainerStore::Type_Weapon: mWeapon = src.mWeapon; break; + case -1: break; + default: assert(0); + } } MWWorld::ContainerStoreIterator& MWWorld::ContainerStoreIterator::operator=( const ContainerStoreIterator& rhs ) { - if (this!=&rhs) - { - copy(rhs); - } - return *this; + if (this!=&rhs) + { + copy(rhs); + } + return *this; } bool MWWorld::operator== (const ContainerStoreIterator& left, const ContainerStoreIterator& right) diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 780d46199..a4c30edd4 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -143,10 +143,6 @@ namespace MWWorld MWWorld::CellRefList::List::iterator mRepair; MWWorld::CellRefList::List::iterator mWeapon; - public: - - ContainerStoreIterator(const ContainerStoreIterator& src); - private: ContainerStoreIterator (ContainerStore *container); @@ -187,6 +183,8 @@ namespace MWWorld public: + ContainerStoreIterator(const ContainerStoreIterator& src); + Ptr *operator->() const; Ptr operator*() const; @@ -195,7 +193,7 @@ namespace MWWorld ContainerStoreIterator operator++ (int); - ContainerStoreIterator& operator= (const ContainerStoreIterator& rhs); + ContainerStoreIterator& operator= (const ContainerStoreIterator& rhs); bool isEqual (const ContainerStoreIterator& iter) const; From 90b55c8d4b344c6bd26f0cd7a24b91b97a2bfce7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 16:37:51 +0100 Subject: [PATCH 085/223] Use Ogre's asin/acos functions which will protect against NaNs --- apps/openmw/mwmechanics/aicombat.cpp | 8 ++++---- apps/openmw/mwmechanics/pathfinding.cpp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 6f643aa68..df45b7133 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -12,13 +12,13 @@ #include "creaturestats.hpp" #include "npcstats.hpp" -#include "OgreMath.h" +#include namespace { - static float sgn(float a) + static float sgn(Ogre::Radian a) { - if(a > 0) + if(a.valueDegrees() > 0) return 1.0; return -1.0; } @@ -106,7 +106,7 @@ namespace MWMechanics float directionY = dest.mY - start.mY; float directionResult = sqrt(directionX * directionX + directionY * directionY); - zAngle = Ogre::Radian( acos(directionY / directionResult) * sgn(asin(directionX / directionResult)) ).valueDegrees(); + zAngle = Ogre::Radian( Ogre::Math::ACos(directionY / directionResult) * sgn(Ogre::Math::ASin(directionX / directionResult)) ).valueDegrees(); // TODO: use movement settings instead of rotating directly MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false); diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index ff266f9ae..18e66d228 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -53,9 +53,9 @@ namespace return sqrt(x * x + y * y + z * z); } - static float sgn(float a) + static float sgn(Ogre::Radian a) { - if(a > 0) + if(a.valueRadians() > 0) return 1.0; return -1.0; } @@ -196,7 +196,7 @@ namespace MWMechanics float directionY = nextPoint.mY - y; float directionResult = sqrt(directionX * directionX + directionY * directionY); - return Ogre::Radian(acos(directionY / directionResult) * sgn(asin(directionX / directionResult))).valueDegrees(); + return Ogre::Radian(Ogre::Math::ACos(directionY / directionResult) * sgn(Ogre::Math::ASin(directionX / directionResult))).valueDegrees(); } bool PathFinder::checkWaypoint(float x, float y, float z) From d97615d5d87604caeffc1ad303e0ef6ea510680d Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 18:05:44 +0100 Subject: [PATCH 086/223] Support separate specular maps --- files/materials/objects.mat | 7 +++++++ files/materials/objects.shader | 25 +++++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/files/materials/objects.mat b/files/materials/objects.mat index 751b51243..2281226b0 100644 --- a/files/materials/objects.mat +++ b/files/materials/objects.mat @@ -8,6 +8,7 @@ material openmw_objects_base diffuseMap black.png normalMap emissiveMap + specMap darkMap use_emissive_map false use_detail_map false @@ -44,6 +45,7 @@ material openmw_objects_base emissiveMap $emissiveMap detailMap $detailMap diffuseMap $diffuseMap + specMap $specMap darkMap $darkMap env_map $env_map env_map_color $env_map_color @@ -107,6 +109,11 @@ material openmw_objects_base anim_texture2 textures\magicitem\caust.dds 32 2 colour_op add } + + texture_unit specMap + { + direct_texture $specMap + } texture_unit shadowMap0 { diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 93368f1f6..ed75babdd 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -14,11 +14,14 @@ #define NEED_DEPTH #endif +#define SPECULAR 1 + #define NORMAL_MAP @shPropertyHasValue(normalMap) #define EMISSIVE_MAP @shPropertyHasValue(emissiveMap) #define DETAIL_MAP @shPropertyHasValue(detailMap) #define DIFFUSE_MAP @shPropertyHasValue(diffuseMap) #define DARK_MAP @shPropertyHasValue(darkMap) +#define SPEC_MAP @shPropertyHasValue(specMap) && SPECULAR #define PARALLAX @shPropertyBool(use_parallax) #define PARALLAX_SCALE 0.04 @@ -38,8 +41,6 @@ #define ENV_MAP @shPropertyBool(env_map) -#define SPECULAR 1 - #define NEED_NORMAL (!VERTEX_LIGHTING || ENV_MAP) || SPECULAR #ifdef SH_VERTEX_SHADER @@ -273,6 +274,10 @@ shUniform(float3, env_map_color) @shUniformProperty3f(env_map_color, env_map_color) #endif +#if SPEC_MAP + shSampler2D(specMap) +#endif + #if ENV_MAP || SPECULAR || PARALLAX shUniform(float3, cameraPosObjSpace) @shAutoConstant(cameraPosObjSpace, camera_position_object_space) #endif @@ -511,8 +516,20 @@ float NdotL = max(dot(normal, light0Dir), 0); float3 halfVec = normalize (light0Dir + eyeDir); - float3 specular = pow(max(dot(normal, halfVec), 0), matShininess) * lightSpec0 * matSpec; - shOutputColour(0).xyz += specular * shadow * diffuse.a; + float shininess = matShininess; +#if SPEC_MAP + float4 specTex = shSample(specMap, UV.xy); + shininess *= (specTex.a); +#endif + + float3 specular = pow(max(dot(normal, halfVec), 0), shininess) * lightSpec0 * matSpec; +#if SPEC_MAP + specular *= specTex.xyz; +#else + specular *= diffuse.a; +#endif + + shOutputColour(0).xyz += specular * shadow; #endif #if FOG From c4ab2f417aec0504910c8df334c26f76dd5329e3 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 18:11:19 +0100 Subject: [PATCH 087/223] Fix exception closing container window --- apps/openmw/mwgui/container.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 31cfd8bc9..b4de0aa62 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -242,9 +242,11 @@ namespace MWGui { WindowBase::close(); - // Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened) - if (!MWBase::Environment::get().getWindowManager()->containsMode(GM_Container) - && !mPickpocketDetected // If it was already detected while taking an item, no need to check now + if (dynamic_cast(mModel) + // Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened) + && !MWBase::Environment::get().getWindowManager()->containsMode(GM_Container) + // If it was already detected while taking an item, no need to check now + && !mPickpocketDetected ) { MWMechanics::Pickpocket pickpocket(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), From d2d76f4f4787a2029860e38906e138036114ca76 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 19:21:19 +0100 Subject: [PATCH 088/223] Fix disintegration bug --- 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 4c9c73ca1..74b459e6a 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -80,7 +80,7 @@ bool disintegrateSlot (MWWorld::Ptr ptr, int slot, float disintegrate) return true; } } - return true; + return false; } From 3c0080d2c17bcfd8a02e372ecb300ab942c53139 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 19:49:16 +0100 Subject: [PATCH 089/223] Implement theft detection --- apps/openmw/mwbase/mechanicsmanager.hpp | 21 ++++++ apps/openmw/mwgui/container.cpp | 21 ++++-- apps/openmw/mwgui/inventorywindow.cpp | 3 + apps/openmw/mwmechanics/actors.hpp | 12 +++- .../mwmechanics/mechanicsmanagerimp.cpp | 66 +++++++++++++++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 12 ++++ apps/openmw/mwworld/actiontake.cpp | 4 +- 7 files changed, 129 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 90f0caee6..a0abb8e48 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -91,6 +91,27 @@ namespace MWBase /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! virtual bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) = 0; + enum OffenseType + { + OT_Theft, // Taking items owned by an NPC or a faction you are not a member of + OT_Assault, // Attacking a peaceful NPC + OT_Murder, // Murdering a peaceful NPC + OT_Trespassing, // Staying in a cell you are not allowed in (where is this defined?) + OT_SleepingInOwnedBed, // Sleeping in a bed owned by an NPC or a faction you are not a member of + OT_Pickpocket // Entering pickpocket mode, leaving it, and being detected. Any items stolen are a separate crime (Theft) + }; + /** + * @brief Commit a crime. If any actors witness the crime and report it, + * reportCrime will be called automatically. + * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. + */ + virtual void commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, + OffenseType type, int arg=0) = 0; + virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, + 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; + enum PersuasionType { PT_Admire, diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index b4de0aa62..aa80388f3 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -7,9 +7,11 @@ #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/dialoguemanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwmechanics/pickpocket.hpp" @@ -249,11 +251,12 @@ namespace MWGui && !mPickpocketDetected ) { - MWMechanics::Pickpocket pickpocket(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), - mPtr); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWMechanics::Pickpocket pickpocket(player, mPtr); if (pickpocket.finish()) { - // TODO: crime + MWBase::Environment::get().getMechanicsManager()->reportCrime( + player, MWWorld::Ptr(), MWBase::MechanicsManager::OT_Pickpocket); MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); MWBase::Environment::get().getDialogueManager()->say(mPtr, "Thief"); mPickpocketDetected = true; @@ -322,19 +325,25 @@ namespace MWGui bool ContainerWindow::onTakeItem(const ItemStack &item, int count) { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); if (dynamic_cast(mModel)) { - MWMechanics::Pickpocket pickpocket(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), - mPtr); + MWMechanics::Pickpocket pickpocket(player, mPtr); if (pickpocket.pick(item.mBase, count)) { - // TODO: crime + int value = item.mBase.getClass().getValue(item.mBase) * count; + MWBase::Environment::get().getMechanicsManager()->reportCrime( + player, MWWorld::Ptr(), MWBase::MechanicsManager::OT_Theft, value); MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); MWBase::Environment::get().getDialogueManager()->say(mPtr, "Thief"); mPickpocketDetected = true; return false; } } + else + { + MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, count); + } return true; } diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 21da53c6d..33814455a 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -8,6 +8,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/inventorystore.hpp" @@ -533,6 +534,8 @@ namespace MWGui if (i == mTradeModel->getItemCount()) throw std::runtime_error("Added item not found"); mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count); + + MWBase::Environment::get().getMechanicsManager()->itemTaken(player, newObject, count); } MyGUI::IntCoord InventoryWindow::getAvatarScreenCoord () diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 83aff63e3..7046543e6 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -25,9 +25,6 @@ namespace MWMechanics { class Actors { - typedef std::map PtrControllerMap; - PtrControllerMap mActors; - std::map mDeathCount; void updateNpc(const MWWorld::Ptr &ptr, float duration, bool paused); @@ -50,6 +47,11 @@ namespace MWMechanics Actors(); ~Actors(); + typedef std::map PtrControllerMap; + + PtrControllerMap::const_iterator begin() { return mActors.begin(); } + PtrControllerMap::const_iterator end() { return mActors.end(); } + /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently /// paused we may want to do it manually (after equipping permanent enchantment) void updateMagicEffects (const MWWorld::Ptr& ptr) { adjustMagicEffects(ptr); } @@ -88,6 +90,10 @@ namespace MWMechanics void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); void skipAnimation(const MWWorld::Ptr& ptr); bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName); + + private: + PtrControllerMap mActors; + }; } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 884294df3..94ea66067 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -728,6 +728,72 @@ namespace MWMechanics return mAI; } + void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count) + { + const std::string& owner = item.getCellRef().mOwner; + if (owner.empty()) + return; + const std::string& faction = item.getCellRef().mFaction; + if (faction.empty()) + return; + const std::map& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks(); + if (factions.find(Misc::StringUtils::lowerCase(faction)) != factions.end()) + return; + + MWWorld::Ptr victim = MWBase::Environment::get().getWorld()->getPtr(owner, true); + + commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); + } + + void MechanicsManager::commitCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) + { + bool reported=false; + for (Actors::PtrControllerMap::const_iterator it = mActors.begin(); it != mActors.end(); ++it) + { + if (it->first != ptr && awarenessCheck(ptr, it->first)) + { + // NPCs will always curse you when they notice you steal their items, even if they don't report the crime + if (it->first == victim && type == OT_Theft) + { + MWBase::Environment::get().getDialogueManager()->say(victim, "Thief"); + } + + // 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) + ) + { + reported=true; + break; + } + } + } + + if (reported) + reportCrime(ptr, victim, type, arg); + } + + void MechanicsManager::reportCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) + { + // Bounty for each type of crime + if (type == OT_Trespassing || type == OT_SleepingInOwnedBed) + arg = 5; + else if (type == OT_Pickpocket) + arg = 25; + else if (type == OT_Assault) + arg = 40; + else if (type == OT_Murder) + arg = 1000; + + MWBase::Environment::get().getWindowManager()->messageBox("#{sCrimeMessage}"); + ptr.getClass().getNpcStats(ptr).setBounty(ptr.getClass().getNpcStats(ptr).getBounty() + + arg); + + // TODO: make any guards in the area try to arrest the player + } + bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer) { const MWWorld::Store& store = MWBase::Environment::get().getWorld()->getStore().get(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 63111f1cc..198a62d84 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -101,6 +101,18 @@ namespace MWMechanics /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! virtual bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer); + /** + * @brief Commit a crime. If any actors witness the crime and report it, + * reportCrime will be called automatically. + * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. + */ + virtual void commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, + OffenseType type, int arg=0); + virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, + 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); + virtual void forceStateUpdate(const MWWorld::Ptr &ptr); virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); diff --git a/apps/openmw/mwworld/actiontake.cpp b/apps/openmw/mwworld/actiontake.cpp index 867a046cf..548a94981 100644 --- a/apps/openmw/mwworld/actiontake.cpp +++ b/apps/openmw/mwworld/actiontake.cpp @@ -4,6 +4,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "class.hpp" #include "containerstore.hpp" @@ -14,8 +15,9 @@ namespace MWWorld void ActionTake::executeImp (const Ptr& actor) { + MWBase::Environment::get().getMechanicsManager()->itemTaken( + actor, getTarget(), getTarget().getRefData().getCount()); actor.getClass().getContainerStore (actor).add (getTarget(), getTarget().getRefData().getCount(), actor); - MWBase::Environment::get().getWorld()->deleteObject (getTarget()); } } From 0285d18fc22bd2b16b99c2dd6af580cbeeb1a9aa Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 20:24:01 +0100 Subject: [PATCH 090/223] Respect items belonging to a faction --- apps/openmw/mwclass/activator.cpp | 4 ++++ apps/openmw/mwclass/apparatus.cpp | 1 + apps/openmw/mwclass/armor.cpp | 1 + apps/openmw/mwclass/book.cpp | 1 + apps/openmw/mwclass/clothing.cpp | 1 + apps/openmw/mwclass/container.cpp | 3 ++- apps/openmw/mwclass/creature.cpp | 4 +++- apps/openmw/mwclass/ingredient.cpp | 1 + apps/openmw/mwclass/light.cpp | 1 + apps/openmw/mwclass/lockpick.cpp | 1 + apps/openmw/mwclass/misc.cpp | 1 + apps/openmw/mwclass/npc.cpp | 4 +++- apps/openmw/mwclass/potion.cpp | 1 + apps/openmw/mwclass/probe.cpp | 1 + apps/openmw/mwclass/repair.cpp | 1 + apps/openmw/mwclass/weapon.cpp | 1 + .../mwmechanics/mechanicsmanagerimp.cpp | 21 ++++++++++++------- apps/openmw/mwworld/containerstore.cpp | 12 ++++++----- apps/openmw/mwworld/containerstore.hpp | 4 ++-- components/esm/cellref.hpp | 4 ++-- 20 files changed, 49 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index 583cb08d3..8bc104d25 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -96,7 +96,11 @@ namespace MWClass std::string text; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + { + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); + } info.text = text; return info; diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index 53c62273d..b3a1af288 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -128,6 +128,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 0fae1b05c..13d19d86d 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -252,6 +252,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 1da920970..429d91259 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -140,6 +140,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index ffa96260d..b3278d07a 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -195,6 +195,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 55b15a7d2..d129e617d 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -53,7 +53,7 @@ namespace MWClass ptr.get(); data->mContainerStore.fill( - ref->mBase->mInventory, ptr.getCellRef().mOwner, MWBase::Environment::get().getWorld()->getStore()); + ref->mBase->mInventory, ptr.getCellRef().mOwner, ptr.getCellRef().mFaction, MWBase::Environment::get().getWorld()->getStore()); // store ptr.getRefData().setCustomData (data.release()); @@ -216,6 +216,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 98919d6f4..864a756c5 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -95,9 +95,11 @@ namespace MWClass data->mCreatureStats.getSpells().add (*iter); // inventory - data->mContainerStore.fill(ref->mBase->mInventory, getId(ptr), + data->mContainerStore.fill(ref->mBase->mInventory, getId(ptr), "", MWBase::Environment::get().getWorld()->getStore()); + // TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory. + // (except for gold you gave him) data->mContainerStore.add("gold_001", ref->mBase->mData.mGold, ptr); // store diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 4296d4e1b..c6ec3deb9 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -149,6 +149,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 6a6133cb9..cc56ec4c8 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -187,6 +187,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index e1dc5b2e1..795b66052 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -145,6 +145,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index d21189103..e5120462e 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -184,6 +184,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 8a32f58b9..24caed3f5 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -320,12 +320,14 @@ namespace MWClass data->mNpcStats.getSpells().add (*iter); // inventory - data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), + data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "", MWBase::Environment::get().getWorld()->getStore()); // store ptr.getRefData().setCustomData (data.release()); + // TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory. + // (except for gold you gave him) getContainerStore(ptr).add("gold_001", gold, ptr); getInventoryStore(ptr).autoEquip(ptr); diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index e276c58aa..457a1c696 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -153,6 +153,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index b54464acd..4209c1431 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -144,6 +144,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index ce2b4ff10..5f2065c3c 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -148,6 +148,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 5e93e0d81..82935673c 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -355,6 +355,7 @@ namespace MWClass if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 94ea66067..6f15becff 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -731,16 +731,23 @@ namespace MWMechanics void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count) { const std::string& owner = item.getCellRef().mOwner; - if (owner.empty()) - return; + bool isOwned = !owner.empty(); + const std::string& faction = item.getCellRef().mFaction; - if (faction.empty()) - return; - const std::map& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks(); - if (factions.find(Misc::StringUtils::lowerCase(faction)) != factions.end()) + bool isFactionOwned = false; + if (!faction.empty()) + { + const std::map& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks(); + if (factions.find(Misc::StringUtils::lowerCase(faction)) == factions.end()) + isFactionOwned = true; + } + + if (!isOwned && !isFactionOwned) return; - MWWorld::Ptr victim = MWBase::Environment::get().getWorld()->getPtr(owner, true); + MWWorld::Ptr victim; + if (!owner.empty()) + victim = MWBase::Environment::get().getWorld()->getPtr(owner, true); commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); } diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 3d5af7bf1..ee4080755 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -279,19 +279,20 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor return count - toRemove; } -void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner, const MWWorld::ESMStore& store) +void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner, const std::string& faction, const MWWorld::ESMStore& store) { for (std::vector::const_iterator iter (items.mList.begin()); iter!=items.mList.end(); ++iter) { std::string id = iter->mItem.toString(); - addInitialItem(id, owner, iter->mCount); + addInitialItem(id, owner, faction, iter->mCount); } flagAsModified(); } -void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, int count, unsigned char failChance, bool topLevel) +void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, const std::string& faction, + int count, unsigned char failChance, bool topLevel) { count = std::abs(count); /// \todo implement item restocking (indicated by negative count) @@ -312,7 +313,7 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std:: if (topLevel && count > 1 && levItem->mFlags & ESM::ItemLevList::Each) { for (int i=0; i Date: Tue, 7 Jan 2014 20:43:08 +0100 Subject: [PATCH 091/223] Get rid of a hack --- apps/openmw/mwrender/renderingmanager.cpp | 8 +------- apps/openmw/mwworld/cells.cpp | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a40535030..a68c6af28 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -19,7 +19,6 @@ #include -#include #include #include @@ -407,12 +406,7 @@ void RenderingManager::postRenderTargetUpdate(const RenderTargetEvent &evt) void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store) { - const MWWorld::Store &lands = - MWBase::Environment::get().getWorld()->getStore().get(); - - if(store->mCell->mData.mFlags & ESM::Cell::HasWater - || ((store->mCell->isExterior()) - && !lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land. + if(store->mCell->mData.mFlags & ESM::Cell::HasWater) { mWater->changeCell(store->mCell); mWater->setActive(true); diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 865c0d01f..621ff3b31 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -79,7 +79,7 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getExterior (int x, int y) // Cell isn't predefined. Make one on the fly. ESM::Cell record; - record.mData.mFlags = 0; + record.mData.mFlags = ESM::Cell::HasWater; record.mData.mX = x; record.mData.mY = y; record.mWater = 0; From 728365b48dadeec68279fe445a6bb45f70491299 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Jan 2014 21:07:02 +0100 Subject: [PATCH 092/223] Remove an unused hook --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/world.hpp | 3 --- apps/openmw/mwrender/characterpreview.hpp | 2 -- apps/openmw/mwrender/externalrendering.hpp | 23 ---------------------- apps/openmw/mwrender/renderingmanager.cpp | 6 ------ apps/openmw/mwrender/renderingmanager.hpp | 3 --- apps/openmw/mwworld/worldimp.cpp | 5 ----- apps/openmw/mwworld/worldimp.hpp | 2 -- 8 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 apps/openmw/mwrender/externalrendering.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 77d442eef..eb5b71ec3 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -19,7 +19,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation actors objects renderinginterface localmap occlusionquery water shadows - characterpreview externalrendering globalmap videoplayer ripplesimulation refraction + characterpreview globalmap videoplayer ripplesimulation refraction terrainstorage renderconst ) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 3a8897114..39919012e 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -40,7 +40,6 @@ namespace ESM namespace MWRender { - class ExternalRendering; class Animation; } @@ -366,8 +365,6 @@ namespace MWBase virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0; - virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; - virtual int canRest() = 0; ///< check if the player is allowed to rest \n /// 0 - yes \n diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index b2dfc9679..cd30cdf46 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -6,8 +6,6 @@ #include -#include "externalrendering.hpp" - #include "../mwworld/ptr.hpp" namespace OEngine diff --git a/apps/openmw/mwrender/externalrendering.hpp b/apps/openmw/mwrender/externalrendering.hpp deleted file mode 100644 index 33c9afd87..000000000 --- a/apps/openmw/mwrender/externalrendering.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef GAME_RENDERING_EXTERNALRENDERING_H -#define GAME_RENDERING_EXTERNALRENDERING_H - -namespace Ogre -{ - class SceneManager; -} - -namespace MWRender -{ - /// \brief Base class for out of world rendering - class ExternalRendering - { - public: - - virtual void setup (Ogre::SceneManager *sceneManager) = 0; - - virtual ~ExternalRendering() {} - }; -} - -#endif - diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a68c6af28..d950b8414 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -39,7 +39,6 @@ #include "localmap.hpp" #include "water.hpp" #include "npcanimation.hpp" -#include "externalrendering.hpp" #include "globalmap.hpp" #include "videoplayer.hpp" #include "terrainstorage.hpp" @@ -932,11 +931,6 @@ bool RenderingManager::isPositionExplored (float nX, float nY, int x, int y, boo return mLocalMap->isPositionExplored(nX, nY, x, y, interior); } -void RenderingManager::setupExternalRendering (MWRender::ExternalRendering& rendering) -{ - rendering.setup (mRendering.getScene()); -} - Animation* RenderingManager::getAnimation(const MWWorld::Ptr &ptr) { Animation *anim = mActors->getAnimation(ptr); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 37488b157..9f77f0a3c 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -48,7 +48,6 @@ namespace MWRender class Shadows; class LocalMap; class Water; - class ExternalRendering; class GlobalMap; class VideoPlayer; class Animation; @@ -204,8 +203,6 @@ public: bool isPositionExplored (float nX, float nY, int x, int y, bool interior); ///< see MWRender::LocalMap::isPositionExplored - void setupExternalRendering (MWRender::ExternalRendering& rendering); - Animation* getAnimation(const MWWorld::Ptr &ptr); void playVideo(const std::string& name, bool allowSkipping); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2d3d3d07f..b72433e5a 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1705,11 +1705,6 @@ namespace MWWorld mPhysics->addActor(mPlayer->getPlayer()); } - void World::setupExternalRendering (MWRender::ExternalRendering& rendering) - { - mRendering->setupExternalRendering (rendering); - } - int World::canRest () { Ptr::CellStore *currentCell = mWorldScene->getCurrentCell(); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 1aecb6fb6..92a993157 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -456,8 +456,6 @@ namespace MWWorld virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable); - virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); - virtual int canRest(); ///< check if the player is allowed to rest \n /// 0 - yes \n From c85c2cff4ee13558ec484e1c086182cd1f5150b3 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 01:24:06 +0100 Subject: [PATCH 093/223] Fix disposition changes from trades not applying properly --- apps/openmw/mwbase/dialoguemanager.hpp | 2 +- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 14 +++++++++++++- apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 2 +- apps/openmw/mwgui/tradewindow.cpp | 4 ++-- apps/openmw/mwmechanics/creaturestats.cpp | 3 ++- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 4 ++++ 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index 58731d1c7..971bc3b4e 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -51,7 +51,7 @@ namespace MWBase virtual void persuade (int type) = 0; virtual int getTemporaryDispositionChange () const = 0; - virtual void applyTemporaryDispositionChange (int delta) = 0; + virtual void applyDispositionChange (int delta) = 0; }; } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index b97986562..0eb20c50a 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -126,6 +126,8 @@ namespace MWDialogue void DialogueManager::startDialogue (const MWWorld::Ptr& actor) { mLastTopic = ""; + mPermanentDispositionChange = 0; + mTemporaryDispositionChange = 0; mChoice = -1; mIsInChoice = false; @@ -514,9 +516,19 @@ namespace MWDialogue return mTemporaryDispositionChange; } - void DialogueManager::applyTemporaryDispositionChange(int delta) + void DialogueManager::applyDispositionChange(int delta) { + int oldTemp = mTemporaryDispositionChange; mTemporaryDispositionChange += delta; + // don't allow increasing beyond 100 or decreasing below 0 + int curDisp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor); + if (curDisp + mTemporaryDispositionChange < 0) + mTemporaryDispositionChange = -curDisp; + else if (curDisp + mTemporaryDispositionChange > 100) + mTemporaryDispositionChange = 100 - curDisp; + + int diff = mTemporaryDispositionChange - oldTemp; + mPermanentDispositionChange += diff; } bool DialogueManager::checkServiceRefused() diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index c9aad1022..5baf20a0e 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -76,7 +76,7 @@ namespace MWDialogue virtual void persuade (int type); virtual int getTemporaryDispositionChange () const; - virtual void applyTemporaryDispositionChange (int delta); + virtual void applyDispositionChange (int delta); }; diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 6000de858..f67ea1a3f 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -319,7 +319,7 @@ namespace MWGui messageBox("#{sNotifyMessage9}"); int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt(); - MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition); + MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterFailDisposition); return; } @@ -328,7 +328,7 @@ namespace MWGui } int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt(); - MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition); + MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterSuccessDisposition); // make the item transfer mTradeModel->transferItems(); diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 85f6cfdbc..b5b9b7156 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -248,7 +248,8 @@ namespace MWMechanics void CreatureStats::setAiSetting (AiSetting index, int base) { - Stat stat(base); + Stat stat = getAiSetting(index); + stat.setBase(base); setAiSetting(index, stat); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 6f15becff..89b3fef83 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -749,11 +749,15 @@ namespace MWMechanics if (!owner.empty()) victim = MWBase::Environment::get().getWorld()->getPtr(owner, true); + // TODO: expell from faction + commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); } void MechanicsManager::commitCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) { + // TODO: expell from faction + bool reported=false; for (Actors::PtrControllerMap::const_iterator it = mActors.begin(); it != mActors.end(); ++it) { From 2bb21f2f765f2513836be1473caaeb182218862d Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 02:35:36 +0100 Subject: [PATCH 094/223] Don't copy NpcStats/CreatureStats unnecessarily. Fixes a bug: taunt actions would not correctly increase the target's fight rating. --- apps/openmw/mwgui/charactercreation.cpp | 2 +- apps/openmw/mwgui/waitdialog.cpp | 2 +- apps/openmw/mwmechanics/creaturestats.hpp | 9 ++++----- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 9 +++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 04507cfc6..fb593650d 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -221,7 +221,7 @@ namespace MWGui { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - MWMechanics::CreatureStats stats = MWWorld::Class::get(player).getCreatureStats(player); + const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); mReviewDialog->setHealth ( stats.getHealth() ); mReviewDialog->setMagicka( stats.getMagicka() ); diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 0a05cd22b..5d1c4b4b6 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -149,7 +149,7 @@ namespace MWGui // 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()->getPlayer().getPlayer(); - MWMechanics::CreatureStats stats = MWWorld::Class::get(player).getCreatureStats(player); + 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; diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 322970e73..6e0804638 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -46,7 +46,6 @@ namespace MWMechanics bool mRecalcDynamicStats; std::map mUsedPowers; - protected: bool mIsWerewolf; AttributeValue mWerewolfAttributes[8]; @@ -124,10 +123,10 @@ namespace MWMechanics enum AiSetting { - AI_Hello, - AI_Fight, - AI_Flee, - AI_Alarm + AI_Hello = 0, + AI_Fight = 1, + AI_Flee = 2, + AI_Alarm = 3 }; void setAiSetting (AiSetting index, Stat value); void setAiSetting (AiSetting index, int base); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 89b3fef83..0058fac6f 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -424,7 +424,7 @@ namespace MWMechanics int MechanicsManager::getDerivedDisposition(const MWWorld::Ptr& ptr) { - MWMechanics::NpcStats npcSkill = MWWorld::Class::get(ptr).getNpcStats(ptr); + const MWMechanics::NpcStats& npcSkill = MWWorld::Class::get(ptr).getNpcStats(ptr); float x = npcSkill.getBaseDisposition(); MWWorld::LiveCellRef* npc = ptr.get(); @@ -539,7 +539,7 @@ namespace MWMechanics const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - MWMechanics::NpcStats npcStats = MWWorld::Class::get(npc).getNpcStats(npc); + MWMechanics::NpcStats& npcStats = MWWorld::Class::get(npc).getNpcStats(npc); MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); @@ -613,6 +613,8 @@ namespace MWMechanics int fight = npcStats.getAiSetting(MWMechanics::CreatureStats::AI_Fight).getBase(); npcStats.setAiSetting (MWMechanics::CreatureStats::AI_Flee, std::max(0, std::min(100, flee + int(std::max(iPerMinChange, s))))); + // TODO: initiate combat and quit dialogue if fight rating is too high + // or should setAiSetting handle this? npcStats.setAiSetting (MWMechanics::CreatureStats::AI_Fight, std::max(0, std::min(100, fight + int(std::min(-iPerMinChange, -s))))); } @@ -644,10 +646,9 @@ namespace MWMechanics float c = std::abs(int(target1 - roll)); - if (roll <= target1) + if (success) { float s = c * fPerDieRollMult * fPerTempMult; - int flee = npcStats.getAiSetting (CreatureStats::AI_Flee).getBase(); int fight = npcStats.getAiSetting (CreatureStats::AI_Fight).getBase(); npcStats.setAiSetting (CreatureStats::AI_Flee, From 46519062d3614f2d5259bb34bc781b22a4d4f263 Mon Sep 17 00:00:00 2001 From: mrcheko Date: Wed, 8 Jan 2014 16:05:14 +0200 Subject: [PATCH 095/223] hit recoils/knockdowns feature --- apps/openmw/mwclass/npc.cpp | 2 +- apps/openmw/mwmechanics/character.cpp | 57 ++++++++------------------- apps/openmw/mwmechanics/character.hpp | 1 + apps/openmw/mwrender/animation.cpp | 14 ------- apps/openmw/mwrender/animation.hpp | 1 - 5 files changed, 19 insertions(+), 56 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index b23cb0814..4fb00a032 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -614,7 +614,7 @@ namespace MWClass // something, alert the character controller, scripts, etc. MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); - getCreatureStats(ptr).setAttacked(true); + getCreatureStats(ptr).setAttacked(true);//used in CharacterController if(object.isEmpty()) { diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index d93ae9519..a4b4f2471 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -158,6 +158,7 @@ public: void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force) { + //hit recoils/knockdown animations handling if(MWWorld::Class::get(mPtr).isActor()) { if(MWWorld::Class::get(mPtr).getCreatureStats(mPtr).getAttacked()) @@ -166,19 +167,20 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat if(mHitState == CharState_None) { - mHitState = CharState_Hit; if(mJumpState != JumpState_None && !MWBase::Environment::get().getWorld()->isFlying(mPtr) && !MWBase::Environment::get().getWorld()->isSwimming(mPtr) ) { - mCurrentHit = sHitList[sHitListSize-1]; //knockdown animation 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); 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)) @@ -249,8 +251,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat else { mAnimation->disable(mCurrentJump); - //mCurrentJump.clear(); - mCurrentJump = jump; + mCurrentJump.clear(); mAnimation->play(jump, Priority_Jump, jumpgroup, true, 1.0f, "loop stop", "stop", 0.0f, 0); } @@ -685,7 +686,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun else { animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); - if(mUpperBodyState == UpperCharState_MinAttackToMaxAttack) + if(mUpperBodyState == UpperCharState_MinAttackToMaxAttack && mHitState != CharState_KnockDown) { if(mAttackType != "shoot") { @@ -710,7 +711,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun } } stats.setAttackStrength(complete); - + mAnimation->disable(mCurrentWeapon); mAnimation->play(mCurrentWeapon, Priority_Weapon, MWRender::Animation::Group_UpperBody, false, @@ -718,6 +719,11 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun 1.0f-complete, 0); mUpperBodyState = UpperCharState_MaxAttackToMinHit; } + else if (mHitState == CharState_KnockDown) + { + mUpperBodyState = UpperCharState_WeapEquiped; + mAnimation->disable(mCurrentWeapon); + } } if(!animPlaying) @@ -728,7 +734,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun { mUpperBodyState = UpperCharState_WeapEquiped; //don't allow to continue playing hit animation on UpperBody after actor had attacked during it - if(mHitState != CharState_None) + if(mHitState == CharState_Hit) { mAnimation->changeGroups(mCurrentHit, MWRender::Animation::Group_LowerBody); //commenting out following 2 lines will give a bit different combat dynamics(slower) @@ -749,12 +755,6 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun stop = mAttackType+" max attack"; mUpperBodyState = UpperCharState_MinAttackToMaxAttack; break; - /*case UpperCharState_MinAttackToMaxAttack: - if(!mAnimation->isPlaying(mCurrentWeapon)) - mAnimation->play(mCurrentWeapon, Priority_Weapon, - MWRender::Animation::Group_UpperBody, false, - 1e-9f, mAttackType+" min attack", mAttackType+" max attack", 0.99f, ~0ul); - break;*/ case UpperCharState_MaxAttackToMinHit: if(mAttackType == "shoot") { @@ -803,23 +803,6 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun weapSpeed, start, stop, 0.0f, 0); } } - - //if playing combat animation and lowerbody is not busy switch to whole body animation - if((weaptype != WeapType_None || UpperCharState_UnEquipingWeap) && animPlaying) - { - if( mMovementState != CharState_None || - mJumpState != JumpState_None || - mHitState != CharState_None || - MWBase::Environment::get().getWorld()->isSwimming(mPtr) || - cls.getStance(mPtr, MWWorld::Class::Sneak)) - { - mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_UpperBody); - } - else - { - mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_All); - } - } MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); @@ -1002,14 +985,8 @@ void CharacterController::update(float duration) } else { - if(!(vec.z > 0.0f)) - { - if(!mAnimation->isPlaying(mCurrentJump)) - { - mJumpState = JumpState_None; - mCurrentJump.clear(); - } - } + if(!(vec.z > 0.0f)) + mJumpState = JumpState_None; vec.z = 0.0f; if(std::abs(vec.x/2.0f) > std::abs(vec.y)) @@ -1076,7 +1053,7 @@ void CharacterController::update(float duration) rot *= duration * Ogre::Math::RadiansToDegrees(1.0f); world->rotateObject(mPtr, rot.x, rot.y, rot.z, true); } - else + else //avoid z-rotating for knockdown world->rotateObject(mPtr, rot.x, rot.y, 0.0f, true); world->queueMovement(mPtr, vec); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index b7c29e9ef..438f542f0 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -30,6 +30,7 @@ enum Priority { Priority_Movement, Priority_Hit, Priority_Weapon, + Priority_Knockdown, Priority_Torch, Priority_Death, diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 3e682399e..8ce751286 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -562,7 +562,6 @@ void Animation::updatePosition(float oldtime, float newtime, Ogre::Vector3 &posi /* Translate the accumulation root back to compensate for the move. */ mAccumRoot->setPosition(-off); - mAccumRootPosUpd=true; } bool Animation::reset(AnimState &state, const NifOgre::TextKeyMap &keys, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint) @@ -852,7 +851,6 @@ void Animation::disable(const std::string &groupname) Ogre::Vector3 Animation::runAnimation(float duration) { Ogre::Vector3 movement(0.0f); - mAccumRootPosUpd = false; AnimStateMap::iterator stateiter = mStates.begin(); while(stateiter != mStates.end()) { @@ -946,18 +944,6 @@ Ogre::Vector3 Animation::runAnimation(float duration) updateEffects(duration); - if (!mAccumRootPosUpd) - { - for(stateiter = mStates.begin();stateiter != mStates.end(); stateiter++) - { - if(mNonAccumCtrl && stateiter->first == mAnimationValuePtr[0]->getAnimName()) - { - updatePosition(stateiter->second.mTime, stateiter->second.mTime, movement); - break; - } - } - } - return movement; } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 013b49400..f5f79dd72 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -128,7 +128,6 @@ protected: NifOgre::ObjectScenePtr mObjectRoot; AnimSourceList mAnimSources; Ogre::Node *mAccumRoot; - bool mAccumRootPosUpd; Ogre::Node *mNonAccumRoot; NifOgre::NodeTargetValue *mNonAccumCtrl; Ogre::Vector3 mAccumulate; From b99ca92fee0fe6bd76042a4f8e3824a1db3e6ffe Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 17:18:13 +0100 Subject: [PATCH 096/223] Add missing line of sight check --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 0058fac6f..c5b5e6401 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -762,7 +762,9 @@ namespace MWMechanics bool reported=false; for (Actors::PtrControllerMap::const_iterator it = mActors.begin(); it != mActors.end(); ++it) { - if (it->first != ptr && awarenessCheck(ptr, it->first)) + if (it->first != ptr && + MWBase::Environment::get().getWorld()->getLOS(ptr, it->first) && + awarenessCheck(ptr, it->first)) { // NPCs will always curse you when they notice you steal their items, even if they don't report the crime if (it->first == victim && type == OT_Theft) From 7b33f6f2acb02df45575dbfd5215c29e672798cd Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 17:19:43 +0100 Subject: [PATCH 097/223] Detect crime of sleeping in other NPC's beds. ShowRestMenu needs to support an explicit/implicit reference for this. --- apps/openmw/mwbase/mechanicsmanager.hpp | 6 +- .../mwmechanics/mechanicsmanagerimp.cpp | 62 +++++++++++++------ .../mwmechanics/mechanicsmanagerimp.hpp | 6 +- apps/openmw/mwscript/docs/vmformat.txt | 4 +- apps/openmw/mwscript/guiextensions.cpp | 28 ++++++++- components/compiler/extensions0.cpp | 2 +- components/compiler/opcodes.hpp | 1 + 7 files changed, 85 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index a0abb8e48..24e955cdf 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -104,13 +104,17 @@ namespace MWBase * @brief Commit a crime. If any actors witness the crime and report it, * reportCrime will be called automatically. * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. + * @return was the crime reported? */ - virtual void commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, + virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, int arg=0) = 0; virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, 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; + /// 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; enum PersuasionType { diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index c5b5e6401..b125b2899 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -16,6 +16,27 @@ #include "spellcasting.hpp" +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) + { + const std::string& owner = item.getCellRef().mOwner; + bool isOwned = !owner.empty(); + + const std::string& faction = item.getCellRef().mFaction; + bool isFactionOwned = false; + if (!faction.empty()) + { + const std::map& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks(); + if (factions.find(Misc::StringUtils::lowerCase(faction)) == factions.end()) + isFactionOwned = true; + } + + return (!isOwned && !isFactionOwned); + } +} + namespace MWMechanics { void MechanicsManager::buildPlayer() @@ -729,33 +750,35 @@ namespace MWMechanics return mAI; } + 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(commitCrime(ptr, victim, OT_SleepingInOwnedBed)) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage64}"); + return true; + } + else + return false; + } + void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count) { - const std::string& owner = item.getCellRef().mOwner; - bool isOwned = !owner.empty(); - - const std::string& faction = item.getCellRef().mFaction; - bool isFactionOwned = false; - if (!faction.empty()) - { - const std::map& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks(); - if (factions.find(Misc::StringUtils::lowerCase(faction)) == factions.end()) - isFactionOwned = true; - } - - if (!isOwned && !isFactionOwned) + if (isAllowedToUse(ptr, item)) return; - MWWorld::Ptr victim; - if (!owner.empty()) - victim = MWBase::Environment::get().getWorld()->getPtr(owner, true); - - // TODO: expell from faction + if (!item.getCellRef().mOwner.empty()) + victim = MWBase::Environment::get().getWorld()->getPtr(item.getCellRef().mOwner, true); commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); } - void MechanicsManager::commitCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) + bool MechanicsManager::commitCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) { // TODO: expell from faction @@ -787,6 +810,7 @@ namespace MWMechanics if (reported) reportCrime(ptr, victim, type, arg); + return reported; } void MechanicsManager::reportCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 198a62d84..cec08fa92 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -105,13 +105,17 @@ namespace MWMechanics * @brief Commit a crime. If any actors witness the crime and report it, * reportCrime will be called automatically. * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. + * @return was the crime reported? */ - virtual void commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, + virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, int arg=0); virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, 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); + /// 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); virtual void forceStateUpdate(const MWWorld::Ptr &ptr); diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 504a8638b..a6349c4da 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -371,4 +371,6 @@ op 0x2000230: Resurrect, explicit op 0x2000231: GetSpellReadied op 0x2000232: GetSpellReadied, explicit op 0x2000233: GetPcJumping -opcodes 0x2000234-0x3ffffff unused +op 0x2000234: ShowRestMenu, explicit +opcodes 0x2000235-0x3ffffff unused + diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index 6c89a0d1c..ebba2a492 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -11,11 +11,15 @@ #include #include "../mwworld/esmstore.hpp" +#include "../mwworld/player.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" + #include "interpretercontext.hpp" +#include "ref.hpp" namespace MWScript { @@ -45,6 +49,27 @@ namespace MWScript } }; + template + class OpShowRestMenu : public Interpreter::Opcode0 + { + public: + virtual void execute (Interpreter::Runtime& runtime) + { + // FIXME: No way to tell if we have a reference before trying to get it, and it will + // cause an exception is there isn't one :( + MWWorld::Ptr bed; + try { + bed = R()(runtime); + } + catch(std::runtime_error&) { + } + + if (bed.isEmpty() || !MWBase::Environment::get().getMechanicsManager()->sleepInBed(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), + bed)) + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_RestBed); + } + }; + class OpShowDialogue : public Interpreter::Opcode0 { MWGui::GuiMode mDialogue; @@ -172,7 +197,8 @@ namespace MWScript new OpEnableRest ()); interpreter.installSegment5 (Compiler::Gui::opcodeShowRestMenu, - new OpShowDialogue (MWGui::GM_RestBed)); + new OpShowRestMenu); + interpreter.installSegment5 (Compiler::Gui::opcodeShowRestMenuExplicit, new OpShowRestMenu); interpreter.installSegment5 (Compiler::Gui::opcodeGetButtonPressed, new OpGetButtonPressed); diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index 6194be532..e35a32ffa 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -198,7 +198,7 @@ namespace Compiler extensions.registerInstruction ("enablerest", "", opcodeEnableRest); extensions.registerInstruction ("enablelevelupmenu", "", opcodeEnableRest); - extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu); + extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu, opcodeShowRestMenuExplicit); extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed); diff --git a/components/compiler/opcodes.hpp b/components/compiler/opcodes.hpp index 46524c7cd..eb2240964 100644 --- a/components/compiler/opcodes.hpp +++ b/components/compiler/opcodes.hpp @@ -161,6 +161,7 @@ namespace Compiler const int opcodeEnableStatsMenu = 0x2000016; const int opcodeEnableRest = 0x2000017; const int opcodeShowRestMenu = 0x2000018; + const int opcodeShowRestMenuExplicit = 0x2000234; const int opcodeGetButtonPressed = 0x2000137; const int opcodeToggleFogOfWar = 0x2000145; const int opcodeToggleFullHelp = 0x2000151; From 098f9712f19787881ad0121b7d7debb8ce839b80 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 18:39:44 +0100 Subject: [PATCH 098/223] Add getPlayerPtr() utility method. Reduces dependencies a lot. --- apps/openmw/engine.cpp | 4 +-- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwclass/armor.cpp | 1 - apps/openmw/mwclass/clothing.cpp | 1 - apps/openmw/mwclass/container.cpp | 3 +- apps/openmw/mwclass/door.cpp | 5 ++- apps/openmw/mwclass/ingredient.cpp | 3 +- apps/openmw/mwclass/potion.cpp | 5 ++- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 3 +- apps/openmw/mwdialogue/filter.cpp | 11 +++---- apps/openmw/mwgui/alchemywindow.cpp | 7 ++-- apps/openmw/mwgui/bookwindow.cpp | 3 +- apps/openmw/mwgui/charactercreation.cpp | 5 ++- apps/openmw/mwgui/container.cpp | 7 ++-- apps/openmw/mwgui/dialogue.cpp | 3 +- apps/openmw/mwgui/enchantingdialog.cpp | 7 ++-- apps/openmw/mwgui/hud.cpp | 9 +++-- apps/openmw/mwgui/inventorywindow.cpp | 13 ++++---- apps/openmw/mwgui/levelupdialog.cpp | 7 ++-- apps/openmw/mwgui/mapwindow.cpp | 6 ++-- apps/openmw/mwgui/merchantrepair.cpp | 5 ++- apps/openmw/mwgui/quickkeysmenu.cpp | 11 +++---- apps/openmw/mwgui/recharge.cpp | 5 ++- apps/openmw/mwgui/referenceinterface.cpp | 4 +-- apps/openmw/mwgui/repair.cpp | 3 +- apps/openmw/mwgui/scrollwindow.cpp | 3 +- apps/openmw/mwgui/spellbuyingwindow.cpp | 5 ++- apps/openmw/mwgui/spellcreationdialog.cpp | 7 ++-- apps/openmw/mwgui/spellicons.cpp | 3 +- apps/openmw/mwgui/spellwindow.cpp | 11 +++---- apps/openmw/mwgui/statswindow.cpp | 8 ++--- apps/openmw/mwgui/tradewindow.cpp | 4 +-- apps/openmw/mwgui/trainingwindow.cpp | 5 ++- apps/openmw/mwgui/travelwindow.cpp | 5 ++- apps/openmw/mwgui/waitdialog.cpp | 7 ++-- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- apps/openmw/mwmechanics/actors.cpp | 5 ++- apps/openmw/mwmechanics/aicombat.cpp | 1 - apps/openmw/mwmechanics/aiescort.cpp | 3 +- apps/openmw/mwmechanics/aisequence.cpp | 3 +- apps/openmw/mwmechanics/aitravel.cpp | 3 +- apps/openmw/mwmechanics/aiwander.cpp | 1 - apps/openmw/mwmechanics/character.cpp | 1 - apps/openmw/mwmechanics/enchanting.cpp | 7 ++-- .../mwmechanics/mechanicsmanagerimp.cpp | 22 ++++++------- apps/openmw/mwmechanics/npcstats.cpp | 1 - apps/openmw/mwmechanics/repair.cpp | 5 ++- apps/openmw/mwmechanics/security.cpp | 1 - apps/openmw/mwmechanics/spellcasting.cpp | 2 +- apps/openmw/mwrender/characterpreview.cpp | 3 +- apps/openmw/mwrender/renderingmanager.cpp | 7 ++-- apps/openmw/mwrender/ripplesimulation.cpp | 6 ++-- apps/openmw/mwscript/cellextensions.cpp | 11 +++---- apps/openmw/mwscript/containerextensions.cpp | 5 ++- apps/openmw/mwscript/controlextensions.cpp | 5 ++- apps/openmw/mwscript/dialogueextensions.cpp | 3 +- apps/openmw/mwscript/guiextensions.cpp | 3 +- apps/openmw/mwscript/interpretercontext.cpp | 15 ++++----- apps/openmw/mwscript/miscextensions.cpp | 3 +- apps/openmw/mwscript/statsextensions.cpp | 33 +++++++++---------- .../mwscript/transformationextensions.cpp | 4 +-- apps/openmw/mwsound/soundmanagerimp.cpp | 5 ++- apps/openmw/mwworld/actionequip.cpp | 4 +-- apps/openmw/mwworld/actionread.cpp | 2 +- apps/openmw/mwworld/containerstore.cpp | 6 ++-- apps/openmw/mwworld/scene.cpp | 10 +++--- apps/openmw/mwworld/weather.cpp | 4 +-- apps/openmw/mwworld/worldimp.cpp | 21 +++++++----- apps/openmw/mwworld/worldimp.hpp | 1 + 69 files changed, 174 insertions(+), 224 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2a5ab3f07..b59b6a2fd 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -511,13 +511,13 @@ void OMW::Engine::activate() MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr); boost::shared_ptr action = - MWWorld::Class::get (ptr).activate (ptr, MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + MWWorld::Class::get (ptr).activate (ptr, MWBase::Environment::get().getWorld()->getPlayerPtr()); interpreterContext.activate (ptr, action); std::string script = MWWorld::Class::get (ptr).getScript (ptr); - MWBase::Environment::get().getWorld()->breakInvisibility(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + MWBase::Environment::get().getWorld()->breakInvisibility(MWBase::Environment::get().getWorld()->getPlayerPtr()); if (!script.empty()) { diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 39919012e..611bd913b 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -112,6 +112,7 @@ namespace MWBase virtual const MWWorld::Fallback *getFallback () const = 0; virtual MWWorld::Player& getPlayer() = 0; + virtual MWWorld::Ptr getPlayerPtr() = 0; virtual const MWWorld::ESMStore& getStore() const = 0; diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 13d19d86d..5e37426c9 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -17,7 +17,6 @@ #include "../mwworld/physicssystem.hpp" #include "../mwworld/nullaction.hpp" #include "../mwworld/containerstore.hpp" -#include "../mwworld/player.hpp" #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index b3278d07a..62fc26a71 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -14,7 +14,6 @@ #include "../mwworld/cellstore.hpp" #include "../mwworld/physicssystem.hpp" #include "../mwworld/nullaction.hpp" -#include "../mwworld/player.hpp" #include "../mwgui/tooltips.hpp" diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index d129e617d..f89a6bce0 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -16,7 +16,6 @@ #include "../mwworld/actionopen.hpp" #include "../mwworld/actiontrap.hpp" #include "../mwworld/physicssystem.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwgui/tooltips.hpp" @@ -108,7 +107,7 @@ namespace MWClass const std::string lockedSound = "LockedChest"; const std::string trapActivationSound = "Disarm Trap Fail"; - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player); bool needKey = ptr.getCellRef().mLockLevel>0; diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 3adb4f6fc..f99cffe04 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -8,7 +8,6 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/nullaction.hpp" #include "../mwworld/failedaction.hpp" @@ -97,7 +96,7 @@ namespace MWClass if (needKey && hasKey) { - if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) + if(actor == MWBase::Environment::get().getWorld()->getPlayerPtr()) MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}"); ptr.getCellRef().mLockLevel = 0; // using a key disarms the trap @@ -118,7 +117,7 @@ namespace MWClass { // teleport door /// \todo remove this if clause once ActionTeleport can also support other actors - if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor) + if (MWBase::Environment::get().getWorld()->getPlayerPtr()==actor) { boost::shared_ptr action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest)); diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index c6ec3deb9..faf29bc83 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -12,7 +12,6 @@ #include "../mwworld/cellstore.hpp" #include "../mwworld/physicssystem.hpp" #include "../mwworld/actioneat.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/nullaction.hpp" #include "../mwmechanics/npcstats.hpp" @@ -153,7 +152,7 @@ namespace MWClass text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase(); diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index 457a1c696..d68db4e45 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -13,7 +13,6 @@ #include "../mwworld/cellstore.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/physicssystem.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/nullaction.hpp" #include "../mwgui/tooltips.hpp" @@ -133,7 +132,7 @@ namespace MWClass info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects); // hide effects the player doesnt know about - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase(); int i=0; @@ -167,7 +166,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayerPtr(); // remove used potion (assume it is present in inventory) ptr.getContainerStore()->remove(ptr, 1, actor); diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 0eb20c50a..2fce7e327 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -30,7 +30,6 @@ #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwworld/player.hpp" #include "../mwgui/dialogue.hpp" @@ -493,7 +492,7 @@ namespace MWDialogue else if (curDisp + mTemporaryDispositionChange > 100) mTemporaryDispositionChange = 100 - curDisp; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Class::get(player).skillUsageSucceeded(player, ESM::Skill::Speechcraft, success ? 0 : 1); std::string text; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 6f16a79ca..af676d643 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -8,7 +8,6 @@ #include "../mwbase/dialoguemanager.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/inventorystore.hpp" @@ -93,7 +92,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const { - const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); // check player faction if (!info.mPcFaction.empty()) @@ -212,7 +211,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c case SelectWrapper::Function_PcHealthPercent: { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); float ratio = MWWorld::Class::get (player).getCreatureStats (player).getHealth().getCurrent() / MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified(); @@ -222,7 +221,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c case SelectWrapper::Function_PcDynamicStat: { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); float value = MWWorld::Class::get (player).getCreatureStats (player). getDynamic (select.getArgument()).getCurrent(); @@ -246,7 +245,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); switch (select.getFunction()) { @@ -420,7 +419,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); switch (select.getFunction()) { diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 09f692e4f..ddbd3f120 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -8,7 +8,6 @@ #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "inventoryitemmodel.hpp" @@ -143,9 +142,9 @@ namespace MWGui void AlchemyWindow::open() { - mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayerPtr()); - InventoryItemModel* model = new InventoryItemModel(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + InventoryItemModel* model = new InventoryItemModel(MWBase::Environment::get().getWorld()->getPlayerPtr()); mSortModel = new SortFilterItemModel(model); mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients); mItemView->setModel (mSortModel); @@ -154,7 +153,7 @@ namespace MWGui int index = 0; - mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayerPtr()); for (MWMechanics::Alchemy::TToolsIterator iter (mAlchemy.beginTools()); iter!=mAlchemy.endTools() && index (mApparatus.size()); ++iter, ++index) diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index c28ef96ef..98d963b22 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -8,7 +8,6 @@ #include "../mwbase/windowmanager.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/player.hpp" #include "formatting.hpp" @@ -138,7 +137,7 @@ namespace MWGui MWBase::Environment::get().getSoundManager()->playSound("Item Book Up", 1.0, 1.0); MWWorld::ActionTake take(mBook); - take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + take.execute (MWBase::Environment::get().getWorld()->getPlayerPtr()); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book); } diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index fb593650d..1a3226074 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -13,7 +13,6 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwworld/class.hpp" #include "../mwworld/fallback.hpp" -#include "../mwworld/player.hpp" namespace { @@ -47,7 +46,7 @@ namespace void updatePlayerHealth() { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats(player); creatureStats.updateHealth(); @@ -220,7 +219,7 @@ namespace MWGui mReviewDialog->setBirthSign(mPlayerBirthSignId); { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); mReviewDialog->setHealth ( stats.getHealth() ); diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index aa80388f3..28f6dd489 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -10,7 +10,6 @@ #include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwmechanics/pickpocket.hpp" @@ -223,7 +222,7 @@ namespace MWGui if (mPtr.getTypeName() == typeid(ESM::NPC).name() && !loot) { // we are stealing stuff - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); mModel = new PickpocketItemModel(player, new InventoryItemModel(container)); } else @@ -251,7 +250,7 @@ namespace MWGui && !mPickpocketDetected ) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::Pickpocket pickpocket(player, mPtr); if (pickpocket.finish()) { @@ -325,7 +324,7 @@ namespace MWGui bool ContainerWindow::onTakeItem(const ItemStack &item, int count) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if (dynamic_cast(mModel)) { MWMechanics::Pickpocket pickpocket(player, mPtr); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 914302d84..0460900ed 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -12,7 +12,6 @@ #include "../mwmechanics/npcstats.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwdialogue/dialoguemanagerimp.hpp" @@ -69,7 +68,7 @@ namespace MWGui void PersuasionDialog::onPersuade(MyGUI::Widget *sender) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWBase::MechanicsManager::PersuasionType type; if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire; else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate; diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index d2e914d17..cb57b51b1 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -5,7 +5,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/class.hpp" @@ -106,7 +105,7 @@ namespace MWGui void EnchantingDialog::startSelfEnchanting(MWWorld::Ptr soulgem) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); mEnchanting.setSelfEnchanting(true); mEnchanting.setEnchanter(player); @@ -149,7 +148,7 @@ namespace MWGui mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected); mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel); mItemSelectionDialog->setVisible(true); - mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr()); mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable); } @@ -236,7 +235,7 @@ namespace MWGui mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected); mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel); mItemSelectionDialog->setVisible(true); - mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr()); mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones); //MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}"); diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 8ef5e59d0..7cd9e2256 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -6,7 +6,6 @@ #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwmechanics/creaturestats.hpp" @@ -242,7 +241,7 @@ namespace MWGui if (world->canPlaceObject(mouseX, mouseY)) world->placeObject(object, mouseX, mouseY, mDragAndDrop->mDraggedCount); else - world->dropObjectOnGround(world->getPlayer().getPlayer(), object, mDragAndDrop->mDraggedCount); + world->dropObjectOnGround(world->getPlayerPtr(), object, mDragAndDrop->mDraggedCount); MWBase::Environment::get().getWindowManager()->changePointer("arrow"); @@ -320,7 +319,7 @@ namespace MWGui void HUD::onWeaponClicked(MyGUI::Widget* _sender) { - const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf()) { MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}"); @@ -332,7 +331,7 @@ namespace MWGui void HUD::onMagicClicked(MyGUI::Widget* _sender) { - const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf()) { MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}"); @@ -517,7 +516,7 @@ namespace MWGui mWeapStatus->setProgressPosition(0); MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf()) mWeapImage->setImageTexture("icons\\k\\tx_werewolf_hand.dds"); else diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 33814455a..27be9339b 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -10,7 +10,6 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/action.hpp" @@ -34,7 +33,7 @@ namespace MWGui , mTrading(false) , mLastXSize(0) , mLastYSize(0) - , mPreview(MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ()) + , mPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr()) , mPreviewDirty(true) , mDragAndDrop(dragAndDrop) , mSelectedItem(-1) @@ -85,7 +84,7 @@ namespace MWGui void InventoryWindow::updatePlayer() { - mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + mPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr()); mSortModel = new SortFilterItemModel(mTradeModel); mItemView->setModel(mSortModel); @@ -277,7 +276,7 @@ namespace MWGui void InventoryWindow::open() { - mPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + mPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); updateEncumbranceBar(); @@ -373,7 +372,7 @@ namespace MWGui boost::shared_ptr action = MWWorld::Class::get(ptr).use(ptr); - action->execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + 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. @@ -433,7 +432,7 @@ namespace MWGui void InventoryWindow::updateEncumbranceBar() { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); float capacity = MWWorld::Class::get(player).getCapacity(player); float encumbrance = MWWorld::Class::get(player).getEncumbrance(player); @@ -518,7 +517,7 @@ namespace MWGui // add to player inventory // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player); // remove from world MWBase::Environment::get().getWorld()->deleteObject (object); diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index e3d8f5dd7..e55d9d8ca 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -6,7 +6,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/fallback.hpp" @@ -59,7 +58,7 @@ namespace MWGui void LevelupDialog::setAttributeValues() { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); @@ -115,7 +114,7 @@ namespace MWGui void LevelupDialog::open() { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); @@ -155,7 +154,7 @@ namespace MWGui void LevelupDialog::onOkButtonClicked (MyGUI::Widget* sender) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 2f34df236..ba6114262 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -294,7 +294,7 @@ namespace MWGui std::vector markers; MWBase::World* world = MWBase::Environment::get().getWorld(); world->listDetectedReferences( - world->getPlayer().getPlayer(), + world->getPlayerPtr(), markers, MWBase::World::DetectionType(type)); if (markers.empty()) return; @@ -515,8 +515,8 @@ namespace MWGui // For interiors, position is set by WindowManager via setGlobalMapPlayerPosition if (MWBase::Environment::get().getWorld ()->isCellExterior ()) { - Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition (); - Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation (); + Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayerPtr().getRefData ().getBaseNode ()->_getDerivedPosition (); + Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayerPtr().getRefData ().getBaseNode ()->_getDerivedOrientation (); Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y); float worldX, worldY; diff --git a/apps/openmw/mwgui/merchantrepair.cpp b/apps/openmw/mwgui/merchantrepair.cpp index 4da166820..20eb3a615 100644 --- a/apps/openmw/mwgui/merchantrepair.cpp +++ b/apps/openmw/mwgui/merchantrepair.cpp @@ -8,7 +8,6 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" @@ -36,7 +35,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor) int currentY = 0; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor; for (MWWorld::ContainerStoreIterator iter (store.begin(categories)); @@ -119,7 +118,7 @@ void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender) int price = boost::lexical_cast(sender->getUserString("Price")); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); player.getClass().getContainerStore(player).remove("gold_001", price, player); startRepair(mActor); diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index b8f52cd1f..77127f59b 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -2,7 +2,6 @@ #include -#include "../mwworld/player.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/actionequip.hpp" #include "../mwmechanics/spellcasting.hpp" @@ -126,7 +125,7 @@ namespace MWGui mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &QuickKeysMenu::onAssignItemCancel); } mItemSelectionDialog->setVisible(true); - mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr()); mAssignDialog->setVisible (false); } @@ -267,7 +266,7 @@ namespace MWGui QuickKeyType type = *button->getUserData(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player); if (type == Type_Item || type == Type_MagicItem) @@ -311,7 +310,7 @@ namespace MWGui boost::shared_ptr action = MWWorld::Class::get(item).use(item); - action->execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + 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. @@ -344,7 +343,7 @@ namespace MWGui // Note: can't use Class::use here because enchanted scrolls for example would then open the scroll window instead of equipping MWWorld::ActionEquip action(item); - action.execute (MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ()); + action.execute (MWBase::Environment::get().getWorld ()->getPlayerPtr()); } store.setSelectedEnchantItem(it); @@ -430,7 +429,7 @@ namespace MWGui const int spellHeight = 18; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::Spells& spells = stats.getSpells(); diff --git a/apps/openmw/mwgui/recharge.cpp b/apps/openmw/mwgui/recharge.cpp index b700360ba..683406d9e 100644 --- a/apps/openmw/mwgui/recharge.cpp +++ b/apps/openmw/mwgui/recharge.cpp @@ -7,7 +7,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" @@ -85,7 +84,7 @@ void Recharge::updateView() int currentY = 0; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) @@ -141,7 +140,7 @@ void Recharge::onItemClicked(MyGUI::Widget *sender) MWWorld::Ptr item = *sender->getUserData(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); MWMechanics::NpcStats& npcStats = player.getClass().getNpcStats(player); diff --git a/apps/openmw/mwgui/referenceinterface.cpp b/apps/openmw/mwgui/referenceinterface.cpp index 86a85be18..756cd5736 100644 --- a/apps/openmw/mwgui/referenceinterface.cpp +++ b/apps/openmw/mwgui/referenceinterface.cpp @@ -3,8 +3,6 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" -#include "../mwworld/player.hpp" - namespace MWGui { ReferenceInterface::ReferenceInterface() @@ -18,7 +16,7 @@ namespace MWGui void ReferenceInterface::checkReferenceAvailable() { - MWWorld::Ptr::CellStore* playerCell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); + MWWorld::Ptr::CellStore* playerCell = MWBase::Environment::get().getWorld()->getPlayerPtr().getCell(); // check if player has changed cell, or count of the reference has become 0 if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL) diff --git a/apps/openmw/mwgui/repair.cpp b/apps/openmw/mwgui/repair.cpp index 0bd4b0995..d729ee7fa 100644 --- a/apps/openmw/mwgui/repair.cpp +++ b/apps/openmw/mwgui/repair.cpp @@ -6,7 +6,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" @@ -88,7 +87,7 @@ void Repair::updateRepairView() int currentY = 0; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor; for (MWWorld::ContainerStoreIterator iter (store.begin(categories)); diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index 48931b18e..e1970004c 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -6,7 +6,6 @@ #include "../mwbase/windowmanager.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/player.hpp" #include "formatting.hpp" @@ -90,7 +89,7 @@ namespace MWGui MWBase::Environment::get().getSoundManager()->playSound("Item Book Up", 1.0, 1.0); MWWorld::ActionTake take(mScroll); - take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + take.execute (MWBase::Environment::get().getWorld()->getPlayerPtr()); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll); } diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index bbd28b2de..f285b01ca 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -8,7 +8,6 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" @@ -103,7 +102,7 @@ namespace MWGui bool SpellBuyingWindow::playerHasSpell(const std::string &id) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::Spells& playerSpells = MWWorld::Class::get (player).getCreatureStats (player).getSpells(); for (MWMechanics::Spells::TIterator it = playerSpells.begin(); it != playerSpells.end(); ++it) { @@ -119,7 +118,7 @@ namespace MWGui if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()>=price) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::Spells& spells = stats.getSpells(); spells.add (mSpellsWidgetMap.find(_sender)->second); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index b9324fea1..3a17d50aa 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -7,7 +7,6 @@ #include "../mwbase/soundmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwmechanics/spellcasting.hpp" @@ -342,7 +341,7 @@ namespace MWGui mSpell.mName = mNameEdit->getCaption(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); player.getClass().getContainerStore(player).remove("gold_001", boost::lexical_cast(mPriceLabel->getCaption()), player); @@ -414,7 +413,7 @@ namespace MWGui mPriceLabel->setCaption(boost::lexical_cast(int(price))); - float chance = MWMechanics::getSpellSuccessChance(&mSpell, MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + float chance = MWMechanics::getSpellSuccessChance(&mSpell, MWBase::Environment::get().getWorld()->getPlayerPtr()); mSuccessChance->setCaption(boost::lexical_cast(int(chance))); } @@ -441,7 +440,7 @@ namespace MWGui { // get the list of magic effects that are known to the player - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::Spells& spells = stats.getSpells(); diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 891206532..0cd665a87 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -9,7 +9,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" @@ -40,7 +39,7 @@ namespace MWGui { // TODO: Tracking add/remove/expire would be better than force updating every frame - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 2ca783bfc..21257ef9c 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -5,7 +5,6 @@ #include "../mwbase/windowmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/actionequip.hpp" @@ -81,7 +80,7 @@ namespace MWGui // retrieve all player spells, divide them into Powers and Spells and sort them std::vector spellList; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::Spells& spells = stats.getSpells(); @@ -298,7 +297,7 @@ namespace MWGui void SpellWindow::onEnchantedItemSelected(MyGUI::Widget* _sender) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player); MWWorld::Ptr item = *_sender->getUserData(); @@ -320,7 +319,7 @@ namespace MWGui // Note: can't use Class::use here because enchanted scrolls for example would then open the scroll window instead of equipping MWWorld::ActionEquip action(item); - action.execute (MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ()); + action.execute (MWBase::Environment::get().getWorld ()->getPlayerPtr()); // since we changed equipping status, update the inventory window MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView(); @@ -335,7 +334,7 @@ namespace MWGui void SpellWindow::onSpellSelected(MyGUI::Widget* _sender) { std::string spellId = _sender->getUserString("Spell"); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player); if (MyGUI::InputManager::getInstance().isShiftPressed()) @@ -389,7 +388,7 @@ namespace MWGui void SpellWindow::onDeleteSpellAccept() { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::Spells& spells = stats.getSpells(); diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 549cf65ab..17bb24e83 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -6,8 +6,8 @@ #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/player.hpp" #include "../mwmechanics/npcstats.hpp" @@ -224,7 +224,7 @@ namespace MWGui if (!mMainWidget->getVisible()) return; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWMechanics::NpcStats &PCstats = MWWorld::Class::get(player).getNpcStats(player); // level progress @@ -424,7 +424,7 @@ namespace MWGui MWBase::World *world = MWBase::Environment::get().getWorld(); const MWWorld::ESMStore &store = world->getStore(); const ESM::NPC *player = - world->getPlayer().getPlayer().get()->mBase; + world->getPlayerPtr().get()->mBase; // race tooltip const ESM::Race* playerRace = store.get().find(player->mRace); @@ -452,7 +452,7 @@ namespace MWGui if (!mSkillWidgets.empty()) addSeparator(coord1, coord2); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWMechanics::NpcStats &PCstats = MWWorld::Class::get(player).getNpcStats(player); const std::set &expelled = PCstats.getExpelled(); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index f67ea1a3f..0111623be 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -16,8 +16,6 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" -#include "../mwworld/player.hpp" - #include "inventorywindow.hpp" #include "itemview.hpp" #include "sortfilteritemmodel.hpp" @@ -271,7 +269,7 @@ namespace MWGui return; } - MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(mCurrentBalance > mCurrentMerchantOffer) { diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 04eddcb17..fc96d31bb 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -9,7 +9,6 @@ #include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" @@ -72,7 +71,7 @@ namespace MWGui MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator (); MyGUI::Gui::getInstance ().destroyWidgets (widgets); - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); const MWWorld::Store &gmst = @@ -115,7 +114,7 @@ namespace MWGui { int skillId = *sender->getUserData(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); const MWWorld::ESMStore &store = diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index dd5da4522..7f223c505 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -9,7 +9,6 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" @@ -57,7 +56,7 @@ namespace MWGui } else { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); ESM::Position PlayerPos = player.getRefData().getPosition(); float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); price = d/gmst.find("fTravelMult")->getFloat(); @@ -121,7 +120,7 @@ namespace MWGui int price; iss >> price; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()getPlayer().getPlayer(); + 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(); @@ -218,7 +217,7 @@ namespace MWGui void WaitDialog::setCanRest (bool canRest) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); bool full = (stats.getFatigue().getCurrent() >= stats.getFatigue().getModified()) && (stats.getHealth().getCurrent() >= stats.getHealth().getModified()) @@ -272,7 +271,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_RestBed); mWaiting = false; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWMechanics::NpcStats &pcstats = MWWorld::Class::get(player).getNpcStats(player); // trigger levelup if possible diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 8f19fb02e..77b72fc0a 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -355,7 +355,7 @@ namespace MWInput // if player tried to start moving, but can't (due to being overencumbered), display a notification. if (triedToMove) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); mOverencumberedMessageDelay -= dt; if (MWWorld::Class::get(player).getEncumbrance(player) >= MWWorld::Class::get(player).getCapacity(player)) { diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 74b459e6a..0a4adb6e2 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -11,7 +11,6 @@ #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/actionequip.hpp" @@ -163,7 +162,7 @@ namespace MWMechanics { CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); //engage combat or not? - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(ptr != player && !creatureStats.isHostile()) { ESM::Position playerpos = player.getRefData().getPosition(); @@ -585,7 +584,7 @@ namespace MWMechanics ptr.getClass().setActorHealth(ptr, stats.getHealth().getCurrent() - 3.0f*duration); // Play a drowning sound as necessary for the player - if(ptr == world->getPlayer().getPlayer()) + if(ptr == world->getPlayerPtr()) { MWBase::SoundManager *sndmgr = MWBase::Environment::get().getSoundManager(); if(!sndmgr->getSoundPlaying(MWWorld::Ptr(), "drown")) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index df45b7133..32b0063b6 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -3,7 +3,6 @@ #include "movement.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/timestamp.hpp" #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 5099625c0..35f9f1993 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -3,7 +3,6 @@ #include "movement.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/timestamp.hpp" #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" @@ -83,7 +82,7 @@ namespace MWMechanics return true; } - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); ESM::Position pos = actor.getRefData().getPosition(); bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY; const ESM::Pathgrid *pathgrid = diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index 6d461e5f6..139f54489 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -15,7 +15,6 @@ #include "npcstats.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/player.hpp" void MWMechanics::AiSequence::copy (const AiSequence& sequence) { @@ -63,7 +62,7 @@ bool MWMechanics::AiSequence::isPackageDone() const void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor,float duration) { - if(actor != MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) + if(actor != MWBase::Environment::get().getWorld()->getPlayerPtr()) { if (!mPackages.empty()) { diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index f56c75996..73b38dd13 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -5,7 +5,6 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" namespace { @@ -38,7 +37,7 @@ namespace MWMechanics Movement &movement = actor.getClass().getMovementSettings(actor); const ESM::Cell *cell = actor.getCell()->mCell; - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); if(cell->mData.mX != player.getCell()->mCell->mData.mX) { int sideX = sgn(cell->mData.mX - player.getCell()->mCell->mData.mX); diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 93c94a3f4..7df88c076 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -3,7 +3,6 @@ #include "movement.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 8a73c98af..50dad9cc0 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -33,7 +33,6 @@ #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 3991454db..f428bd4b0 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -1,5 +1,4 @@ #include "enchanting.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" @@ -53,7 +52,7 @@ namespace MWMechanics bool Enchanting::create() { - const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); ESM::Enchantment enchantment; enchantment.mData.mCharge = getGemCharge(); @@ -213,7 +212,7 @@ namespace MWMechanics return 0; const float enchantCost = getEnchantPoints(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::NpcStats &stats = MWWorld::Class::get(player).getNpcStats(player); int eSkill = stats.getSkill(ESM::Skill::Enchant).getModified(); @@ -297,7 +296,7 @@ namespace MWMechanics void Enchanting::payForEnchantment() const { - const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); store.remove("gold_001", getEnchantPrice(), player); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index b125b2899..47dd7858c 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -41,7 +41,7 @@ namespace MWMechanics { void MechanicsManager::buildPlayer() { - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr); @@ -251,7 +251,7 @@ namespace MWMechanics { // Uses ingame time, but scaled to real time duration /= MWBase::Environment::get().getWorld()->getTimeScaleFactor(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); player.getClass().getInventoryStore(player).rechargeItems(duration); } @@ -332,7 +332,7 @@ namespace MWMechanics MWBase::Environment::get().getWindowManager(); const ESM::NPC *player = - world->getPlayer().getPlayer().get()->mBase; + world->getPlayerPtr().get()->mBase; const ESM::Race *race = world->getStore().get().find(player->mRace); @@ -358,7 +358,7 @@ namespace MWMechanics // HACK? The player has been changed, so a new Animation object may // have been made for them. Make sure they're properly updated. - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); mActors.removeActor(ptr); mActors.addActor(ptr); } @@ -377,7 +377,7 @@ namespace MWMechanics MWBase::World *world = MWBase::Environment::get().getWorld(); ESM::NPC player = - *world->getPlayer().getPlayer().get()->mBase; + *world->getPlayerPtr().get()->mBase; player.mName = name; world->createRecord(player); @@ -390,7 +390,7 @@ namespace MWMechanics MWBase::World *world = MWBase::Environment::get().getWorld(); ESM::NPC player = - *world->getPlayer().getPlayer().get()->mBase; + *world->getPlayerPtr().get()->mBase; player.mRace = race; player.mHead = head; @@ -416,7 +416,7 @@ namespace MWMechanics MWBase::World *world = MWBase::Environment::get().getWorld(); ESM::NPC player = - *world->getPlayer().getPlayer().get()->mBase; + *world->getPlayerPtr().get()->mBase; player.mClass = id; world->createRecord(player); @@ -433,7 +433,7 @@ namespace MWMechanics const ESM::Class *ptr = world->createRecord(cls); ESM::NPC player = - *world->getPlayer().getPlayer().get()->mBase; + *world->getPlayerPtr().get()->mBase; player.mClass = ptr->mId; world->createRecord(player); @@ -449,7 +449,7 @@ namespace MWMechanics float x = npcSkill.getBaseDisposition(); MWWorld::LiveCellRef* npc = ptr.get(); - MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::LiveCellRef* player = playerPtr.get(); const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); @@ -517,7 +517,7 @@ namespace MWMechanics const MWMechanics::NpcStats &sellerStats = MWWorld::Class::get(ptr).getNpcStats(ptr); - MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); // I suppose the temporary disposition change _has_ to be considered here, @@ -562,7 +562,7 @@ namespace MWMechanics MWMechanics::NpcStats& npcStats = MWWorld::Class::get(npc).getNpcStats(npc); - MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); float persTerm = playerStats.getAttribute(ESM::Attribute::Personality).getModified() diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 94dd97186..9b70e3347 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -15,7 +15,6 @@ #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwworld/player.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwmechanics/repair.cpp b/apps/openmw/mwmechanics/repair.cpp index 5e8a46fd4..1b17f8305 100644 --- a/apps/openmw/mwmechanics/repair.cpp +++ b/apps/openmw/mwmechanics/repair.cpp @@ -8,7 +8,6 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" @@ -20,7 +19,7 @@ namespace MWMechanics void Repair::repair(const MWWorld::Ptr &itemToRepair) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::LiveCellRef *ref = mTool.get(); @@ -77,7 +76,7 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair) // tool used up? if (mTool.getCellRef().mCharge == 0) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); store.remove(mTool, 1, player); diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index c373e83f5..0769e13df 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -1,7 +1,6 @@ #include "security.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 52fb0805a..21b6d0d77 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -7,8 +7,8 @@ #include "../mwworld/containerstore.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/actionteleport.hpp" +#include "../mwworld/player.hpp" #include "../mwrender/animation.hpp" diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 643225515..f7333db35 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -10,7 +10,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" @@ -219,7 +218,7 @@ namespace MWRender // -------------------------------------------------------------------------------------------------- RaceSelectionPreview::RaceSelectionPreview() - : CharacterPreview(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), + : CharacterPreview(MWBase::Environment::get().getWorld()->getPlayerPtr(), 512, 512, "CharacterHeadPreview", Ogre::Vector3(0, 6, -35), Ogre::Vector3(0,125,0)) , mRef(&mBase) { diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index d950b8414..11d06704e 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -33,7 +33,6 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwworld/ptr.hpp" -#include "../mwworld/player.hpp" #include "shadows.hpp" #include "localmap.hpp" @@ -324,7 +323,7 @@ void RenderingManager::update (float duration, bool paused) { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::Blind).mMagnitude; mRendering.getFader()->setFactor(std::max(0.f, 1.f-(blind / 100.f))); @@ -585,7 +584,7 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour) { mAmbientColor = colour; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); int nightEye = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye).mMagnitude; Ogre::ColourValue final = colour; final += Ogre::ColourValue(0.7,0.7,0.7,0) * std::min(1.f, (nightEye/100.f)); @@ -737,7 +736,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec else if (it->second == "max viewing distance" && it->first == "Viewing distance") { if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior()) - configureFog(*MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()); + configureFog(*MWBase::Environment::get().getWorld()->getPlayerPtr().getCell()); } else if (it->first == "Video" && ( it->second == "resolution x" diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp index 47fbc8ddf..e5db8346f 100644 --- a/apps/openmw/mwrender/ripplesimulation.cpp +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -10,8 +10,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/player.hpp" - namespace MWRender { @@ -154,11 +152,11 @@ void RippleSimulation::addImpulses() /// \todo it should be more efficient to render all emitters at once for (std::vector::iterator it=mEmitters.begin(); it !=mEmitters.end(); ++it) { - if (it->mPtr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ()) + if (it->mPtr == MWBase::Environment::get().getWorld ()->getPlayerPtr()) { // fetch a new ptr (to handle cell change etc) // for non-player actors this is done in updateObjectCell - it->mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + it->mPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); } float* _currentPos = it->mPtr.getRefData().getPosition().pos; Ogre::Vector3 currentPos (_currentPos[0], _currentPos[1], _currentPos[2]); diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index f26602f7a..e0d41cd19 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -12,7 +12,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" - #include "../mwworld/player.hpp" #include "interpretercontext.hpp" @@ -89,7 +88,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { bool interior = - !MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->isExterior(); + !MWBase::Environment::get().getWorld()->getPlayerPtr().getCell()->mCell->isExterior(); runtime.push (interior ? 1 : 0); } @@ -104,7 +103,7 @@ namespace MWScript std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - const ESM::Cell *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell; + const ESM::Cell *cell = MWBase::Environment::get().getWorld()->getPlayerPtr().getCell()->mCell; std::string current = cell->mName; @@ -129,7 +128,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); + MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayerPtr().getCell(); runtime.push (cell->mWaterLevel); } }; @@ -142,7 +141,7 @@ namespace MWScript { Interpreter::Type_Float level = runtime[0].mFloat; - MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); + MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayerPtr().getCell(); if (cell->mCell->isExterior()) throw std::runtime_error("Can't set water level in exterior cell"); @@ -160,7 +159,7 @@ namespace MWScript { Interpreter::Type_Float level = runtime[0].mFloat; - MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); + MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayerPtr().getCell(); if (cell->mCell->isExterior()) throw std::runtime_error("Can't set water level in exterior cell"); diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 53f4c23c9..5234eaea3 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -21,7 +21,6 @@ #include "../mwworld/containerstore.hpp" #include "../mwworld/actionequip.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/player.hpp" #include "interpretercontext.hpp" #include "ref.hpp" @@ -55,7 +54,7 @@ namespace MWScript MWWorld::Ptr itemPtr = *ptr.getClass().getContainerStore (ptr).add (item, count, ptr); // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) - if (ptr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer() ) + if (ptr == MWBase::Environment::get().getWorld ()->getPlayerPtr() ) { // The two GMST entries below expand to strings informing the player of what, and how many of it has been added to their inventory std::string msgBox; @@ -133,7 +132,7 @@ namespace MWScript // Spawn a messagebox (only for items removed from player's inventory) if ((numRemoved > 0) - && (ptr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer())) + && (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())) { // The two GMST entries below expand to strings informing the player of what, and how many of it has been removed from their inventory std::string msgBox; diff --git a/apps/openmw/mwscript/controlextensions.cpp b/apps/openmw/mwscript/controlextensions.cpp index e46302b18..7697ab619 100644 --- a/apps/openmw/mwscript/controlextensions.cpp +++ b/apps/openmw/mwscript/controlextensions.cpp @@ -11,7 +11,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/ptr.hpp" @@ -144,7 +143,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer(); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); runtime.push (MWWorld::Class::get(ptr).getStance (ptr, MWWorld::Class::Run)); } }; @@ -155,7 +154,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer(); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); runtime.push (MWWorld::Class::get(ptr).getStance (ptr, MWWorld::Class::Sneak)); } }; diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index 5e797ee58..a882ae05e 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -13,7 +13,6 @@ #include "../mwbase/journal.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwmechanics/npcstats.hpp" #include "interpretercontext.hpp" @@ -183,7 +182,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); runtime.push (MWWorld::Class::get(ptr).getNpcStats (ptr).isSameFaction (MWWorld::Class::get(player).getNpcStats (player))); } diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index ebba2a492..e51bdcf69 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -11,7 +11,6 @@ #include #include "../mwworld/esmstore.hpp" -#include "../mwworld/player.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -64,7 +63,7 @@ namespace MWScript catch(std::runtime_error&) { } - if (bed.isEmpty() || !MWBase::Environment::get().getMechanicsManager()->sleepInBed(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), + if (bed.isEmpty() || !MWBase::Environment::get().getMechanicsManager()->sleepInBed(MWBase::Environment::get().getWorld()->getPlayerPtr(), bed)) MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_RestBed); } diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index b8fc9ed47..aa9e32008 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -14,7 +14,6 @@ #include "../mwbase/inputmanager.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwmechanics/npcstats.hpp" @@ -248,28 +247,28 @@ namespace MWScript std::string InterpreterContext::getPCName() const { MWBase::World *world = MWBase::Environment::get().getWorld(); - ESM::NPC player = *world->getPlayer().getPlayer().get()->mBase; + ESM::NPC player = *world->getPlayerPtr().get()->mBase; return player.mName; } std::string InterpreterContext::getPCRace() const { MWBase::World *world = MWBase::Environment::get().getWorld(); - std::string race = world->getPlayer().getPlayer().get()->mBase->mRace; + std::string race = world->getPlayerPtr().get()->mBase->mRace; return world->getStore().get().find(race)->mName; } std::string InterpreterContext::getPCClass() const { MWBase::World *world = MWBase::Environment::get().getWorld(); - std::string class_ = world->getPlayer().getPlayer().get()->mBase->mClass; + std::string class_ = world->getPlayerPtr().get()->mBase->mClass; return world->getStore().get().find(class_)->mName; } std::string InterpreterContext::getPCRank() const { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); std::string factionId = MWWorld::Class::get (mReference).getNpcStats (mReference).getFactionRanks().begin()->first; @@ -288,7 +287,7 @@ namespace MWScript std::string InterpreterContext::getPCNextRank() const { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); std::string factionId = MWWorld::Class::get (mReference).getNpcStats (mReference).getFactionRanks().begin()->first; @@ -316,7 +315,7 @@ namespace MWScript int InterpreterContext::getPCBounty() const { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); return MWWorld::Class::get (player).getNpcStats (player).getBounty(); } @@ -387,7 +386,7 @@ namespace MWScript if (!mAction.get()) throw std::runtime_error ("activation failed, because no action to perform"); - mAction->execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + mAction->execute (MWBase::Environment::get().getWorld()->getPlayerPtr()); mActivationHandled = true; } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 54a8139d8..61d286ae3 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -18,7 +18,6 @@ #include "../mwbase/scriptmanager.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwmechanics/npcstats.hpp" @@ -65,7 +64,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWBase::World* world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); runtime.push (!world->isOnGround(player) && !world->isFlying(player)); } }; diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index f053e9a97..2ade3200e 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -21,7 +21,6 @@ #include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" @@ -391,7 +390,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); runtime.push (static_cast (MWWorld::Class::get (player).getNpcStats (player).getBounty())); } }; @@ -403,7 +402,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); MWWorld::Class::get (player).getNpcStats (player).setBounty(runtime[0].mFloat); runtime.pop(); @@ -417,7 +416,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); MWWorld::Class::get (player).getNpcStats (player).setBounty(runtime[0].mFloat + MWWorld::Class::get (player).getNpcStats (player).getBounty()); runtime.pop(); @@ -539,7 +538,7 @@ namespace MWScript Misc::StringUtils::toLower(factionID); if(factionID != "") { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(MWWorld::Class::get(player).getNpcStats(player).getFactionRanks().find(factionID) == MWWorld::Class::get(player).getNpcStats(player).getFactionRanks().end()) { MWWorld::Class::get(player).getNpcStats(player).getFactionRanks()[factionID] = 0; @@ -568,7 +567,7 @@ namespace MWScript Misc::StringUtils::toLower(factionID); if(factionID != "") { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(MWWorld::Class::get(player).getNpcStats(player).getFactionRanks().find(factionID) == MWWorld::Class::get(player).getNpcStats(player).getFactionRanks().end()) { MWWorld::Class::get(player).getNpcStats(player).getFactionRanks()[factionID] = 0; @@ -601,7 +600,7 @@ namespace MWScript Misc::StringUtils::toLower(factionID); if(factionID != "") { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(MWWorld::Class::get(player).getNpcStats(player).getFactionRanks().find(factionID) != MWWorld::Class::get(player).getNpcStats(player).getFactionRanks().end()) { MWWorld::Class::get(player).getNpcStats(player).getFactionRanks()[factionID] = MWWorld::Class::get(player).getNpcStats(player).getFactionRanks()[factionID] -1; @@ -637,7 +636,7 @@ namespace MWScript } } Misc::StringUtils::toLower(factionID); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(factionID!="") { if(MWWorld::Class::get(player).getNpcStats(player).getFactionRanks().find(factionID) != MWWorld::Class::get(player).getNpcStats(player).getFactionRanks().end()) @@ -740,7 +739,7 @@ namespace MWScript Misc::StringUtils::toLower (factionId); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); runtime.push ( MWWorld::Class::get (player).getNpcStats (player).getFactionReputation (factionId)); } @@ -776,7 +775,7 @@ namespace MWScript Misc::StringUtils::toLower (factionId); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Class::get (player).getNpcStats (player).setFactionReputation (factionId, value); } }; @@ -811,7 +810,7 @@ namespace MWScript Misc::StringUtils::toLower (factionId); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Class::get (player).getNpcStats (player).setFactionReputation (factionId, MWWorld::Class::get (player).getNpcStats (player).getFactionReputation (factionId)+ value); @@ -870,7 +869,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); runtime.push (MWWorld::Class::get(ptr).getNpcStats (ptr).getWerewolfKills ()); } @@ -903,7 +902,7 @@ namespace MWScript } } Misc::StringUtils::toLower(factionID); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(factionID!="") { std::set& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled (); @@ -949,7 +948,7 @@ namespace MWScript factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first; } } - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(factionID!="") { std::set& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled (); @@ -985,7 +984,7 @@ namespace MWScript factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first; } } - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(factionID!="") { std::set& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled (); @@ -1011,7 +1010,7 @@ namespace MWScript { factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first; } - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); // no-op when executed on the player if (ptr == player) @@ -1038,7 +1037,7 @@ namespace MWScript { factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first; } - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); // no-op when executed on the player if (ptr == player) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index e44180977..81aff9958 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -16,8 +16,8 @@ #include "../mwbase/environment.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/manualref.hpp" +#include "../mwworld/player.hpp" #include "interpretercontext.hpp" #include "ref.hpp" @@ -482,7 +482,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr actor = pc - ? MWBase::Environment::get().getWorld()->getPlayer().getPlayer() + ? MWBase::Environment::get().getWorld()->getPlayerPtr() : R()(runtime); std::string itemID = runtime.getStringLiteral (runtime[0].mInteger); diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 2e52739ac..28a3aae37 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -8,7 +8,6 @@ #include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwworld/player.hpp" #include "sound_output.hpp" #include "sound_decoder.hpp" @@ -479,7 +478,7 @@ namespace MWSound static std::string regionName = ""; static float sTimePassed = 0.0; MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Ptr player = world->getPlayer().getPlayer(); + const MWWorld::Ptr player = world->getPlayerPtr(); const ESM::Cell *cell = player.getCell()->mCell; sTimePassed += duration; @@ -547,7 +546,7 @@ namespace MWSound startRandomTitle(); MWWorld::Ptr player = - MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWBase::Environment::get().getWorld()->getPlayerPtr(); const ESM::Cell *cell = player.getCell()->mCell; Environment env = Env_Normal; diff --git a/apps/openmw/mwworld/actionequip.cpp b/apps/openmw/mwworld/actionequip.cpp index 0d091e742..6a0b4eec7 100644 --- a/apps/openmw/mwworld/actionequip.cpp +++ b/apps/openmw/mwworld/actionequip.cpp @@ -24,7 +24,7 @@ namespace MWWorld std::pair result = MWWorld::Class::get (object).canBeEquipped (object, actor); // display error message if the player tried to equip something - if (!result.second.empty() && actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) + if (!result.second.empty() && actor == MWBase::Environment::get().getWorld()->getPlayerPtr()) MWBase::Environment::get().getWindowManager()->messageBox(result.second); switch(result.first) @@ -84,7 +84,7 @@ namespace MWWorld 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()->getPlayer().getPlayer() && script != "") + if(equipped && actor == MWBase::Environment::get().getWorld()->getPlayerPtr() && script != "") object.getRefData().getLocals().setVarByInt(script, "onpcequip", 1); } } diff --git a/apps/openmw/mwworld/actionread.cpp b/apps/openmw/mwworld/actionread.cpp index 6d5d9d8fd..67755259e 100644 --- a/apps/openmw/mwworld/actionread.cpp +++ b/apps/openmw/mwworld/actionread.cpp @@ -34,7 +34,7 @@ namespace MWWorld MWBase::Environment::get().getWindowManager()->getBookWindow()->open(getTarget()); } - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); // Skill gain from books diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index ee4080755..08d29b86b 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -148,7 +148,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr { CellStore *cell; - Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); if(&(MWWorld::Class::get (player).getContainerStore (player)) == this) { @@ -305,8 +305,8 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std:: const ESM::ItemLevList* levItem = ref.getPtr().get()->mBase; const std::vector& items = levItem->mList; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - int playerLevel = MWWorld::Class::get(player).getCreatureStats(player).getLevel(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerLevel = player.getClass().getCreatureStats(player).getLevel(); failChance += levItem->mChanceNone; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index b3a9c9bb3..3607b8276 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -166,10 +166,10 @@ namespace MWWorld void Scene::playerCellChange(MWWorld::CellStore *cell, const ESM::Position& pos, bool adjustPlayerPos) { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr old = world->getPlayer().getPlayer(); + MWWorld::Ptr old = world->getPlayerPtr(); world->getPlayer().setCell(cell); - MWWorld::Ptr player = world->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayerPtr(); mRendering.updatePlayerPtr(player); if (adjustPlayerPos) { @@ -369,14 +369,14 @@ namespace MWWorld if(!loadcell) { MWBase::World *world = MWBase::Environment::get().getWorld(); - world->moveObject(world->getPlayer().getPlayer(), position.pos[0], position.pos[1], position.pos[2]); + world->moveObject(world->getPlayerPtr(), position.pos[0], position.pos[1], position.pos[2]); float x = Ogre::Radian(position.rot[0]).valueDegrees(); float y = Ogre::Radian(position.rot[1]).valueDegrees(); float z = Ogre::Radian(position.rot[2]).valueDegrees(); - world->rotateObject(world->getPlayer().getPlayer(), x, y, z); + world->rotateObject(world->getPlayerPtr(), x, y, z); - MWWorld::Class::get(world->getPlayer().getPlayer()).adjustPosition(world->getPlayer().getPlayer()); + MWWorld::Class::get(world->getPlayerPtr()).adjustPosition(world->getPlayerPtr()); world->getFader()->fadeIn(0.5f); return; } diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 513dcf6c7..c34beb3f2 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -665,7 +665,7 @@ void WeatherManager::changeWeather(const std::string& region, const unsigned int mRegionOverrides[Misc::StringUtils::lowerCase(region)] = weather; - std::string playerRegion = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion; + std::string playerRegion = MWBase::Environment::get().getWorld()->getPlayerPtr().getCell()->mCell->mRegion; if (Misc::StringUtils::ciEqual(region, playerRegion)) setWeather(weather); } @@ -696,7 +696,7 @@ void WeatherManager::switchToNextWeather(bool instantly) MWBase::World* world = MWBase::Environment::get().getWorld(); if (world->isCellExterior() || world->isCellQuasiExterior()) { - std::string regionstr = Misc::StringUtils::lowerCase(world->getPlayer().getPlayer().getCell()->mCell->mRegion); + std::string regionstr = Misc::StringUtils::lowerCase(world->getPlayerPtr().getCell()->mCell->mRegion); if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) { diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index b72433e5a..8bb2e7956 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -753,16 +753,16 @@ namespace MWWorld void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position) { - removeContainerScripts(getPlayer().getPlayer()); + removeContainerScripts(getPlayerPtr()); mWorldScene->changeToInteriorCell(cellName, position); - addContainerScripts(getPlayer().getPlayer(), getPlayer().getPlayer().getCell()); + addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell()); } void World::changeToExteriorCell (const ESM::Position& position) { - removeContainerScripts(getPlayer().getPlayer()); + removeContainerScripts(getPlayerPtr()); mWorldScene->changeToExteriorCell(position); - addContainerScripts(getPlayer().getPlayer(), getPlayer().getPlayer().getCell()); + addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell()); } void World::markCellAsUnchanged() @@ -869,7 +869,7 @@ namespace MWWorld int cellY = newCell.mCell->getGridY(); mWorldScene->changeCell(cellX, cellY, pos, false); } - addContainerScripts (getPlayer().getPlayer(), &newCell); + addContainerScripts (getPlayerPtr(), &newCell); } else { @@ -1493,9 +1493,9 @@ namespace MWWorld cell = mCells.getExterior(cellX, cellY); } else - cell = getPlayer().getPlayer().getCell(); + cell = getPlayerPtr().getCell(); - ESM::Position pos = getPlayer().getPlayer().getRefData().getPosition(); + ESM::Position pos = getPlayerPtr().getRefData().getPosition(); pos.pos[0] = result.second[0]; pos.pos[1] = result.second[1]; pos.pos[2] = result.second[2]; @@ -2035,7 +2035,7 @@ namespace MWWorld std::string message; bool fail = false; - bool isPlayer = (actor == getPlayer().getPlayer()); + bool isPlayer = (actor == getPlayerPtr()); std::string selectedSpell = stats.getSpells().getSelectedSpell(); @@ -2415,4 +2415,9 @@ namespace MWWorld // with the Telekinesis effect. return feet * 22; } + + MWWorld::Ptr World::getPlayerPtr() + { + return mPlayer->getPlayer(); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 92a993157..51ad3a045 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -187,6 +187,7 @@ namespace MWWorld virtual const Fallback *getFallback() const; virtual Player& getPlayer(); + virtual MWWorld::Ptr getPlayerPtr(); virtual const MWWorld::ESMStore& getStore() const; From 19d63f392ff184ffa6835ccd452143606209c5a7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 18:59:00 +0100 Subject: [PATCH 099/223] Clean up the NpcStats expelled interface. Show message box when expelled. --- apps/openmw/mwdialogue/filter.cpp | 4 +--- .../mwmechanics/mechanicsmanagerimp.cpp | 2 +- apps/openmw/mwmechanics/npcstats.cpp | 20 +++++++++++++++---- apps/openmw/mwmechanics/npcstats.hpp | 6 ++++-- apps/openmw/mwscript/statsextensions.cpp | 20 +++---------------- 5 files changed, 25 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index af676d643..4f478afce 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -507,9 +507,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co std::string faction = MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first; - std::set& expelled = MWWorld::Class::get (player).getNpcStats (player).getExpelled(); - - return expelled.find (faction)!=expelled.end(); + return player.getClass().getNpcStats(player).getExpelled(faction); } case SelectWrapper::Function_PcVampire: diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 47dd7858c..53422fbb1 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -470,7 +470,7 @@ namespace MWMechanics it != MWBase::Environment::get().getWorld()->getStore().get().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.end(); ++it) { if(Misc::StringUtils::lowerCase(it->mFaction) == Misc::StringUtils::lowerCase(npcFaction) - && playerStats.getExpelled().find(Misc::StringUtils::lowerCase(it->mFaction)) == playerStats.getExpelled().end()) + && !playerStats.getExpelled(it->mFaction)) reaction = it->mReaction; } rank = playerStats.getFactionRanks().find(Misc::StringUtils::lowerCase(npcFaction))->second; diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 9b70e3347..289fcc70f 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -108,14 +108,26 @@ std::map& MWMechanics::NpcStats::getFactionRanks() return mFactionRank; } -const std::set& MWMechanics::NpcStats::getExpelled() const +bool MWMechanics::NpcStats::getExpelled(const std::string& factionID) const { - return mExpelled; + return mExpelled.find(Misc::StringUtils::lowerCase(factionID)) != mExpelled.end(); } -std::set& MWMechanics::NpcStats::getExpelled() +void MWMechanics::NpcStats::expell(const std::string& factionID) { - return mExpelled; + std::string lower = Misc::StringUtils::lowerCase(factionID); + if (mExpelled.find(lower) == mExpelled.end()) + { + std::string message = "#{sExpelledMessage}"; + message += MWBase::Environment::get().getWorld()->getStore().get().find(factionID)->mName; + MWBase::Environment::get().getWindowManager()->messageBox(message); + mExpelled.insert(lower); + } +} + +void MWMechanics::NpcStats::clearExpelled(const std::string& factionID) +{ + mExpelled.erase(Misc::StringUtils::lowerCase(factionID)); } bool MWMechanics::NpcStats::isSameFaction (const NpcStats& npcStats) const diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 586e06832..5fd358c85 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -99,8 +99,10 @@ namespace MWMechanics const std::map& getFactionRanks() const; std::map& getFactionRanks(); - const std::set& getExpelled() const; - std::set& getExpelled(); + const std::set& getExpelled() const { return mExpelled; } + bool getExpelled(const std::string& factionID) const; + void expell(const std::string& factionID); + void clearExpelled(const std::string& factionID); bool isSameFaction (const NpcStats& npcStats) const; ///< Do *this and \a npcStats share a faction? diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 2ade3200e..56b309576 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -905,15 +905,7 @@ namespace MWScript MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(factionID!="") { - std::set& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled (); - if (expelled.find (factionID) != expelled.end()) - { - runtime.push(1); - } - else - { - runtime.push(0); - } + runtime.push(player.getClass().getNpcStats(player).getExpelled(factionID)); } else { @@ -951,9 +943,7 @@ namespace MWScript MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(factionID!="") { - std::set& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled (); - Misc::StringUtils::toLower(factionID); - expelled.insert(factionID); + player.getClass().getNpcStats(player).expell(factionID); } } }; @@ -986,11 +976,7 @@ namespace MWScript } MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(factionID!="") - { - std::set& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled (); - Misc::StringUtils::toLower(factionID); - expelled.erase (factionID); - } + player.getClass().getNpcStats(player).clearExpelled(factionID); } }; From 9baa1bef7854e249dab21c4b5575d376df440736 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 19:26:03 +0100 Subject: [PATCH 100/223] Expell player from faction when committing a crime against a faction member --- apps/openmw/mwgui/container.cpp | 2 +- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 28f6dd489..bccc7120f 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -255,7 +255,7 @@ namespace MWGui if (pickpocket.finish()) { MWBase::Environment::get().getMechanicsManager()->reportCrime( - player, MWWorld::Ptr(), MWBase::MechanicsManager::OT_Pickpocket); + player, mPtr, MWBase::MechanicsManager::OT_Pickpocket); MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); MWBase::Environment::get().getDialogueManager()->say(mPtr, "Thief"); mPickpocketDetected = true; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 53422fbb1..429683b97 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -829,6 +829,18 @@ namespace MWMechanics ptr.getClass().getNpcStats(ptr).setBounty(ptr.getClass().getNpcStats(ptr).getBounty() + arg); + // If committing a crime against a faction member, expell from the faction + if (!victim.isEmpty() && victim.getClass().isNpc()) + { + std::string factionID; + if(!victim.getClass().getNpcStats(victim).getFactionRanks().empty()) + factionID = victim.getClass().getNpcStats(victim).getFactionRanks().begin()->first; + if (ptr.getClass().getNpcStats(ptr).isSameFaction(victim.getClass().getNpcStats(victim))) + { + ptr.getClass().getNpcStats(ptr).expell(factionID); + } + } + // TODO: make any guards in the area try to arrest the player } From 154fae9f251de3a589c75ee1291c4cc21bce7aac Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 19:52:57 +0100 Subject: [PATCH 101/223] Don't suppress exceptions thrown while running scripts --- apps/openmw/mwscript/scriptmanagerimp.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index 14fe5b7fd..8b6b7ed2a 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -114,10 +114,8 @@ namespace MWScript } catch (const std::exception& e) { - std::cerr << "execution of script " << name << " failed." << std::endl; - - if (mVerbose) - std::cerr << "(" << e.what() << ")" << std::endl; + std::cerr << "Execution of script " << name << " failed:" << std::endl; + std::cerr << e.what() << std::endl; iter->second.first.clear(); // don't execute again. } From bf02b77c1dc008c022b9e5ef294b77b5f53f5fa7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 19:57:13 +0100 Subject: [PATCH 102/223] Closes #1090: Don't throw an exception if a cell has no region in GetPCCell --- apps/openmw/mwscript/cellextensions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index e0d41cd19..0e3b379d8 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -107,7 +107,8 @@ namespace MWScript std::string current = cell->mName; - if (!(cell->mData.mFlags & ESM::Cell::Interior) && current.empty()) + if (!(cell->mData.mFlags & ESM::Cell::Interior) && current.empty() + && !cell->mRegion.empty()) { const ESM::Region *region = MWBase::Environment::get().getWorld()->getStore().get().find (cell->mRegion); From 3127b8518e321ec2ad5dce758c0960bd5acec03f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 8 Jan 2014 20:15:54 +0100 Subject: [PATCH 103/223] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index bd0c6ca74..561931cde 100644 --- a/credits.txt +++ b/credits.txt @@ -24,6 +24,7 @@ Chris Robinson (KittyCat) Cory F. Cohen (cfcohen) Cris Mihalache (Mirceam) darkf +Dmitry Shkurskiy (endorph) Douglas Diniz (Dgdiniz) Douglas Mencken (dougmencken) Edmondo Tommasina (edmondo) From c55f9bd0aaa931afde650849856eb0371778440a Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 20:19:47 +0100 Subject: [PATCH 104/223] GetWaterLevel fix (similar to MCP): if there is no water in the cell, return -FLT_MAX to prevent mods from incorrectly thinking the player is underwater. --- apps/openmw/mwscript/cellextensions.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index 0e3b379d8..5de95d1d4 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -130,7 +130,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayerPtr().getCell(); - runtime.push (cell->mWaterLevel); + if (cell->mCell->hasWater()) + runtime.push (cell->mWaterLevel); + else + runtime.push (-std::numeric_limits().max()); } }; From 372cd437d199529c9d4d2409d0692689eeaafd03 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 22:58:36 +0100 Subject: [PATCH 105/223] Add a utility function for counting items in a container --- apps/openmw/mwscript/containerextensions.cpp | 10 ++-------- apps/openmw/mwworld/containerstore.cpp | 9 +++++++++ apps/openmw/mwworld/containerstore.hpp | 3 +++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 5234eaea3..202ec6464 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -87,15 +87,9 @@ namespace MWScript std::string item = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr); + MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); - Interpreter::Type_Integer sum = 0; - - for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) - if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item)) - sum += iter->getRefData().getCount(); - - runtime.push (sum); + runtime.push (store.count(item)); } }; diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 08d29b86b..1583f26e1 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -77,6 +77,15 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end() return ContainerStoreIterator (this); } +int MWWorld::ContainerStore::count(const std::string &id) +{ + int total=0; + for (MWWorld::ContainerStoreIterator iter (begin()); iter!=end(); ++iter) + if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, id)) + total += iter->getRefData().getCount(); + return total; +} + void MWWorld::ContainerStore::unstack(const Ptr &ptr, const Ptr& container) { if (ptr.getRefData().getCount() <= 1) diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index e4e10b327..9a97f9c1c 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -92,6 +92,9 @@ namespace MWWorld void unstack (const Ptr& ptr, const Ptr& container); ///< Unstack an item in this container. The item's count will be set to 1, then a new stack will be added with (origCount-1). + /// @return How many items with refID \a id are in this container? + int count (const std::string& id); + protected: ContainerStoreIterator addNewStack (const Ptr& ptr, int count); ///< Add the item to this container (do not try to stack it onto existing items) From 0f5dc5917695d61953bce045f82919b4063f253e Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 23:37:46 +0100 Subject: [PATCH 106/223] Remove useless dependencies on InventoryWindow for getting player gold. Don't use string literals for gold_001 id, just to be sure. --- apps/openmw/mwclass/creature.cpp | 2 +- apps/openmw/mwclass/npc.cpp | 2 +- apps/openmw/mwgui/dialogue.cpp | 10 +++---- apps/openmw/mwgui/enchantingdialog.cpp | 7 ++--- apps/openmw/mwgui/inventorywindow.cpp | 13 ---------- apps/openmw/mwgui/inventorywindow.hpp | 2 -- apps/openmw/mwgui/merchantrepair.cpp | 12 ++++----- apps/openmw/mwgui/spellbuyingwindow.cpp | 19 +++++++++----- apps/openmw/mwgui/spellcreationdialog.cpp | 10 +++---- apps/openmw/mwgui/tradeitemmodel.cpp | 2 +- apps/openmw/mwgui/tradewindow.cpp | 26 +++++++++++-------- apps/openmw/mwgui/tradewindow.hpp | 4 +-- apps/openmw/mwgui/trainingwindow.cpp | 14 +++++----- apps/openmw/mwgui/travelwindow.cpp | 20 +++++++++----- apps/openmw/mwmechanics/enchanting.cpp | 2 +- .../mwmechanics/mechanicsmanagerimp.cpp | 1 + apps/openmw/mwworld/containerstore.cpp | 6 +++-- apps/openmw/mwworld/containerstore.hpp | 2 ++ 18 files changed, 82 insertions(+), 72 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 864a756c5..480c335c2 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -100,7 +100,7 @@ namespace MWClass // TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory. // (except for gold you gave him) - data->mContainerStore.add("gold_001", ref->mBase->mData.mGold, ptr); + data->mContainerStore.add(MWWorld::ContainerStore::sGoldId, ref->mBase->mData.mGold, ptr); // store ptr.getRefData().setCustomData (data.release()); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 24caed3f5..f3b396a70 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -328,7 +328,7 @@ namespace MWClass // TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory. // (except for gold you gave him) - getContainerStore(ptr).add("gold_001", gold, ptr); + getContainerStore(ptr).add(MWWorld::ContainerStore::sGoldId, gold, ptr); getInventoryStore(ptr).autoEquip(ptr); } diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 0460900ed..8269e8364 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -20,7 +20,6 @@ #include "list.hpp" #include "tradewindow.hpp" #include "spellbuyingwindow.hpp" -#include "inventorywindow.hpp" #include "travelwindow.hpp" #include "bookpage.hpp" @@ -75,17 +74,17 @@ namespace MWGui else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt; else if (sender == mBribe10Button) { - player.getClass().getContainerStore(player).remove("gold_001", 10, player); + player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, 10, player); type = MWBase::MechanicsManager::PT_Bribe10; } else if (sender == mBribe100Button) { - player.getClass().getContainerStore(player).remove("gold_001", 100, player); + player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, 100, player); type = MWBase::MechanicsManager::PT_Bribe100; } else /*if (sender == mBribe1000Button)*/ { - player.getClass().getContainerStore(player).remove("gold_001", 1000, player); + player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, 1000, player); type = MWBase::MechanicsManager::PT_Bribe1000; } @@ -99,7 +98,8 @@ namespace MWGui WindowModal::open(); center(); - int playerGold = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); mBribe10Button->setEnabled (playerGold >= 10); mBribe100Button->setEnabled (playerGold >= 100); diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index cb57b51b1..4d79875a2 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -5,12 +5,11 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" -#include "../mwworld/manualref.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" #include "itemselection.hpp" #include "container.hpp" -#include "inventorywindow.hpp" #include "sortfilteritemmodel.hpp" @@ -289,7 +288,9 @@ namespace MWGui mEnchanting.setNewItemName(mName->getCaption()); mEnchanting.setEffect(mEffectList); - if (mEnchanting.getEnchantPrice() > MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + if (mEnchanting.getEnchantPrice() > playerGold) { MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage18}"); return; diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 27be9339b..0ad156cdf 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -447,19 +447,6 @@ namespace MWGui updateEncumbranceBar(); } - int InventoryWindow::getPlayerGold() - { - MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); - - for (MWWorld::ContainerStoreIterator it = invStore.begin(); - it != invStore.end(); ++it) - { - if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001")) - return it->getRefData().getCount(); - } - return 0; - } - void InventoryWindow::setTrading(bool trading) { mTrading = trading; diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index 94ecfd4c8..112e737fa 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -31,8 +31,6 @@ namespace MWGui void pickUpObject (MWWorld::Ptr object); - int getPlayerGold(); - MyGUI::IntCoord getAvatarScreenCoord(); MWWorld::Ptr getAvatarSelectedItem(int x, int y); diff --git a/apps/openmw/mwgui/merchantrepair.cpp b/apps/openmw/mwgui/merchantrepair.cpp index 20eb3a615..8b811ff50 100644 --- a/apps/openmw/mwgui/merchantrepair.cpp +++ b/apps/openmw/mwgui/merchantrepair.cpp @@ -11,8 +11,6 @@ #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" -#include "inventorywindow.hpp" - namespace MWGui { @@ -36,6 +34,8 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor) int currentY = 0; MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor; for (MWWorld::ContainerStoreIterator iter (store.begin(categories)); @@ -69,7 +69,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor) MyGUI::Button* button = mList->createWidget( - (price>MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", + (price>playerGold) ? "SandTextGreyedOut" : "SandTextButton", 0, currentY, 0, @@ -79,7 +79,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor) currentY += 18; - button->setEnabled(price<=MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()); + button->setEnabled(price<=playerGold); button->setUserString("Price", boost::lexical_cast(price)); button->setUserData(*iter); button->setCaptionWithReplacing(name); @@ -92,7 +92,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor) mList->setCanvasSize (MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY))); mGoldLabel->setCaptionWithReplacing("#{sGold}: " - + boost::lexical_cast(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold())); + + boost::lexical_cast(playerGold)); } void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel) @@ -119,7 +119,7 @@ void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender) int price = boost::lexical_cast(sender->getUserString("Price")); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - player.getClass().getContainerStore(player).remove("gold_001", price, player); + player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); startRepair(mActor); } diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index f285b01ca..4be7919a9 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -13,8 +13,6 @@ #include "../mwmechanics/creaturestats.hpp" -#include "inventorywindow.hpp" - namespace MWGui { const int SpellBuyingWindow::sLineHeight = 18; @@ -42,9 +40,12 @@ namespace MWGui int price = spell->mData.mCost*store.get().find("fSpellValueMult")->getFloat(); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + MyGUI::Button* toAdd = mSpellsView->createWidget( - (price>MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", + (price>playerGold) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, @@ -116,13 +117,16 @@ namespace MWGui { int price = *_sender->getUserData(); - if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()>=price) + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + + if (playerGold>=price) { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::Spells& spells = stats.getSpells(); spells.add (mSpellsWidgetMap.find(_sender)->second); - player.getClass().getContainerStore(player).remove("gold_001", price, player); + player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); startSpellBuying(mPtr); MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); @@ -136,7 +140,10 @@ namespace MWGui void SpellBuyingWindow::updateLabels() { - mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold())); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + + mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(playerGold)); mPlayerGold->setCoord(8, mPlayerGold->getTop(), mPlayerGold->getTextSize().width, diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 3a17d50aa..857dd76d5 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -13,7 +13,6 @@ #include "tooltips.hpp" #include "class.hpp" -#include "inventorywindow.hpp" namespace { @@ -333,7 +332,10 @@ namespace MWGui return; } - if (boost::lexical_cast(mPriceLabel->getCaption()) > MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + + if (boost::lexical_cast(mPriceLabel->getCaption()) > playerGold) { MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage18}"); return; @@ -341,9 +343,7 @@ namespace MWGui mSpell.mName = mNameEdit->getCaption(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - - player.getClass().getContainerStore(player).remove("gold_001", boost::lexical_cast(mPriceLabel->getCaption()), player); + player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, boost::lexical_cast(mPriceLabel->getCaption()), player); MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); diff --git a/apps/openmw/mwgui/tradeitemmodel.cpp b/apps/openmw/mwgui/tradeitemmodel.cpp index 5c12843da..28216ad14 100644 --- a/apps/openmw/mwgui/tradeitemmodel.cpp +++ b/apps/openmw/mwgui/tradeitemmodel.cpp @@ -149,7 +149,7 @@ namespace MWGui if(!mMerchant.isEmpty()) { MWWorld::Ptr base = item.mBase; - if(Misc::StringUtils::ciEqual(base.getCellRef().mRefID, "gold_001")) + if(Misc::StringUtils::ciEqual(base.getCellRef().mRefID, MWWorld::ContainerStore::sGoldId)) continue; if(!MWWorld::Class::get(base).canSell(base, services)) continue; diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 0111623be..1cd4c1c7c 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -210,11 +210,11 @@ namespace MWGui if (amount > 0) { - store.add("gold_001", amount, actor); + store.add(MWWorld::ContainerStore::sGoldId, amount, actor); } else { - store.remove("gold_001", - amount, actor); + store.remove(MWWorld::ContainerStore::sGoldId, - amount, actor); } } @@ -251,8 +251,11 @@ namespace MWGui return; } + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + // check if the player can afford this - if (mCurrentBalance < 0 && MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold() < std::abs(mCurrentBalance)) + if (mCurrentBalance < 0 && playerGold < std::abs(mCurrentBalance)) { // user notification MWBase::Environment::get().getWindowManager()-> @@ -269,8 +272,6 @@ namespace MWGui return; } - MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); - if(mCurrentBalance > mCurrentMerchantOffer) { //if npc is a creature: reject (no haggle) @@ -292,8 +293,8 @@ namespace MWGui float clampedDisposition = std::max(0,std::min(int(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr) + MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100)); - const MWMechanics::NpcStats &sellerStats = MWWorld::Class::get(mPtr).getNpcStats(mPtr); - const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); + 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 b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); @@ -322,7 +323,7 @@ namespace MWGui } //skill use! - MWWorld::Class::get(playerPtr).skillUsageSucceeded(playerPtr, ESM::Skill::Mercantile, 0); + player.getClass().skillUsageSucceeded(player, ESM::Skill::Mercantile, 0); } int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt(); @@ -335,7 +336,7 @@ namespace MWGui // transfer the gold if (mCurrentBalance != 0) { - addOrRemoveGold(mCurrentBalance, playerPtr); + addOrRemoveGold(mCurrentBalance, player); addOrRemoveGold(-mCurrentBalance, mPtr); } @@ -396,7 +397,10 @@ namespace MWGui void TradeWindow::updateLabels() { - mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold())); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + + mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast(playerGold)); if (mCurrentBalance > 0) { @@ -445,7 +449,7 @@ namespace MWGui MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr); for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { - if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001")) + if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, MWWorld::ContainerStore::sGoldId)) merchantGold += it->getRefData().getCount(); } return merchantGold; diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 7c11bd539..1a8999e6e 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -28,8 +28,6 @@ namespace MWGui void startTrade(const MWWorld::Ptr& actor); - void addOrRemoveGold(int gold, const MWWorld::Ptr& actor); - void onFrame(float frameDuration); void borrowItem (int index, size_t count); @@ -95,6 +93,8 @@ namespace MWGui void onIncreaseButtonTriggered(); void onDecreaseButtonTriggered(); + void addOrRemoveGold(int gold, const MWWorld::Ptr& actor); + void updateLabels(); virtual void onReferenceUnavailable(); diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index fc96d31bb..e196e93f2 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -14,7 +14,6 @@ #include "../mwmechanics/npcstats.hpp" -#include "inventorywindow.hpp" #include "tooltips.hpp" namespace MWGui @@ -40,7 +39,10 @@ namespace MWGui { mPtr = actor; - mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold())); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + + mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(playerGold)); MWMechanics::NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats (actor); @@ -71,7 +73,6 @@ namespace MWGui MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator (); MyGUI::Gui::getInstance ().destroyWidgets (widgets); - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); const MWWorld::Store &gmst = @@ -82,7 +83,7 @@ namespace MWGui int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer (mPtr,pcStats.getSkill (bestSkills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true); - std::string skin = (price > MWBase::Environment::get().getWindowManager()->getInventoryWindow ()->getPlayerGold ()) ? "SandTextGreyedOut" : "SandTextButton"; + std::string skin = (price > playerGold) ? "SandTextGreyedOut" : "SandTextButton"; MyGUI::Button* button = mTrainingOptions->createWidget(skin, MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default); @@ -115,6 +116,7 @@ namespace MWGui int skillId = *sender->getUserData(); MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); const MWWorld::ESMStore &store = @@ -123,7 +125,7 @@ namespace MWGui int price = pcStats.getSkill (skillId).getBase() * store.get().find("iTrainingMod")->getInt (); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); - if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()removeGuiMode (GM_Training); diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 7f223c505..2f844c3fd 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -2,6 +2,8 @@ #include +#include + #include #include "../mwbase/environment.hpp" @@ -12,8 +14,6 @@ #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" -#include "inventorywindow.hpp" - namespace MWGui { const int TravelWindow::sLineHeight = 18; @@ -50,13 +50,15 @@ namespace MWGui const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + if(interior) { price = gmst.find("fMagesGuildTravel")->getFloat(); } else { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); ESM::Position PlayerPos = player.getRefData().getPosition(); float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); price = d/gmst.find("fTravelMult")->getFloat(); @@ -64,7 +66,7 @@ namespace MWGui price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); - MyGUI::Button* toAdd = mDestinationsView->createWidget((price>MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); + MyGUI::Button* toAdd = mDestinationsView->createWidget((price>playerGold) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); mCurrentY += sLineHeight; if(interior) toAdd->setUserString("interior","y"); @@ -121,12 +123,13 @@ namespace MWGui iss >> price; MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); - if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()getFader ()->fadeOut(1); ESM::Position pos = *_sender->getUserData(); @@ -165,7 +168,10 @@ namespace MWGui void TravelWindow::updateLabels() { - mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold())); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + + mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(playerGold)); mPlayerGold->setCoord(8, mPlayerGold->getTop(), mPlayerGold->getTextSize().width, diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index f428bd4b0..9ccc69f90 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -299,6 +299,6 @@ namespace MWMechanics const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); - store.remove("gold_001", getEnchantPrice(), player); + store.remove(MWWorld::ContainerStore::sGoldId, getEnchantPrice(), player); } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 429683b97..2a613b7ff 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -802,6 +802,7 @@ namespace MWMechanics && (type != OT_Assault || it->first != victim) ) { + // TODO: stats.setAlarmed(true) on NPCs within earshot reported=true; break; } diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 1583f26e1..70a6fe856 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -63,6 +63,8 @@ namespace } } +const std::string MWWorld::ContainerStore::sGoldId = "gold_001"; + MWWorld::ContainerStore::ContainerStore() : mCachedWeight (0), mWeightUpToDate (false) {} MWWorld::ContainerStore::~ContainerStore() {} @@ -196,7 +198,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter) { - if (Misc::StringUtils::ciEqual((*iter).get()->mRef.mRefID, "gold_001")) + if (Misc::StringUtils::ciEqual((*iter).get()->mRef.mRefID, MWWorld::ContainerStore::sGoldId)) { iter->getRefData().setCount(iter->getRefData().getCount() + realCount); flagAsModified(); @@ -204,7 +206,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, } } - MWWorld::ManualRef ref(esmStore, "Gold_001", count); + MWWorld::ManualRef ref(esmStore, MWWorld::ContainerStore::sGoldId, count); return addNewStack(ref.getPtr(), count); } diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 9a97f9c1c..936468f8d 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -35,6 +35,8 @@ namespace MWWorld static const int Type_All = 0xffff; + static const std::string sGoldId; + private: MWWorld::CellRefList potions; From d7f69205f652bad7a2f043ca357fbf61cd6d9022 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 8 Jan 2014 23:56:40 +0100 Subject: [PATCH 107/223] Don't play "Menu Click" sound for disabled (= cannot receive input) buttons, plus some redundancy fixes --- apps/openmw/mwgui/merchantrepair.cpp | 3 +-- apps/openmw/mwgui/spellbuyingwindow.cpp | 21 ++++++++------------- apps/openmw/mwgui/trainingwindow.cpp | 9 ++------- apps/openmw/mwgui/travelwindow.cpp | 3 ++- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- files/mygui/openmw_text.skin.xml | 8 -------- 6 files changed, 14 insertions(+), 32 deletions(-) diff --git a/apps/openmw/mwgui/merchantrepair.cpp b/apps/openmw/mwgui/merchantrepair.cpp index 8b811ff50..3c3335d8b 100644 --- a/apps/openmw/mwgui/merchantrepair.cpp +++ b/apps/openmw/mwgui/merchantrepair.cpp @@ -68,8 +68,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor) MyGUI::Button* button = - mList->createWidget( - (price>playerGold) ? "SandTextGreyedOut" : "SandTextButton", + mList->createWidget("SandTextButton", 0, currentY, 0, diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index 4be7919a9..68aecf28d 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -45,13 +45,14 @@ namespace MWGui MyGUI::Button* toAdd = mSpellsView->createWidget( - (price>playerGold) ? "SandTextGreyedOut" : "SandTextButton", + "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default ); + toAdd->setEnabled(price<=playerGold); mCurrentY += sLineHeight; @@ -118,19 +119,13 @@ namespace MWGui int price = *_sender->getUserData(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); + MWMechanics::Spells& spells = stats.getSpells(); + spells.add (mSpellsWidgetMap.find(_sender)->second); + player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); + startSpellBuying(mPtr); - if (playerGold>=price) - { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); - MWMechanics::Spells& spells = stats.getSpells(); - spells.add (mSpellsWidgetMap.find(_sender)->second); - player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); - startSpellBuying(mPtr); - - MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); - } + MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); } void SpellBuyingWindow::onCancelButtonClicked(MyGUI::Widget* _sender) diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index e196e93f2..709bc0fb9 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -83,11 +83,10 @@ namespace MWGui int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer (mPtr,pcStats.getSkill (bestSkills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true); - std::string skin = (price > playerGold) ? "SandTextGreyedOut" : "SandTextButton"; - - MyGUI::Button* button = mTrainingOptions->createWidget(skin, + MyGUI::Button* button = mTrainingOptions->createWidget("SandTextButton", MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default); + button->setEnabled(price <= playerGold); button->setUserData(bestSkills[i].first); button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected); @@ -116,7 +115,6 @@ namespace MWGui int skillId = *sender->getUserData(); MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); const MWWorld::ESMStore &store = @@ -125,9 +123,6 @@ namespace MWGui int price = pcStats.getSkill (skillId).getBase() * store.get().find("iTrainingMod")->getInt (); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); - if (playerGoldgetBarterOffer(mPtr,price,true); - MyGUI::Button* toAdd = mDestinationsView->createWidget((price>playerGold) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); + MyGUI::Button* toAdd = mDestinationsView->createWidget("SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); + toAdd->setEnabled(price<=playerGold); mCurrentY += sLineHeight; if(interior) toAdd->setUserString("interior","y"); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 77b72fc0a..c2efa0c33 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -555,7 +555,7 @@ namespace MWInput if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) { MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); - if (b) + if (b && b->getEnabled()) { MWBase::Environment::get().getSoundManager ()->playSound ("Menu Click", 1.f, 1.f); } diff --git a/files/mygui/openmw_text.skin.xml b/files/mygui/openmw_text.skin.xml index 6a1dea60b..15287bc74 100644 --- a/files/mygui/openmw_text.skin.xml +++ b/files/mygui/openmw_text.skin.xml @@ -17,14 +17,6 @@ - - - - - - - - From 9bf7bf529c948b02a63596a17e9ca30dbeff2af3 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 00:40:25 +0100 Subject: [PATCH 108/223] Implement crime-related dialogue globals as they are described in MSFD --- apps/openmw/mwbase/world.hpp | 4 ++++ apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 6 ++++++ apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 1 + apps/openmw/mwworld/worldimp.cpp | 21 +++++++++++++++++++ apps/openmw/mwworld/worldimp.hpp | 4 ++++ 5 files changed, 36 insertions(+) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 611bd913b..b719ce4d6 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -448,6 +448,10 @@ namespace MWBase /// @note This also works for references in containers. virtual void listDetectedReferences (const MWWorld::Ptr& ptr, std::vector& out, DetectionType type) = 0; + + /// 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; }; } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 2fce7e327..b2107c329 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -143,6 +143,7 @@ namespace MWDialogue //setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI updateTopics(); + updateGlobals(); //greeting const MWWorld::Store &dialogs = @@ -298,6 +299,11 @@ namespace MWDialogue } } + void DialogueManager::updateGlobals() + { + MWBase::Environment::get().getWorld()->updateDialogueGlobals(); + } + void DialogueManager::updateTopics() { std::list keywordList; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index 5baf20a0e..c32a5dbd8 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -40,6 +40,7 @@ namespace MWDialogue void parseText (const std::string& text); void updateTopics(); + void updateGlobals(); bool compile (const std::string& cmd,std::vector& code); void executeScript (const std::string& script); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 8bb2e7956..46511f5bc 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2420,4 +2420,25 @@ namespace MWWorld { return mPlayer->getPlayer(); } + + void World::updateDialogueGlobals() + { + MWWorld::Ptr player = getPlayerPtr(); + int bounty = player.getClass().getNpcStats(player).getBounty(); + int playerGold = player.getClass().getContainerStore(player).count(ContainerStore::sGoldId); + + float fCrimeGoldDiscountMult = getStore().get().find("fCrimeGoldDiscountMult")->getFloat(); + float fCrimeGoldTurnInMult = getStore().get().find("fCrimeGoldTurnInMult")->getFloat(); + + int discount = bounty*fCrimeGoldDiscountMult; + int turnIn = bounty * fCrimeGoldTurnInMult; + + mGlobalVariables->setInt("pchascrimegold", (bounty <= playerGold) ? 1 : 0); + + mGlobalVariables->setInt("pchasgolddiscount", (discount <= playerGold) ? 1 : 0); + mGlobalVariables->setInt("crimegolddiscount", discount); + + mGlobalVariables->setInt("crimegoldturnin", turnIn); + mGlobalVariables->setInt("pchasturnin", (turnIn <= playerGold) ? 1 : 0); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 51ad3a045..ba7dc66b6 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -533,6 +533,10 @@ namespace MWWorld /// @note This also works for references in containers. virtual void listDetectedReferences (const MWWorld::Ptr& ptr, std::vector& out, DetectionType type); + + /// 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(); }; } From 925d28e4a7b812ffc2cafe020b61fe93230ffd98 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Thu, 9 Jan 2014 00:46:25 +0100 Subject: [PATCH 109/223] crashcatcher uname error checking --- apps/openmw/crashcatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/crashcatcher.cpp b/apps/openmw/crashcatcher.cpp index d7ebc0d47..65a036919 100644 --- a/apps/openmw/crashcatcher.cpp +++ b/apps/openmw/crashcatcher.cpp @@ -177,7 +177,7 @@ static void sys_info(void) { #ifdef __unix__ struct utsname info; - if(!uname(&info)) + if(uname(&info)) printf("!!! Failed to get system information\n"); else printf("System: %s %s %s %s %s\n", From baf55df7a11a7e199121f0a653eca4414bcd4c0e Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 01:34:10 +0100 Subject: [PATCH 110/223] Gold fixes (when did this break?) --- apps/openmw/mwclass/misc.cpp | 4 +++- apps/openmw/mwgui/inventorywindow.cpp | 2 -- apps/openmw/mwworld/containerstore.cpp | 10 ++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index e5120462e..a8a6c55ec 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -93,7 +93,9 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - int value = (ptr.getCellRef().mGoldValue == 1) ? ref->mBase->mData.mValue : ptr.getCellRef().mGoldValue; + int value = ref->mBase->mData.mValue; + if (ptr.getCellRef().mGoldValue > 1 && ptr.getRefData().getCount() == 1) + value = ptr.getCellRef().mGoldValue; if (ptr.getCellRef().mSoul != "") { diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 0ad156cdf..7781c8526 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -499,8 +499,6 @@ namespace MWGui return; int count = object.getRefData().getCount(); - if (object.getCellRef().mGoldValue > 1) - count = object.getCellRef().mGoldValue; // add to player inventory // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 70a6fe856..744971985 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -134,7 +134,11 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2) MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const std::string &id, int count, const Ptr &actorPtr) { MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), id, count); - return add(ref.getPtr(), count, actorPtr, true); + // a bit pointless to set owner for the player + if (actorPtr.getRefData().getHandle() != "player") + return add(ref.getPtr(), count, actorPtr, true); + else + return add(ref.getPtr(), count, actorPtr, false); } MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool setOwner) @@ -194,7 +198,9 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, || Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025") || Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100")) { - int realCount = MWWorld::Class::get(ptr).getValue(ptr) * ptr.getRefData().getCount(); + int realCount = ptr.getRefData().getCount(); + if (ptr.getCellRef().mGoldValue > 1 && realCount == 1) + realCount = ptr.getCellRef().mGoldValue; for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter) { From 6f9113fe882c183d572bcffe846af1a63becd071 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 01:49:58 +0100 Subject: [PATCH 111/223] Add preliminary implementation of PayFine, PayFineThief and GoToJail instructions --- apps/openmw/mwbase/world.hpp | 5 ++- apps/openmw/mwgui/messagebox.cpp | 1 + apps/openmw/mwmechanics/spellcasting.cpp | 8 ++--- apps/openmw/mwrender/camera.cpp | 1 + apps/openmw/mwscript/docs/vmformat.txt | 5 ++- apps/openmw/mwscript/miscextensions.cpp | 40 ++++++++++++++++++++++++ apps/openmw/mwworld/worldimp.cpp | 8 ++++- apps/openmw/mwworld/worldimp.hpp | 5 ++- components/compiler/extensions0.cpp | 3 ++ components/compiler/opcodes.hpp | 3 ++ 10 files changed, 65 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index b719ce4d6..43e526ecb 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -431,11 +431,10 @@ namespace MWBase virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result) = 0; - /// Teleports \a ptr to the reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker) - /// closest to \a worldPos. + /// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker) /// @note id must be lower case virtual void teleportToClosestMarker (const MWWorld::Ptr& ptr, - const std::string& id, Ogre::Vector3 worldPos) = 0; + const std::string& id) = 0; enum DetectionType { diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 378e76e46..8e518668b 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -10,6 +10,7 @@ namespace MWGui MessageBoxManager::MessageBoxManager () { + // TODO: fMessageTimePerChar mMessageBoxSpeed = 0.1; mInterMessageBoxe = NULL; mStaticMessageBox = NULL; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 21b6d0d77..a1cdb8b61 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -287,17 +287,13 @@ namespace MWMechanics if (!MWBase::Environment::get().getWorld()->isTeleportingEnabled()) return; - Ogre::Vector3 worldPos; - if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(target.getCell(), worldPos)) - worldPos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition(); - if (effectId == ESM::MagicEffect::DivineIntervention) { - MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "divinemarker", worldPos); + MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "divinemarker"); } else if (effectId == ESM::MagicEffect::AlmsiviIntervention) { - MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "templemarker", worldPos); + MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "templemarker"); } else if (effectId == ESM::MagicEffect::Mark) diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 9a35725ee..dda9797ef 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -228,6 +228,7 @@ namespace MWRender void Camera::setSneakOffset() { + // TODO: iFirstPersonSneakDelta if(mAnimation) mAnimation->addFirstPersonOffset(Ogre::Vector3(0.f, 0.f, -9.8f)); } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index a6349c4da..64a9d427a 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -372,5 +372,8 @@ op 0x2000231: GetSpellReadied op 0x2000232: GetSpellReadied, explicit op 0x2000233: GetPcJumping op 0x2000234: ShowRestMenu, explicit -opcodes 0x2000235-0x3ffffff unused +op 0x2000235: GoToJail +op 0x2000236: PayFine +op 0x2000237: PayFineThief +opcodes 0x2000238-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 61d286ae3..03dc5c14c 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -762,6 +762,43 @@ namespace MWScript } }; + class OpGoToJail : public Interpreter::Opcode0 + { + public: + 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); + // TODO: pass time, change skills, show messagebox + // TODO: move stolen items to closest evidence chest + // iDaysinPrisonMod + } + }; + + class OpPayFine : public Interpreter::Opcode0 + { + public: + virtual void execute(Interpreter::Runtime &runtime) + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + player.getClass().getNpcStats(player).setBounty(0); + + // TODO: move stolen items to closest evidence chest + } + }; + + class OpPayFineThief : public Interpreter::Opcode0 + { + public: + virtual void execute(Interpreter::Runtime &runtime) + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + player.getClass().getNpcStats(player).setBounty(0); + } + }; + void installOpcodes (Interpreter::Interpreter& interpreter) { interpreter.installSegment5 (Compiler::Misc::opcodeXBox, new OpXBox); @@ -785,6 +822,9 @@ namespace MWScript interpreter.installSegment5 (Compiler::Misc::opcodeGetPcJumping, new OpGetPcJumping); interpreter.installSegment5 (Compiler::Misc::opcodeWakeUpPc, new OpWakeUpPc); interpreter.installSegment5 (Compiler::Misc::opcodePlayBink, new OpPlayBink); + interpreter.installSegment5 (Compiler::Misc::opcodePayFine, new OpPayFine); + interpreter.installSegment5 (Compiler::Misc::opcodePayFineThief, new OpPayFineThief); + interpreter.installSegment5 (Compiler::Misc::opcodeGoToJail, new OpGoToJail); interpreter.installSegment5 (Compiler::Misc::opcodeGetLocked, new OpGetLocked); interpreter.installSegment5 (Compiler::Misc::opcodeGetLockedExplicit, new OpGetLocked); interpreter.installSegment5 (Compiler::Misc::opcodeGetEffect, new OpGetEffect); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 46511f5bc..f61938f92 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2273,6 +2273,8 @@ namespace MWWorld bool World::findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result) { + if (cell->isExterior()) + return false; MWWorld::CellRefList& doors = cell->mDoors; CellRefList::List& refList = doors.mList; @@ -2293,8 +2295,12 @@ namespace MWWorld } void World::teleportToClosestMarker (const MWWorld::Ptr& ptr, - const std::string& id, Ogre::Vector3 worldPos) + const std::string& id) { + Ogre::Vector3 worldPos; + if (!findInteriorPositionInWorldSpace(ptr.getCell(), worldPos)) + worldPos = mPlayer->getLastKnownExteriorPosition(); + MWWorld::Ptr closestMarker; float closestDistance = FLT_MAX; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index ba7dc66b6..cc087a89f 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -522,11 +522,10 @@ namespace MWWorld virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result); - /// Teleports \a ptr to the reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker) - /// closest to \a worldPos. + /// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker) /// @note id must be lower case virtual void teleportToClosestMarker (const MWWorld::Ptr& ptr, - const std::string& id, Ogre::Vector3 worldPos); + const std::string& id); /// List all references (filtered by \a type) detected by \a ptr. The range /// is determined by the current magnitude of the "Detect X" magic effect belonging to \a type. diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index e35a32ffa..03510d833 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -244,6 +244,9 @@ namespace Compiler extensions.registerFunction ("getpcjumping", 'l', "", opcodeGetPcJumping); extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc); extensions.registerInstruction ("playbink", "Sl", opcodePlayBink); + extensions.registerInstruction ("payfine", "", opcodePayFine); + extensions.registerInstruction ("payfinethief", "", opcodePayFineThief); + extensions.registerInstruction ("gotojail", "", opcodeGoToJail); extensions.registerFunction ("getlocked", 'l', "", opcodeGetLocked, opcodeGetLockedExplicit); extensions.registerFunction ("geteffect", 'l', "S", opcodeGetEffect, opcodeGetEffectExplicit); extensions.registerInstruction ("addsoulgem", "cc", opcodeAddSoulGem, opcodeAddSoulGemExplicit); diff --git a/components/compiler/opcodes.hpp b/components/compiler/opcodes.hpp index eb2240964..3a4c8135d 100644 --- a/components/compiler/opcodes.hpp +++ b/components/compiler/opcodes.hpp @@ -223,6 +223,9 @@ namespace Compiler const int opcodeGetStandingActorExplicit = 0x200020f; const int opcodeGetWindSpeed = 0x2000212; const int opcodePlayBink = 0x20001f7; + const int opcodeGoToJail = 0x2000235; + const int opcodePayFine = 0x2000236; + const int opcodePayFineThief = 0x2000237; const int opcodeHitOnMe = 0x2000213; const int opcodeHitOnMeExplicit = 0x2000214; const int opcodeDisableTeleporting = 0x2000215; From 223c1d5a389c03f4f483d6d6ed90798cc37d2041 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 01:55:49 +0100 Subject: [PATCH 112/223] Use GMSTs for crime bounty --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 2a613b7ff..511fe6544 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -803,6 +803,7 @@ namespace MWMechanics ) { // TODO: stats.setAlarmed(true) on NPCs within earshot + // fAlarmRadius ? reported=true; break; } @@ -816,15 +817,18 @@ namespace MWMechanics void MechanicsManager::reportCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) { + const MWWorld::Store& store = MWBase::Environment::get().getWorld()->getStore().get(); // Bounty for each type of crime if (type == OT_Trespassing || type == OT_SleepingInOwnedBed) - arg = 5; + arg = store.find("iCrimeTresspass")->getInt(); else if (type == OT_Pickpocket) - arg = 25; + arg = store.find("iCrimePickPocket")->getInt(); else if (type == OT_Assault) - arg = 40; + arg = store.find("iCrimeAttack")->getInt(); else if (type == OT_Murder) - arg = 1000; + arg = store.find("iCrimeKilling")->getInt(); + else if (type == OT_Theft) + arg *= store.find("fCrimeStealing")->getFloat(); MWBase::Environment::get().getWindowManager()->messageBox("#{sCrimeMessage}"); ptr.getClass().getNpcStats(ptr).setBounty(ptr.getClass().getNpcStats(ptr).getBounty() From 768d9f72378da0863a252614081cf9326c8fd6e7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 02:14:08 +0100 Subject: [PATCH 113/223] Scripting: Add an optional 'required' parameter to getReference (default: true). If required=false, it will not throw an exception if there's no reference. Fixes PcExpell not working without a reference like it's supposed to, and makes the code nicer for some others (use required=false instead of catching the exception) --- apps/openmw/mwscript/guiextensions.cpp | 9 +-------- apps/openmw/mwscript/interpretercontext.cpp | 12 ++++++------ apps/openmw/mwscript/interpretercontext.hpp | 6 +++--- apps/openmw/mwscript/miscextensions.cpp | 10 ++++------ apps/openmw/mwscript/ref.hpp | 6 +++--- apps/openmw/mwscript/statsextensions.cpp | 6 ++---- 6 files changed, 19 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index e51bdcf69..b5e2bd293 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -54,14 +54,7 @@ namespace MWScript public: virtual void execute (Interpreter::Runtime& runtime) { - // FIXME: No way to tell if we have a reference before trying to get it, and it will - // cause an exception is there isn't one :( - MWWorld::Ptr bed; - try { - bed = R()(runtime); - } - catch(std::runtime_error&) { - } + MWWorld::Ptr bed = R()(runtime, false); if (bed.isEmpty() || !MWBase::Environment::get().getMechanicsManager()->sleepInBed(MWBase::Environment::get().getWorld()->getPlayerPtr(), bed)) diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index aa9e32008..18baf0bda 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -23,7 +23,7 @@ namespace MWScript { MWWorld::Ptr InterpreterContext::getReference ( - const std::string& id, bool activeOnly) + const std::string& id, bool activeOnly, bool doThrow) { if (!id.empty()) { @@ -31,7 +31,7 @@ namespace MWScript } else { - if (mReference.isEmpty()) + if (mReference.isEmpty() && doThrow) throw std::runtime_error ("no implicit reference"); return mReference; @@ -39,7 +39,7 @@ namespace MWScript } const MWWorld::Ptr InterpreterContext::getReference ( - const std::string& id, bool activeOnly) const + const std::string& id, bool activeOnly, bool doThrow) const { if (!id.empty()) { @@ -47,7 +47,7 @@ namespace MWScript } else { - if (mReference.isEmpty()) + if (mReference.isEmpty() && doThrow) throw std::runtime_error ("no implicit reference"); return mReference; @@ -498,8 +498,8 @@ namespace MWScript ptr.getRefData().getLocals().mFloats[index] = value; } - MWWorld::Ptr InterpreterContext::getReference() + MWWorld::Ptr InterpreterContext::getReference(bool required) { - return getReference ("", true); + return getReference ("", true, required); } } diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index 9c7b443ae..04546faed 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -33,9 +33,9 @@ namespace MWScript bool mActivationHandled; boost::shared_ptr mAction; - MWWorld::Ptr getReference (const std::string& id, bool activeOnly); + MWWorld::Ptr getReference (const std::string& id, bool activeOnly, bool doThrow=true); - const MWWorld::Ptr getReference (const std::string& id, bool activeOnly) const; + const MWWorld::Ptr getReference (const std::string& id, bool activeOnly, bool doThrow=true) const; public: @@ -150,7 +150,7 @@ namespace MWScript virtual void setMemberFloat (const std::string& id, const std::string& name, float value); - MWWorld::Ptr getReference(); + MWWorld::Ptr getReference(bool required=true); ///< Reference, that the script is running from (can be empty) }; } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 03dc5c14c..a403d76ed 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -699,13 +699,11 @@ namespace MWScript public: virtual void execute(Interpreter::Runtime& runtime) { - // No way to tell if we have a reference before trying to get it, and it will - // cause an exception is there isn't one :( - try { - MWWorld::Ptr ptr = R()(runtime); + MWWorld::Ptr ptr = R()(runtime, false); + if (!ptr.isEmpty()) printLocalVars(runtime, ptr); - } - catch(std::runtime_error&) { + else + { // No reference, no problem. printGlobalVars(runtime); } diff --git a/apps/openmw/mwscript/ref.hpp b/apps/openmw/mwscript/ref.hpp index 81b1d5ef9..795839139 100644 --- a/apps/openmw/mwscript/ref.hpp +++ b/apps/openmw/mwscript/ref.hpp @@ -16,7 +16,7 @@ namespace MWScript { struct ExplicitRef { - MWWorld::Ptr operator() (Interpreter::Runtime& runtime) const + MWWorld::Ptr operator() (Interpreter::Runtime& runtime, bool required=true) const { std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -27,12 +27,12 @@ namespace MWScript struct ImplicitRef { - MWWorld::Ptr operator() (Interpreter::Runtime& runtime) const + MWWorld::Ptr operator() (Interpreter::Runtime& runtime, bool required=true) const { MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - return context.getReference(); + return context.getReference(required); } }; } diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 56b309576..d6c2cb894 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -921,8 +921,6 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { - MWWorld::Ptr ptr = R()(runtime); - std::string factionID = ""; if(arg0 >0 ) { @@ -931,6 +929,7 @@ namespace MWScript } else { + MWWorld::Ptr ptr = R()(runtime); if(MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().empty()) { factionID = ""; @@ -955,8 +954,6 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { - MWWorld::Ptr ptr = R()(runtime); - std::string factionID = ""; if(arg0 >0 ) { @@ -965,6 +962,7 @@ namespace MWScript } else { + MWWorld::Ptr ptr = R()(runtime); if(MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().empty()) { factionID = ""; From aa855e9524115d27c0dda59c69a7d0166f95e396 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 20:56:24 +0100 Subject: [PATCH 114/223] 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 c8b37e9bb..620586bd2 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 f7333db35..2dbc72e26 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 a69511acd..246103471 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 21bbe51b6..9ebb0ab08 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 0a4db30e9..9e3105168 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 0c1fdfbee..5a76b702e 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 9e5ec5414..c86697497 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 115/223] 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 8e518668b..72a5bd0b0 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 d41f27451b9bab6172c7a86ee5d9be025336a58d Mon Sep 17 00:00:00 2001 From: mrcheko Date: Thu, 9 Jan 2014 23:36:40 +0200 Subject: [PATCH 116/223] appropriate camera vanity<>preview mode switch + hit recoils fix --- apps/openmw/mwmechanics/character.cpp | 6 ++++++ apps/openmw/mwrender/animation.cpp | 11 ++++++----- apps/openmw/mwrender/animation.hpp | 2 +- apps/openmw/mwrender/camera.cpp | 10 +++++----- apps/openmw/mwrender/npcanimation.cpp | 3 +++ 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index a4b4f2471..75fdc2550 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -179,6 +179,12 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat mHitState = CharState_Hit; int iHit = rand() % (sHitListSize-1); mCurrentHit = sHitList[iHit]; + if(mPtr.getRefData().getHandle()=="player" && !mAnimation->hasAnimation(mCurrentHit)) + { + //only 4 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); } } diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 8ce751286..1d4868361 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -387,7 +387,6 @@ Ogre::Node *Animation::getNode(const std::string &name) return NULL; } - NifOgre::TextKeyMap::const_iterator Animation::findGroupStart(const NifOgre::TextKeyMap &keys, const std::string &groupname) { NifOgre::TextKeyMap::const_iterator iter(keys.begin()); @@ -1008,14 +1007,16 @@ void Animation::detachObjectFromBone(Ogre::MovableObject *obj) mSkelBase->detachObjectFromBone(obj); } -bool Animation::isPlaying(Group group) const +bool Animation::allowSwitchViewMode() const { for (AnimStateMap::const_iterator stateiter = mStates.begin(); stateiter != mStates.end(); ++stateiter) { - if(stateiter->second.mGroups == group) - return true; + if(stateiter->second.mGroups == Group_UpperBody + || (stateiter->first.size()==4 && stateiter->first.find("hit") != std::string::npos) + || (stateiter->first.find("knock") != std::string::npos) ) + return false; } - return false; + return true; } void Animation::addEffect(const std::string &model, int effectId, bool loop, const std::string &bonename, std::string texture) diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index f5f79dd72..a682f3960 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -258,7 +258,7 @@ public: /** Returns true if the named animation group is playing. */ bool isPlaying(const std::string &groupname) const; - bool isPlaying(Group group) const; + bool allowSwitchViewMode() const; /** Gets info about the given animation group. * \param groupname Animation group to check. diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 9a35725ee..9babb0b08 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -107,7 +107,7 @@ namespace MWRender void Camera::update(float duration, bool paused) { - if (!mAnimation->isPlaying(MWRender::Animation::Group_UpperBody)) + if (mAnimation->allowSwitchViewMode()) { // Now process the view changes we queued earlier if (mVanityToggleQueued) @@ -144,7 +144,7 @@ namespace MWRender { // Changing the view will stop all playing animations, so if we are playing // anything important, queue the view change for later - if (mAnimation->isPlaying(MWRender::Animation::Group_UpperBody)) + if (!mAnimation->allowSwitchViewMode()) { mViewModeToggleQueued = true; return; @@ -171,7 +171,7 @@ namespace MWRender { // Changing the view will stop all playing animations, so if we are playing // anything important, queue the view change for later - if (mAnimation->isPlaying(MWRender::Animation::Group_UpperBody)) + if (!mPreviewMode) { mVanityToggleQueued = true; return false; @@ -205,7 +205,7 @@ namespace MWRender void Camera::togglePreviewMode(bool enable) { - if (mAnimation->isPlaying(MWRender::Animation::Group_UpperBody)) + if (mFirstPersonView && !mAnimation->allowSwitchViewMode()) return; if(mPreviewMode == enable) @@ -358,7 +358,7 @@ namespace MWRender Ogre::TagPoint *tag = mAnimation->attachObjectToBone("Head", mCamera); tag->setInheritOrientation(false); } - else + else { mAnimation->setViewMode(NpcAnimation::VM_Normal); mCameraNode->attachObject(mCamera); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index b1455f0dc..edb6688ff 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -140,6 +140,9 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) { assert(viewMode != VM_HeadOnly); + if(mViewMode == viewMode) + return; + mViewMode = viewMode; rebuild(); } From bfdca3b73816831d45e86c2e806462c04fab5be2 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Jan 2014 23:13:31 +0100 Subject: [PATCH 117/223] 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 be6ccbed6..e2cc3712b 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 118/223] 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 6132b3407..940a251e3 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 119/223] 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 940a251e3..44bb7d302 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 bc31ad537..56a85c8fd 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 120/223] 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 56a85c8fd..dbfcd7574 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 121/223] 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 dbfcd7574..338983cc7 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 122/223] 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 44bb7d302..fccc5218b 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 123/223] 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 fccc5218b..36878d44b 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 ffcb7fb280f737e1f678dbb8401b9316d643881b Mon Sep 17 00:00:00 2001 From: mrcheko Date: Fri, 10 Jan 2014 19:04:07 +0200 Subject: [PATCH 124/223] fix for bug scrawl mentioned --- apps/openmw/mwmechanics/character.cpp | 4 ++-- apps/openmw/mwrender/animation.hpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 75fdc2550..019054af2 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -181,7 +181,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat mCurrentHit = sHitList[iHit]; if(mPtr.getRefData().getHandle()=="player" && !mAnimation->hasAnimation(mCurrentHit)) { - //only 4 different hit animations if player is in 1st person + //only 3 different hit animations if player is in 1st person int iHit = rand() % (sHitListSize-3); mCurrentHit = sHitList[iHit]; } @@ -489,7 +489,7 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun const bool isWerewolf = stats.isWerewolf(); bool forcestateupdate = false; - if(weaptype != mWeaponType) + if(weaptype != mWeaponType && mHitState != CharState_KnockDown) { forcestateupdate = true; diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index a682f3960..4ba68dd85 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -258,6 +258,7 @@ public: /** Returns true if the named animation group is playing. */ bool isPlaying(const std::string &groupname) const; + //Checks if playing any animation which shouldn't be stopped when switching camera view modes bool allowSwitchViewMode() const; /** Gets info about the given animation group. From 627dcddb333a2d8e881184bf1f6a1dd72d8d15b6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 10 Jan 2014 20:53:53 +0100 Subject: [PATCH 125/223] 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 709bc0fb9..24be5363d 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 126/223] 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 6c46f2176..7965669f1 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 127/223] 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 24e955cdf..85fcfc75b 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 511fe6544..002cd561d 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 cec08fa92..569cd2fca 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 0769e13df..2e5eaecfd 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 a1cdb8b61..8c4c4d292 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 a55c45fd1..438b65575 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 2aee74eee..b11c22c72 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 128/223] 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 4d79875a2..d9d2a2ea8 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 72a5bd0b0..b0abaef14 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 0288f366c..e82a51642 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 3accd925f..e4297f8fc 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 0a4adb6e2..afc94255b 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 1510372dd..b24a476c4 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 db3fa24a0..683d47fe7 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 129/223] 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 438b65575..a1ae254f6 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 dda9797ef..d579c9793 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 d31d9e56c..808f817cf 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 11d06704e..0c5e053c9 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 130/223] 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 01fe61472..1c5c302d8 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 131/223] 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 32b0063b6..34b721755 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 132/223] 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 f61938f92..738c71a7d 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 133/223] 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 6c85be5fd..c39de4400 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 bccc7120f..d22842b57 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 f934d8828..ce4707af6 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 b0abaef14..ae01f4293 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 e82a51642..caa37008c 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 e4297f8fc..cda146e8c 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 a3b135ad4..9838a667f 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 c2efa0c33..f0feba89f 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 4eaee9b69..d41b4c3f3 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 134/223] 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 5dcdb7fed..be468866b 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 9d6b44de8..398ebac01 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 68fae01af..18d05b100 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 86eef36ff..1436de0c3 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 135/223] 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 002cd561d..2ce196fdd 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 136/223] 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 2ce196fdd..57b876723 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 137/223] 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 b11c22c72..3e81da212 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 138/223] 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 1c5c302d8..68b7d41f5 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 57b876723..901b6e414 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 8c4c4d292..b8c36d213 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 139/223] 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 43e526ecb..10e25b376 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 a403d76ed..f69f2e7cb 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 621ff3b31..575e10f04 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 31de2f60e..afa7c03f2 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 738c71a7d..c5315afe6 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 cc087a89f..8c091de50 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 140/223] 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 10e25b376..2fb5f02eb 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 901b6e414..76ba2ff16 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 c5315afe6..ca85d7a7f 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 8c091de50..d5ccd7625 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 141/223] 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 68b7d41f5..12ed2dd09 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 142/223] 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 be468866b..8e78d2216 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 143/223] 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 afc94255b..468a21892 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 99067a6b7..fed3f485f 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 b8c36d213..850c4dcf5 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 144/223] 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 2fb5f02eb..fe40fab24 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 f69f2e7cb..bb3600a27 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 ca85d7a7f..620058c65 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 d5ccd7625..634cc8d6b 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 828e5841d86ce3b4afed7b2637913981ff662883 Mon Sep 17 00:00:00 2001 From: gus Date: Sat, 11 Jan 2014 11:00:34 +0100 Subject: [PATCH 145/223] Windows SDL fix --- apps/launcher/main.cpp | 1 + apps/openmw/engine.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 156bbf65b..fabf77d90 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -16,6 +16,7 @@ int main(int argc, char *argv[]) { SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); + SDL_SetMainReady(); if (SDL_Init(SDL_INIT_VIDEO) != 0) { qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError()); diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index b59b6a2fd..5d04b985f 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -157,6 +157,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) //kindly ask SDL not to trash our OGL context //might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ? SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); + SDL_SetMainReady(); if(SDL_Init(flags) != 0) { throw std::runtime_error("Could not initialize SDL! " + std::string(SDL_GetError())); From 0609b71df9daf2a1248889c15617d99b12c71bdd Mon Sep 17 00:00:00 2001 From: gus Date: Sat, 11 Jan 2014 11:57:07 +0100 Subject: [PATCH 146/223] fix pathfinding --- apps/openmw/mwmechanics/pathfinding.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 18e66d228..c8bc9b49c 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -150,6 +150,7 @@ namespace MWMechanics void PathFinder::buildPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint, const ESM::Pathgrid *pathGrid, float xCell, float yCell, bool allowShortcuts) { + mPath.clear(); if(allowShortcuts) { if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ, From 3db299f1b2c8074d9febbe257066f1c610bf617d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 11 Jan 2014 21:04:31 +0100 Subject: [PATCH 147/223] 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 12ed2dd09..41c6de40c 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 148/223] 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 1cd4c1c7c..14024dec6 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 149/223] 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 850c4dcf5..de078f9ef 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 150/223] 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 41c6de40c..dc219f373 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 b29ae2914..0856ada0c 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 de078f9ef..be67b6592 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 151/223] 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 dc219f373..86f0fbc3b 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 152/223] 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 0856ada0c..e5236f02b 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 153/223] 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 7b1fc7fb2..56c9a2fad 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 f994c28b8..af58e9ee0 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 77056b9ec..8281f4969 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 154/223] 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 86f0fbc3b..4aa27e38a 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 155/223] 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 e5236f02b..86785ec22 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 156/223] 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 2a7165974..994798b0b 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 2ddb4ec55..7a40afb4c 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 468a21892..6f710988e 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 be67b6592..a0e91791b 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 157/223] 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 7781c8526..7139c1b2c 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 112e737fa..7e5a0fe10 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 77127f59b..61e414fc4 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 6a0b4eec7..348b09ad9 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 158/223] 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 348b09ad9..d34773bd5 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 159/223] 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 4aa27e38a..e08a3c07e 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 c39ca42ef..22a9632e8 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 86785ec22..07859d57c 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 b5b9b7156..aadce499e 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 6e0804638..1f82a9b5c 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 160/223] 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 e08a3c07e..19561e53d 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 4f478afce..d7b7df983 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 0119cdea5..934dae015 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 08d769fbe..c0b010eae 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 161/223] 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 6f710988e..e2255f8cb 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 162/223] 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 19561e53d..a7ff92cf5 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 aadce499e..ba6f0ba04 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 163/223] 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 17bb24e83..37128c43f 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 289fcc70f..f77b04271 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 e66cf86de..75ac6939a 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 164/223] 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 d22842b57..858378c03 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 165/223] 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 36878d44b..d5064d272 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 166/223] 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 d5064d272..f89c641d4 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 167/223] 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 f89c641d4..3be594d3e 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 168/223] 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 85fcfc75b..d1472de38 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 24be5363d..bee76992a 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 dcf54d25a..c314ce1fd 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 e71ed4247..5058e53ee 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 e2255f8cb..0fc7210b2 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 7046543e6..382aa5400 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 76ba2ff16..456b3a8f9 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 569cd2fca..25e556e6a 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 169/223] 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 d1472de38..726c8cf04 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 5058e53ee..1ad703790 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 0fc7210b2..a0be8357d 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 382aa5400..b7544dad4 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 456b3a8f9..d6dd73bd0 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 25e556e6a..469123df9 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 170/223] 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 28a3aae37..a7ee96831 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 171/223] 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 4ee754b35..9dc0b8c5d 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 172/223] 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 620058c65..f9899c3a2 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 173/223] 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 3e81da212..e8938b2c0 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 174/223] 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 eb5b71ec3..4da5e2997 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 000000000..af5f71f51 --- /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 744971985..864bb2a0d 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 936468f8d..0a1728740 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 175/223] 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 5774c96ae..6f3b5bb5a 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 176/223] 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 202ec6464..7bac7cdbe 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 bb3600a27..637159475 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 177/223] 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 d6dd73bd0..1738f9fdd 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 178/223] 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 56c9a2fad..d270a9534 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 48d7b249b..007f93316 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 a5664c1c8..b68004f1f 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 fe40fab24..83fcba87c 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 1ad703790..f52771ffe 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 2723f7a80..d96649af6 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 a0be8357d..99381a204 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 07859d57c..9a3983b07 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 af5f71f51..d65503011 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 864bb2a0d..475eeb8f4 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 f9899c3a2..ebc1044bc 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 634cc8d6b..92975400a 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 9dcc6177a..a4e1b85c2 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 179/223] 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 3be594d3e..f89c641d4 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 180/223] 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 f89c641d4..5624480af 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 181/223] 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 d0dbeb1bd..52f935710 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 9c0d5b0fd..2f3911270 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 87bb925c2..50d09f313 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 d7b7df983..f132d13a3 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 8269e8364..481c98314 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 ae01f4293..644b8f66a 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 1738f9fdd..79a038dff 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 575e10f04..c8a070e21 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 0c145ab60..b492c6f32 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 475eeb8f4..154fa1999 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 512883f1a..ca37cc591 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 182/223] 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 916ba1b49..79a953e38 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 183/223] 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 5624480af..ed0fec1da 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 184/223] 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 ed0fec1da..62b2a5172 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 185/223] 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 62b2a5172..6615d0a57 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 186/223] 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 6615d0a57..dab61bfff 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 187/223] 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 5b9aafcb3..6b388dc72 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 188/223] 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 b68004f1f..184d11bb4 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 9a3983b07..07859d57c 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 189/223] 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 f52771ffe..0ead54d9d 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 190/223] 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 a7ff92cf5..7ba5f340c 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 191/223] 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 7ba5f340c..ef5665397 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 965606709..9c8e07f3e 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 7965669f1..1e1aebd95 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 2c73226e3..299b34b51 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 9ccc69f90..6c765aa41 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 b5e2bd293..ab8901881 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 d6c2cb894..095fad7ab 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 81aff9958..43a0fedce 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 c34beb3f2..b00ad15ca 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 8f07b9e50..eb741fb10 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 18f7377ff..7f9ebaae1 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 e2cc3712b..4dae1a93d 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 192/223] 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 1a5569983..000000000 --- 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 a7c50d100..000000000 --- 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 657913f30..000000000 --- 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 75e169d54..000000000 --- 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 72e51e331..000000000 --- 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 decd43df5..000000000 --- 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 df9139b95..000000000 --- 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 2eab2d50d..000000000 --- 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 e69de29bb..000000000 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 ce0136250..000000000 --- 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 9133aec32..000000000 --- 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 2d07708ad..000000000 --- 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 193/223] 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 5cb2fd5b2..b365e162f 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 fc4f3278f..000000000 --- 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 d24cd9722..000000000 --- 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 4e80088bf..481b99bad 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 194/223] 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 c22c1b22b..f6bc29ae1 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 61d586b9d..b066f497e 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 195/223] 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 9c4fee7a0..65f90c8c1 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 196/223] 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 ef5665397..e6e1e1892 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 c0b010eae..a752f76a7 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 197/223] 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 65f90c8c1..cdddb94d0 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 198/223] 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 e6e1e1892..c89822843 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 22a9632e8..9977866cd 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 62158fb12..42b618143 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 07859d57c..580b71731 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 ba6f0ba04..8d37e34c8 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 1f82a9b5c..26856c966 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 79a038dff..4514c077c 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 f77b04271..293b078da 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 5fd358c85..b89a2b4b3 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 0c5e053c9..47cf3ee41 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 7697ab619..d2e774859 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 934dae015..07bd90571 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 a752f76a7..5c1c063a3 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 c59445402..3ea6c62f8 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 199/223] 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 7d0562767..09b1ed447 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 200/223] 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 915595c25..bf6c1dc38 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 201/223] 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 580b71731..39c421907 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 202/223] 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 480c335c2..ac8f85d13 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 34e19ebdc..461410a49 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 c89822843..8d51fd1cf 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 9977866cd..b729d0151 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 13ee4396d..0196bf02d 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 14024dec6..f86044841 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 39c421907..5104a0f57 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 4514c077c..0dee4706a 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 8e8a70d88..53681caf8 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 a1ae254f6..52af26ad1 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 095fad7ab..7a59e9689 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 07bd90571..f3128780b 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 5c1c063a3..bbc74323c 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 e8938b2c0..82b827e75 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 b5ea49508..c0523025b 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 203/223] 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 ac8f85d13..a18df6d9f 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 461410a49..7d2f95fae 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 204/223] 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 80afa26bc..638de6ebf 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 205/223] 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 3e26018d0..4a3a76f52 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 206/223] 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 37128c43f..40eb2d3b1 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 207/223] 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 a18df6d9f..f2a4f9ccd 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 208/223] 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 79a953e38..73caa6ca7 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 209/223] 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 154fa1999..0c4226f9b 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 210/223] 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 bf6c1dc38..853d0ff7b 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 a7ee96831..bdd03a8b4 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 211/223] 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 8d51fd1cf..57de52338 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 212/223] 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 cf1589114..648ab3ebe 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 213/223] 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 d4a3533a1..f0650fd82 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 1400cb9a2..22f2e5df9 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 497279bd8..bcb6a374c 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 6f0403b9d..e86ec7d4e 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 214/223] 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 d270a9534..7a42e6900 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 9ed526818..176a19f2f 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 4da5e2997..3b533b416 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 83fcba87c..3ad716b72 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 f2a4f9ccd..0fc26950d 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 7d2f95fae..708999ef0 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 57de52338..93a7ddcf6 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 b729d0151..497d0ced8 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 f0650fd82..de89b0207 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 22f2e5df9..da1c1628c 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 c3ad512dd..20e5ff8ef 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 000000000..eb4525a4f --- /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 000000000..0c8bc3857 --- /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 47cf3ee41..8a2ab1c7a 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 9f77f0a3c..b6379bee4 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 f3128780b..6c00b949c 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 bbc74323c..ec22d0306 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 ebc1044bc..a40f20696 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 92975400a..38766e74f 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 c0523025b..817c0e43c 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 215/223] 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 61e414fc4..e1d430307 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 5104a0f57..755dbc093 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 cf9b66091..facf02da8 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 216/223] uuid is not used --- CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b365e162f..fd5de4c39 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 217/223] 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 93a7ddcf6..cfd981088 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 218/223] 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 fd5de4c39..8eb8b44c2 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 219/223] 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 7cd9e2256..a6ad43ce5 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 220/223] 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 2a7f5948e..a7103b991 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 221/223] 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 755dbc093..fe650237a 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 438f542f0..d3d4b4435 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 a40f20696..0d7802081 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 222/223] 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 0fc26950d..e6d2965fa 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 cfd981088..f93a3e342 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 fe650237a..013af5b3a 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 26856c966..308883fc5 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 de89b0207..a7623efea 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 223/223] 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 e6d2965fa..a97268318 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 708999ef0..d518d0056 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: