mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 00:26:39 +00:00 
			
		
		
		
	Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
		
						commit
						6c4920c58e
					
				
					 82 changed files with 683 additions and 404 deletions
				
			
		| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
OpenMW
 | 
			
		||||
======
 | 
			
		||||
 | 
			
		||||
[](https://travis-ci.org/OpenMW/openmw) [](https://scan.coverity.com/projects/3740)
 | 
			
		||||
[](https://travis-ci.org/OpenMW/openmw) [](https://scan.coverity.com/projects/3740)
 | 
			
		||||
 | 
			
		||||
OpenMW is an attempt at recreating the engine for the popular role-playing game
 | 
			
		||||
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +68,10 @@ Command line options
 | 
			
		|||
                                            of the blacklist is enabled)
 | 
			
		||||
      --script-blacklist-use [=arg(=1)] (=1)
 | 
			
		||||
                                            enable script blacklisting
 | 
			
		||||
      --load-savegame arg                   load a save game file on game startup
 | 
			
		||||
      --load-savegame arg                   load a save game file on game startup 
 | 
			
		||||
                                            (specify an absolute filename or a 
 | 
			
		||||
                                            filename relative to the current 
 | 
			
		||||
                                            working directory)
 | 
			
		||||
      --skip-menu [=arg(=1)] (=0)           skip main menu on game startup
 | 
			
		||||
      --new-game [=arg(=1)] (=0)            run new game sequence (ignored if
 | 
			
		||||
                                            skip-menu=0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -535,10 +535,10 @@ void Record<ESM::Class>::print()
 | 
			
		|||
    std::cout << "  Specialization: " << specializationLabel(mData.mData.mSpecialization)
 | 
			
		||||
              << " (" << mData.mData.mSpecialization << ")" << std::endl;
 | 
			
		||||
    for (int i = 0; i != 5; i++)
 | 
			
		||||
        std::cout << "  Major Skill: " << skillLabel(mData.mData.mSkills[i][0])
 | 
			
		||||
        std::cout << "  Minor Skill: " << skillLabel(mData.mData.mSkills[i][0])
 | 
			
		||||
                  << " (" << mData.mData.mSkills[i][0] << ")" << std::endl;
 | 
			
		||||
    for (int i = 0; i != 5; i++)
 | 
			
		||||
        std::cout << "  Minor Skill: " << skillLabel(mData.mData.mSkills[i][1])
 | 
			
		||||
        std::cout << "  Major Skill: " << skillLabel(mData.mData.mSkills[i][1])
 | 
			
		||||
                  << " (" << mData.mData.mSkills[i][1] << ")" << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -837,7 +837,7 @@ void Record<ESM::CreatureLevList>::print()
 | 
			
		|||
    std::cout << "  Chance for None: " << (int)mData.mChanceNone << std::endl;
 | 
			
		||||
    std::cout << "  Flags: " << creatureListFlags(mData.mFlags) << std::endl;
 | 
			
		||||
    std::cout << "  Number of items: " << mData.mList.size() << std::endl;
 | 
			
		||||
    std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
 | 
			
		||||
    std::vector<ESM::LevelledListBase::LevelItem>::iterator iit;
 | 
			
		||||
    for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
 | 
			
		||||
        std::cout << "  Creature: Level: " << iit->mLevel
 | 
			
		||||
                  << " Creature: " << iit->mId << std::endl;
 | 
			
		||||
| 
						 | 
				
			
			@ -849,7 +849,7 @@ void Record<ESM::ItemLevList>::print()
 | 
			
		|||
    std::cout << "  Chance for None: " << (int)mData.mChanceNone << std::endl;
 | 
			
		||||
    std::cout << "  Flags: " << itemListFlags(mData.mFlags) << std::endl;
 | 
			
		||||
    std::cout << "  Number of items: " << mData.mList.size() << std::endl;
 | 
			
		||||
    std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
 | 
			
		||||
    std::vector<ESM::LevelledListBase::LevelItem>::iterator iit;
 | 
			
		||||
    for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
 | 
			
		||||
        std::cout << "  Inventory: Level: " << iit->mLevel
 | 
			
		||||
                  << " Item: " << iit->mId << std::endl;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
#include <components/esm/weatherstate.hpp>
 | 
			
		||||
#include <components/esm/globalscript.hpp>
 | 
			
		||||
#include <components/esm/queststate.hpp>
 | 
			
		||||
#include <components/esm/stolenitems.hpp>
 | 
			
		||||
 | 
			
		||||
#include "importcrec.hpp"
 | 
			
		||||
#include "importcntc.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -387,24 +388,50 @@ public:
 | 
			
		|||
    virtual void read(ESM::ESMReader &esm)
 | 
			
		||||
    {
 | 
			
		||||
        std::string itemid = esm.getHNString("NAME");
 | 
			
		||||
        Misc::StringUtils::toLower(itemid);
 | 
			
		||||
 | 
			
		||||
        while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
 | 
			
		||||
        {
 | 
			
		||||
            if (esm.retSubName().toString() == "FNAM")
 | 
			
		||||
            {
 | 
			
		||||
                std::string factionid = esm.getHString();
 | 
			
		||||
                mFactionStolenItems.insert(std::make_pair(itemid, factionid));
 | 
			
		||||
                mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(factionid), true));
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                std::string ownerid = esm.getHString();
 | 
			
		||||
                mStolenItems.insert(std::make_pair(itemid, ownerid));
 | 
			
		||||
                mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    virtual void write(ESM::ESMWriter &esm)
 | 
			
		||||
    {
 | 
			
		||||
        ESM::StolenItems items;
 | 
			
		||||
        for (std::map<std::string, std::set<Owner> >::const_iterator it = mStolenItems.begin(); it != mStolenItems.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            std::map<std::pair<std::string, bool>, int> owners;
 | 
			
		||||
            for (std::set<Owner>::const_iterator ownerIt = it->second.begin(); ownerIt != it->second.end(); ++ownerIt)
 | 
			
		||||
            {
 | 
			
		||||
                owners.insert(std::make_pair(std::make_pair(ownerIt->first, ownerIt->second)
 | 
			
		||||
                                             // Since OpenMW doesn't suffer from the owner contamination bug,
 | 
			
		||||
                                             // it needs a count argument. But for legacy savegames, we don't know
 | 
			
		||||
                                             // this count, so must assume all items of that ID are stolen,
 | 
			
		||||
                                             // like vanilla MW did.
 | 
			
		||||
                                             ,std::numeric_limits<int>::max()));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            items.mStolenItems.insert(std::make_pair(it->first, owners));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        esm.startRecord(ESM::REC_STLN);
 | 
			
		||||
        items.write(esm);
 | 
			
		||||
        esm.endRecord(ESM::REC_STLN);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::multimap<std::string, std::string> mStolenItems;
 | 
			
		||||
    std::multimap<std::string, std::string> mFactionStolenItems;
 | 
			
		||||
    typedef std::pair<std::string, bool> Owner; // <owner id, bool isFaction>
 | 
			
		||||
 | 
			
		||||
    std::map<std::string, std::set<Owner> > mStolenItems;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Seen responses for a dialogue topic?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,8 @@ namespace ESSImport
 | 
			
		|||
        }
 | 
			
		||||
        for (int i=0; i<8; ++i)
 | 
			
		||||
            out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];
 | 
			
		||||
        for (int i=0; i<27; ++i)
 | 
			
		||||
            out.mObject.mNpcStats.mSkills[i].mRegular.mProgress = pcdt.mPNAM.mSkillProgress[i];
 | 
			
		||||
        out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress;
 | 
			
		||||
 | 
			
		||||
        if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon)
 | 
			
		||||
| 
						 | 
				
			
			@ -24,9 +26,6 @@ namespace ESSImport
 | 
			
		|||
        if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Spell)
 | 
			
		||||
            out.mObject.mCreatureStats.mDrawState = 2;
 | 
			
		||||
 | 
			
		||||
        // TODO: convert PNAM.mSkillProgress, needs to be converted to uniform scale
 | 
			
		||||
        // (or change openmw to accept non-uniform skill progress)
 | 
			
		||||
 | 
			
		||||
        firstPersonCam = (pcdt.mPNAM.mCameraState == PCDT::CameraState_FirstPerson);
 | 
			
		||||
 | 
			
		||||
        for (std::vector<std::string>::const_iterator it = pcdt.mKnownDialogueTopics.begin();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ namespace ESSImport
 | 
			
		|||
        bool mHasACSC;
 | 
			
		||||
        ACSC mACSC;
 | 
			
		||||
 | 
			
		||||
        int mSkills[27][2];
 | 
			
		||||
        int mSkills[27][2]; // skills, base and modified
 | 
			
		||||
 | 
			
		||||
        // creature combat stats, base and modified
 | 
			
		||||
        // I think these can be ignored in the conversion, because it is not possible
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ namespace ESSImport
 | 
			
		|||
        ActorData::load(esm);
 | 
			
		||||
        if (esm.isNextSub("LVCR"))
 | 
			
		||||
        {
 | 
			
		||||
            // occurs on leveled creature spawner references
 | 
			
		||||
            // occurs on levelled creature spawner references
 | 
			
		||||
            // probably some identifier for the creature that has been spawned?
 | 
			
		||||
            unsigned char lvcr;
 | 
			
		||||
            esm.getHT(lvcr);
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ namespace ESSImport
 | 
			
		|||
        mEnabled = true;
 | 
			
		||||
        esm.getHNOT(mEnabled, "ZNAM");
 | 
			
		||||
 | 
			
		||||
        // DATA should occur for all references, except leveled creature spawners
 | 
			
		||||
        // DATA should occur for all references, except levelled creature spawners
 | 
			
		||||
        // I've seen DATA *twice* on a creature record, and with the exact same content too! weird
 | 
			
		||||
        // alarmvoi0000.ess
 | 
			
		||||
        esm.getHNOT(mPos, "DATA", 24);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@
 | 
			
		|||
#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
 | 
			
		||||
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
 | 
			
		||||
 | 
			
		||||
#include <SDL.h>
 | 
			
		||||
#include <SDL_video.h>
 | 
			
		||||
 | 
			
		||||
#include <OgreRoot.h>
 | 
			
		||||
#include <OgreRenderSystem.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
#include <iostream>
 | 
			
		||||
#include <csignal>
 | 
			
		||||
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
#include <QTextCodec>
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +27,8 @@ int main(int argc, char *argv[])
 | 
			
		|||
            qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError());
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        signal(SIGINT, SIG_DFL); // We don't want to use the SDL event loop in the launcher,
 | 
			
		||||
                                 // so reset SIGINT which SDL wants to redirect to an SDL_Quit event.
 | 
			
		||||
 | 
			
		||||
        QApplication app(argc, argv);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -170,7 +170,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
 | 
			
		|||
 | 
			
		||||
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
 | 
			
		||||
  : mOgre (0)
 | 
			
		||||
  , mFpsLevel(0)
 | 
			
		||||
  , mVerboseScripts (false)
 | 
			
		||||
  , mSkipMenu (false)
 | 
			
		||||
  , mUseSound (true)
 | 
			
		||||
| 
						 | 
				
			
			@ -292,16 +291,10 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
 | 
			
		|||
    else
 | 
			
		||||
        throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed.");
 | 
			
		||||
 | 
			
		||||
    // load user settings if they exist, otherwise just load the default settings as user settings
 | 
			
		||||
    // load user settings if they exist
 | 
			
		||||
    const std::string settingspath = mCfgMgr.getUserConfigPath().string() + "/settings.cfg";
 | 
			
		||||
    if (boost::filesystem::exists(settingspath))
 | 
			
		||||
        settings.loadUser(settingspath);
 | 
			
		||||
    else if (boost::filesystem::exists(localdefault))
 | 
			
		||||
        settings.loadUser(localdefault);
 | 
			
		||||
    else if (boost::filesystem::exists(globaldefault))
 | 
			
		||||
        settings.loadUser(globaldefault);
 | 
			
		||||
 | 
			
		||||
    mFpsLevel = settings.getInt("fps", "HUD");
 | 
			
		||||
 | 
			
		||||
    // load nif overrides
 | 
			
		||||
    NifOverrides::Overrides nifOverrides;
 | 
			
		||||
| 
						 | 
				
			
			@ -377,7 +370,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
 | 
			
		|||
    mEnvironment.setInputManager (input);
 | 
			
		||||
 | 
			
		||||
    MWGui::WindowManager* window = new MWGui::WindowManager(
 | 
			
		||||
                mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
 | 
			
		||||
                mExtensions, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
 | 
			
		||||
                mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, mFallbackMap);
 | 
			
		||||
    mEnvironment.setWindowManager (window);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -578,11 +571,6 @@ void OMW::Engine::setSoundUsage(bool soundUsage)
 | 
			
		|||
    mUseSound = soundUsage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OMW::Engine::showFPS(int level)
 | 
			
		||||
{
 | 
			
		||||
    mFpsLevel = level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
 | 
			
		||||
{
 | 
			
		||||
    mEncoding = encoding;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,7 +71,6 @@ namespace OMW
 | 
			
		|||
            OEngine::Render::OgreRenderer *mOgre;
 | 
			
		||||
            std::string mCellName;
 | 
			
		||||
            std::vector<std::string> mContentFiles;
 | 
			
		||||
            int mFpsLevel;
 | 
			
		||||
            bool mVerboseScripts;
 | 
			
		||||
            bool mSkipMenu;
 | 
			
		||||
            bool mUseSound;
 | 
			
		||||
| 
						 | 
				
			
			@ -151,9 +150,6 @@ namespace OMW
 | 
			
		|||
             */
 | 
			
		||||
            void addContentFile(const std::string& file);
 | 
			
		||||
 | 
			
		||||
            /// Enable fps counter
 | 
			
		||||
            void showFPS(int level);
 | 
			
		||||
 | 
			
		||||
            /// Enable or disable verbose script output
 | 
			
		||||
            void setScriptsVerbosity(bool scriptsVerbosity);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,7 +153,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
 | 
			
		|||
            ->default_value(true), "enable script blacklisting")
 | 
			
		||||
 | 
			
		||||
        ("load-savegame", bpo::value<std::string>()->default_value(""),
 | 
			
		||||
            "load a save game file on game startup")
 | 
			
		||||
            "load a save game file on game startup (specify an absolute filename or a filename relative to the current working directory)")
 | 
			
		||||
 | 
			
		||||
        ("skip-menu", bpo::value<bool>()->implicit_value(true)
 | 
			
		||||
            ->default_value(false), "skip main menu on game startup")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#ifndef GAME_BASE_INVIRONMENT_H
 | 
			
		||||
#define GAME_BASE_INVIRONMENT_H
 | 
			
		||||
#ifndef GAME_BASE_ENVIRONMENT_H
 | 
			
		||||
#define GAME_BASE_ENVIRONMENT_H
 | 
			
		||||
 | 
			
		||||
namespace MWBase
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,8 @@
 | 
			
		|||
#define GAME_MWBASE_INPUTMANAGER_H
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
namespace MWBase
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ namespace MWBase
 | 
			
		|||
 | 
			
		||||
            virtual void changeInputMode(bool guiMode) = 0;
 | 
			
		||||
 | 
			
		||||
            virtual void processChangedSettings(const Settings::CategorySettingVector& changed) = 0;
 | 
			
		||||
            virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& changed) = 0;
 | 
			
		||||
 | 
			
		||||
            virtual void setDragDrop(bool dragDrop) = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -129,16 +129,15 @@ namespace MWBase
 | 
			
		|||
            /// @return false if the attack was considered a "friendly hit" and forgiven
 | 
			
		||||
            virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 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;
 | 
			
		||||
            /// @param container The container the item is in; may be empty for an item in the world
 | 
			
		||||
            virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container,
 | 
			
		||||
                                    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;
 | 
			
		||||
 | 
			
		||||
            /// @return is \a ptr allowed to take/use \a item or is it a crime?
 | 
			
		||||
            virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim) = 0;
 | 
			
		||||
 | 
			
		||||
            enum PersuasionType
 | 
			
		||||
            {
 | 
			
		||||
                PT_Admire,
 | 
			
		||||
| 
						 | 
				
			
			@ -203,6 +202,15 @@ namespace MWBase
 | 
			
		|||
            virtual void keepPlayerAlive() = 0;
 | 
			
		||||
 | 
			
		||||
            virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const = 0;
 | 
			
		||||
 | 
			
		||||
            virtual void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) = 0;
 | 
			
		||||
 | 
			
		||||
            /// List the owners that the player has stolen this item from (the owner can be an NPC or a faction).
 | 
			
		||||
            /// <Owner, item count>
 | 
			
		||||
            virtual std::vector<std::pair<std::string, int> > getStolenItemOwners(const std::string& itemid) = 0;
 | 
			
		||||
 | 
			
		||||
            /// Has the player stolen this item from the given owner?
 | 
			
		||||
            virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,11 +2,9 @@
 | 
			
		|||
#define GAME_MWBASE_SOUNDMANAGER_H
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwworld/ptr.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Ogre
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +72,7 @@ namespace MWBase
 | 
			
		|||
 | 
			
		||||
            virtual ~SoundManager() {}
 | 
			
		||||
 | 
			
		||||
            virtual void processChangedSettings(const Settings::CategorySettingVector& settings) = 0;
 | 
			
		||||
            virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& settings) = 0;
 | 
			
		||||
 | 
			
		||||
            virtual void stopMusic() = 0;
 | 
			
		||||
            ///< Stops music if it's playing
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,16 +5,20 @@
 | 
			
		|||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include <components/translation/translation.hpp>
 | 
			
		||||
 | 
			
		||||
#include <components/loadinglistener/loadinglistener.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwmechanics/stat.hpp"
 | 
			
		||||
 | 
			
		||||
#include "../mwgui/mode.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Loading
 | 
			
		||||
{
 | 
			
		||||
    class Listener;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Translation
 | 
			
		||||
{
 | 
			
		||||
    class Storage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace MyGUI
 | 
			
		||||
{
 | 
			
		||||
    class Gui;
 | 
			
		||||
| 
						 | 
				
			
			@ -267,7 +271,7 @@ namespace MWBase
 | 
			
		|||
             */
 | 
			
		||||
            virtual std::string getGameSettingString(const std::string &id, const std::string &default_) = 0;
 | 
			
		||||
 | 
			
		||||
            virtual void processChangedSettings(const Settings::CategorySettingVector& changed) = 0;
 | 
			
		||||
            virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& changed) = 0;
 | 
			
		||||
 | 
			
		||||
            virtual void windowResized(int x, int y) = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,26 +3,23 @@
 | 
			
		|||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
#include <set>
 | 
			
		||||
 | 
			
		||||
#include <components/esm/cellid.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwworld/globals.hpp"
 | 
			
		||||
#include "../mwworld/ptr.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Ogre
 | 
			
		||||
{
 | 
			
		||||
    class Vector2;
 | 
			
		||||
    class Vector3;
 | 
			
		||||
    class Quaternion;
 | 
			
		||||
    class Image;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace OEngine
 | 
			
		||||
namespace Loading
 | 
			
		||||
{
 | 
			
		||||
    namespace Physic
 | 
			
		||||
    {
 | 
			
		||||
        class PhysicEngine;
 | 
			
		||||
    }
 | 
			
		||||
    class Listener;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace ESM
 | 
			
		||||
| 
						 | 
				
			
			@ -390,7 +387,7 @@ namespace MWBase
 | 
			
		|||
            virtual bool canPlaceObject (float cursorX, float cursorY) = 0;
 | 
			
		||||
            ///< @return true if it is possible to place on object at specified cursor location
 | 
			
		||||
 | 
			
		||||
            virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0;
 | 
			
		||||
            virtual void processChangedSettings (const std::set< std::pair<std::string, std::string> >& settings) = 0;
 | 
			
		||||
 | 
			
		||||
            virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
 | 
			
		||||
            virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,8 +59,10 @@ namespace MWClass
 | 
			
		|||
            MWWorld::LiveCellRef<ESM::Container> *ref =
 | 
			
		||||
                ptr.get<ESM::Container>();
 | 
			
		||||
 | 
			
		||||
            // setting ownership not needed, since taking items from a container inherits the
 | 
			
		||||
            // container's owner automatically
 | 
			
		||||
            data->mContainerStore.fill(
 | 
			
		||||
                ref->mBase->mInventory, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction(), ptr.getCellRef().getFactionRank(), MWBase::Environment::get().getWorld()->getStore());
 | 
			
		||||
                ref->mBase->mInventory, "");
 | 
			
		||||
 | 
			
		||||
            // store
 | 
			
		||||
            ptr.getRefData().setCustomData (data.release());
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +84,10 @@ namespace MWClass
 | 
			
		|||
        MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>();
 | 
			
		||||
        const ESM::InventoryList& list = ref->mBase->mInventory;
 | 
			
		||||
        MWWorld::ContainerStore& store = getContainerStore(ptr);
 | 
			
		||||
        store.restock(list, ptr, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction(), ptr.getCellRef().getFactionRank());
 | 
			
		||||
 | 
			
		||||
        // setting ownership not needed, since taking items from a container inherits the
 | 
			
		||||
        // container's owner automatically
 | 
			
		||||
        store.restock(list, ptr, "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Container::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,8 +139,7 @@ namespace MWClass
 | 
			
		|||
            // store
 | 
			
		||||
            ptr.getRefData().setCustomData(data.release());
 | 
			
		||||
 | 
			
		||||
            getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr), "", -1,
 | 
			
		||||
                                       MWBase::Environment::get().getWorld()->getStore());
 | 
			
		||||
            getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr));
 | 
			
		||||
 | 
			
		||||
            if (ref->mBase->mFlags & ESM::Creature::Weapon)
 | 
			
		||||
                getInventoryStore(ptr).autoEquip(ptr);   
 | 
			
		||||
| 
						 | 
				
			
			@ -886,7 +885,7 @@ namespace MWClass
 | 
			
		|||
        MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
 | 
			
		||||
        const ESM::InventoryList& list = ref->mBase->mInventory;
 | 
			
		||||
        MWWorld::ContainerStore& store = getContainerStore(ptr);
 | 
			
		||||
        store.restock(list, ptr, ptr.getCellRef().getRefId(), "", -1);
 | 
			
		||||
        store.restock(list, ptr, ptr.getCellRef().getRefId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int Creature::getBaseFightRating(const MWWorld::Ptr &ptr) const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -384,8 +384,8 @@ namespace MWClass
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            // inventory
 | 
			
		||||
            data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "", -1,
 | 
			
		||||
                                       MWBase::Environment::get().getWorld()->getStore());
 | 
			
		||||
            // setting ownership is used to make the NPC auto-equip his initial equipment only, and not bartered items
 | 
			
		||||
            data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr));
 | 
			
		||||
 | 
			
		||||
            data->mNpcStats.setGoldPool(gold);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1328,7 +1328,7 @@ namespace MWClass
 | 
			
		|||
        MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
 | 
			
		||||
        const ESM::InventoryList& list = ref->mBase->mInventory;
 | 
			
		||||
        MWWorld::ContainerStore& store = getContainerStore(ptr);
 | 
			
		||||
        store.restock(list, ptr, ptr.getCellRef().getRefId(), "", -1);
 | 
			
		||||
        store.restock(list, ptr, ptr.getCellRef().getRefId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int Npc::getBaseFightRating (const MWWorld::Ptr& ptr) const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
#include "scripttest.hpp"
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include "../mwworld/manualref.hpp"
 | 
			
		||||
#include "../mwworld/class.hpp"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -285,7 +285,7 @@ namespace MWGui
 | 
			
		|||
            if (mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead())
 | 
			
		||||
                return true;
 | 
			
		||||
            else
 | 
			
		||||
                MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, count);
 | 
			
		||||
                MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, mPtr, count);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -339,7 +339,8 @@ namespace MWGui
 | 
			
		|||
            for (int i=0; i<2; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem();
 | 
			
		||||
                if (Misc::StringUtils::ciEqual(item.getCellRef().getOwner(), mPtr.getCellRef().getRefId()))
 | 
			
		||||
                if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(),
 | 
			
		||||
                                                                                       mPtr.getCellRef().getRefId()))
 | 
			
		||||
                {
 | 
			
		||||
                    std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->getString();
 | 
			
		||||
                    if (msg.find("%s") != std::string::npos)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@
 | 
			
		|||
#include <MyGUI_ScrollView.h>
 | 
			
		||||
 | 
			
		||||
#include <components/misc/resourcehelpers.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
#include "../mwbase/soundmanager.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,16 +65,7 @@ MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack &item, size_t count, I
 | 
			
		|||
    if (item.mFlags & ItemStack::Flag_Bound)
 | 
			
		||||
        return MWWorld::Ptr();
 | 
			
		||||
 | 
			
		||||
    bool setNewOwner = false;
 | 
			
		||||
 | 
			
		||||
    // Are you dead? Then you wont need that anymore
 | 
			
		||||
    if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead()
 | 
			
		||||
            // Make sure that the item is actually owned by the dead actor
 | 
			
		||||
            // Prevents a potential exploit for resetting the owner of any item, by placing the item in a corpse
 | 
			
		||||
            && Misc::StringUtils::ciEqual(item.mBase.getCellRef().getOwner(), mActor.getCellRef().getRefId()))
 | 
			
		||||
        setNewOwner = true;
 | 
			
		||||
 | 
			
		||||
    MWWorld::Ptr ret = otherModel->copyItem(item, count, setNewOwner);
 | 
			
		||||
    MWWorld::Ptr ret = otherModel->copyItem(item, count, false);
 | 
			
		||||
    removeItem(item, count);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,8 @@
 | 
			
		|||
#include <MyGUI_InputManager.h>
 | 
			
		||||
#include <MyGUI_Button.h>
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
#include "../mwbase/soundmanager.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -622,7 +624,7 @@ namespace MWGui
 | 
			
		|||
            throw std::runtime_error("Added item not found");
 | 
			
		||||
        mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
 | 
			
		||||
 | 
			
		||||
        MWBase::Environment::get().getMechanicsManager()->itemTaken(player, newObject, count);
 | 
			
		||||
        MWBase::Environment::get().getMechanicsManager()->itemTaken(player, newObject, MWWorld::Ptr(), count);
 | 
			
		||||
 | 
			
		||||
        if (MWBase::Environment::get().getWindowManager()->getSpellWindow())
 | 
			
		||||
            MWBase::Environment::get().getWindowManager()->getSpellWindow()->updateSpells();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
#include "itemmodel.hpp"
 | 
			
		||||
 | 
			
		||||
#include <set>
 | 
			
		||||
 | 
			
		||||
#include "../mwworld/class.hpp"
 | 
			
		||||
#include "../mwworld/containerstore.hpp"
 | 
			
		||||
#include "../mwworld/store.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,20 +46,27 @@ namespace MWGui
 | 
			
		|||
        ItemModel();
 | 
			
		||||
        virtual ~ItemModel() {}
 | 
			
		||||
 | 
			
		||||
        typedef int ModelIndex;
 | 
			
		||||
        typedef int ModelIndex; // -1 means invalid index
 | 
			
		||||
 | 
			
		||||
        /// Throws for invalid index or out of range index
 | 
			
		||||
        virtual ItemStack getItem (ModelIndex index) = 0;
 | 
			
		||||
        ///< throws for invalid index
 | 
			
		||||
 | 
			
		||||
        /// The number of items in the model, this specifies the range of indices you can pass to
 | 
			
		||||
        /// the getItem function (but this range is only valid until the next call to update())
 | 
			
		||||
        virtual size_t getItemCount() = 0;
 | 
			
		||||
 | 
			
		||||
        /// Returns an invalid index if the item was not found
 | 
			
		||||
        virtual ModelIndex getIndex (ItemStack item) = 0;
 | 
			
		||||
 | 
			
		||||
        /// Rebuild the item model, this will invalidate existing model indices
 | 
			
		||||
        virtual void update() = 0;
 | 
			
		||||
 | 
			
		||||
        /// Move items from this model to \a otherModel.
 | 
			
		||||
        /// @note Derived implementations may return an empty Ptr if the move was unsuccessful.
 | 
			
		||||
        virtual MWWorld::Ptr moveItem (const ItemStack& item, size_t count, ItemModel* otherModel);
 | 
			
		||||
 | 
			
		||||
        /// @param setNewOwner Set the copied item's owner to the actor we are copying to, or keep the original owner?
 | 
			
		||||
        /// @param setNewOwner If true, set the copied item's owner to the actor we are copying to,
 | 
			
		||||
        ///                    otherwise reset owner to ""
 | 
			
		||||
        virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false) = 0;
 | 
			
		||||
        virtual void removeItem (const ItemStack& item, size_t count) = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,8 @@
 | 
			
		|||
 | 
			
		||||
#include <components/misc/utf8stream.hpp>
 | 
			
		||||
 | 
			
		||||
#include <components/translation/translation.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
#include "../mwbase/journal.hpp"
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,7 +139,6 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
        if(world->getStore().get<ESM::Class>().isDynamic(cls->mId))
 | 
			
		||||
        {
 | 
			
		||||
            // Vanilla uses thief.dds for custom classes.
 | 
			
		||||
            // Choosing Stealth specialization and Speed/Agility as attributes, if possible. Otherwise fall back to first class found.
 | 
			
		||||
            MWWorld::SharedIterator<ESM::Class> it = world->getStore().get<ESM::Class>().begin();
 | 
			
		||||
            for(; it != world->getStore().get<ESM::Class>().end(); ++it)
 | 
			
		||||
| 
						 | 
				
			
			@ -173,14 +172,17 @@ namespace MWGui
 | 
			
		|||
            if (pcStats.getAttribute(i).getBase() < 100)
 | 
			
		||||
            {
 | 
			
		||||
                mAttributes[i]->setEnabled(true);
 | 
			
		||||
                mAttributeValues[i]->setEnabled(true);
 | 
			
		||||
                availableAttributes++;
 | 
			
		||||
 | 
			
		||||
                int mult = pcStats.getLevelupAttributeMultiplier (i);
 | 
			
		||||
                mult = std::min(mult, 100-pcStats.getAttribute(i).getBase());
 | 
			
		||||
                text->setCaption(mult <= 1 ? "" : "x" + MyGUI::utility::toString(mult));
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mAttributes[i]->setEnabled(false);
 | 
			
		||||
                mAttributeValues[i]->setEnabled(false);
 | 
			
		||||
 | 
			
		||||
                text->setCaption("");
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,8 @@
 | 
			
		|||
#include <MyGUI_Gui.h>
 | 
			
		||||
#include <MyGUI_TextBox.h>
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
#include "../mwbase/statemanager.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@
 | 
			
		|||
#include <components/version/version.hpp>
 | 
			
		||||
 | 
			
		||||
#include <components/widgets/imagebutton.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
#include "../mwbase/windowmanager.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@
 | 
			
		|||
#include <MyGUI_FactoryManager.h>
 | 
			
		||||
 | 
			
		||||
#include <components/esm/globalmap.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/windowmanager.hpp"
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,7 @@
 | 
			
		|||
#include <SDL_video.h>
 | 
			
		||||
 | 
			
		||||
#include <components/widgets/sharedstatebutton.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -376,18 +376,26 @@ namespace MWGui
 | 
			
		|||
        for (SkillList::const_iterator it = skills.begin(); it != end; ++it)
 | 
			
		||||
        {
 | 
			
		||||
            int skillId = *it;
 | 
			
		||||
            if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
 | 
			
		||||
            if (skillId < 0 || skillId >= ESM::Skill::Length) // Skip unknown skill indexes
 | 
			
		||||
                continue;
 | 
			
		||||
            assert(skillId >= 0 && skillId < ESM::Skill::Length);
 | 
			
		||||
            const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId];
 | 
			
		||||
            const MWMechanics::SkillValue &stat = mSkillValues.find(skillId)->second;
 | 
			
		||||
            int base = stat.getBase();
 | 
			
		||||
            int modified = stat.getModified();
 | 
			
		||||
            int progressPercent = stat.getProgress() * 100;
 | 
			
		||||
 | 
			
		||||
            MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
 | 
			
		||||
            const MWWorld::ESMStore &esmStore =
 | 
			
		||||
                MWBase::Environment::get().getWorld()->getStore();
 | 
			
		||||
 | 
			
		||||
            float progressRequirement = player.getClass().getNpcStats(player).getSkillProgressRequirement(skillId,
 | 
			
		||||
                *esmStore.get<ESM::Class>().find(player.get<ESM::NPC>()->mBase->mClass));
 | 
			
		||||
 | 
			
		||||
            // This is how vanilla MW displays the progress bar (I think). Note it's slightly inaccurate,
 | 
			
		||||
            // due to the int casting in the skill levelup logic. Also the progress label could in rare cases
 | 
			
		||||
            // reach 100% without the skill levelling up.
 | 
			
		||||
            // Leaving the original display logic for now, for consistency with ess-imported savegames.
 | 
			
		||||
            int progressPercent = int(float(stat.getProgress()) / float(progressRequirement) * 100.f + 0.5f);
 | 
			
		||||
 | 
			
		||||
            const ESM::Skill* skill = esmStore.get<ESM::Skill>().find(skillId);
 | 
			
		||||
 | 
			
		||||
            std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,10 +8,12 @@
 | 
			
		|||
#include <MyGUI_ImageBox.h>
 | 
			
		||||
 | 
			
		||||
#include <components/misc/resourcehelpers.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
#include "../mwbase/windowmanager.hpp"
 | 
			
		||||
#include "../mwbase/mechanicsmanager.hpp"
 | 
			
		||||
 | 
			
		||||
#include "../mwworld/class.hpp"
 | 
			
		||||
#include "../mwworld/esmstore.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -585,6 +587,15 @@ namespace MWGui
 | 
			
		|||
        ret += getMiscString(cellref.getFaction(), "Faction");
 | 
			
		||||
        if (cellref.getFactionRank() > 0)
 | 
			
		||||
            ret += getValueString(cellref.getFactionRank(), "Rank");
 | 
			
		||||
 | 
			
		||||
        std::vector<std::pair<std::string, int> > itemOwners =
 | 
			
		||||
                MWBase::Environment::get().getMechanicsManager()->getStolenItemOwners(cellref.getRefId());
 | 
			
		||||
 | 
			
		||||
        for (std::vector<std::pair<std::string, int> >::const_iterator it = itemOwners.begin(); it != itemOwners.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            ret += std::string("\nStolen from ") + it->first;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ret += getMiscString(cellref.getGlobalVariable(), "Global");
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -135,11 +135,9 @@ namespace MWGui
 | 
			
		|||
            if (i == sourceModel->getItemCount())
 | 
			
		||||
                throw std::runtime_error("The borrowed item disappeared");
 | 
			
		||||
 | 
			
		||||
            // reset owner while copying, but only for items bought by the player
 | 
			
		||||
            bool setNewOwner = (mMerchant.isEmpty());
 | 
			
		||||
            const ItemStack& item = sourceModel->getItem(i);
 | 
			
		||||
            // copy the borrowed items to our model
 | 
			
		||||
            copyItem(item, it->mCount, setNewOwner);
 | 
			
		||||
            copyItem(item, it->mCount);
 | 
			
		||||
            // then remove them from the source model
 | 
			
		||||
            sourceModel->removeItem(item, it->mCount);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -300,7 +300,8 @@ namespace MWGui
 | 
			
		|||
        // check if the player is attempting to sell back an item stolen from this actor
 | 
			
		||||
        for (std::vector<ItemStack>::iterator it = merchantBought.begin(); it != merchantBought.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (Misc::StringUtils::ciEqual(it->mBase.getCellRef().getOwner(), mPtr.getCellRef().getRefId()))
 | 
			
		||||
            if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(it->mBase.getCellRef().getRefId(),
 | 
			
		||||
                                                                                   mPtr.getCellRef().getRefId()))
 | 
			
		||||
            {
 | 
			
		||||
                std::string msg = gmst.find("sNotifyMessage49")->getString();
 | 
			
		||||
                if (msg.find("%s") != std::string::npos)
 | 
			
		||||
| 
						 | 
				
			
			@ -315,6 +316,8 @@ namespace MWGui
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // TODO: move to mwmechanics
 | 
			
		||||
 | 
			
		||||
        // Is the player buying?
 | 
			
		||||
        bool buying = (mCurrentMerchantOffer < 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#include <MyGUI_ProgressBar.h>
 | 
			
		||||
 | 
			
		||||
#include <components/widgets/box.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/windowmanager.hpp"
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,8 @@
 | 
			
		|||
 | 
			
		||||
#include <MyGUI_InputManager.h>
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/windowmanager.hpp"
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,9 @@
 | 
			
		|||
#include <MyGUI_ClipboardManager.h>
 | 
			
		||||
#include <MyGUI_RenderManager.h>
 | 
			
		||||
 | 
			
		||||
#include <SDL_keyboard.h>
 | 
			
		||||
#include <SDL_clipboard.h>
 | 
			
		||||
 | 
			
		||||
#include <openengine/ogre/renderer.hpp>
 | 
			
		||||
#include <openengine/gui/manager.hpp>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +29,8 @@
 | 
			
		|||
 | 
			
		||||
#include <components/fontloader/fontloader.hpp>
 | 
			
		||||
 | 
			
		||||
#include <components/translation/translation.hpp>
 | 
			
		||||
 | 
			
		||||
#include <components/widgets/widgets.hpp>
 | 
			
		||||
#include <components/widgets/tags.hpp>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +96,7 @@ namespace MWGui
 | 
			
		|||
{
 | 
			
		||||
 | 
			
		||||
    WindowManager::WindowManager(
 | 
			
		||||
        const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *ogre,
 | 
			
		||||
        const Compiler::Extensions& extensions, OEngine::Render::OgreRenderer *ogre,
 | 
			
		||||
            const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
 | 
			
		||||
            Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map<std::string, std::string>& fallbackMap)
 | 
			
		||||
      : mConsoleOnlyScripts(consoleOnlyScripts)
 | 
			
		||||
| 
						 | 
				
			
			@ -162,7 +167,6 @@ namespace MWGui
 | 
			
		|||
      , mForceHidden(GW_None)
 | 
			
		||||
      , mAllowed(GW_ALL)
 | 
			
		||||
      , mRestAllowed(true)
 | 
			
		||||
      , mShowFPSLevel(fpsLevel)
 | 
			
		||||
      , mFPS(0.0f)
 | 
			
		||||
      , mTriangleCount(0)
 | 
			
		||||
      , mBatchCount(0)
 | 
			
		||||
| 
						 | 
				
			
			@ -264,7 +268,7 @@ namespace MWGui
 | 
			
		|||
        trackWindow(mDialogueWindow, "dialogue");
 | 
			
		||||
        mContainerWindow = new ContainerWindow(mDragAndDrop);
 | 
			
		||||
        trackWindow(mContainerWindow, "container");
 | 
			
		||||
        mHud = new HUD(mCustomMarkers, mShowFPSLevel, mDragAndDrop);
 | 
			
		||||
        mHud = new HUD(mCustomMarkers, Settings::Manager::getInt("fps", "HUD"), mDragAndDrop);
 | 
			
		||||
        mToolTips = new ToolTips();
 | 
			
		||||
        mScrollWindow = new ScrollWindow();
 | 
			
		||||
        mBookWindow = new BookWindow();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,13 +5,14 @@
 | 
			
		|||
   This class owns and controls all the MW specific windows in the
 | 
			
		||||
   GUI. It can enable/disable Gui mode, and is responsible for sending
 | 
			
		||||
   and retrieving information from the Gui.
 | 
			
		||||
 | 
			
		||||
   MyGUI should be initialized separately before creating instances of
 | 
			
		||||
   this class.
 | 
			
		||||
**/
 | 
			
		||||
 | 
			
		||||
#include <stack>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/windowmanager.hpp"
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "mapwindow.hpp"
 | 
			
		||||
 | 
			
		||||
#include <MyGUI_KeyCode.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +97,7 @@ namespace MWGui
 | 
			
		|||
    typedef std::pair<std::string, int> Faction;
 | 
			
		||||
    typedef std::vector<Faction> FactionList;
 | 
			
		||||
 | 
			
		||||
    WindowManager(const Compiler::Extensions& extensions, int fpsLevel,
 | 
			
		||||
    WindowManager(const Compiler::Extensions& extensions,
 | 
			
		||||
                  OEngine::Render::OgreRenderer *mOgre, const std::string& logpath,
 | 
			
		||||
                  const std::string& cacheDir, bool consoleOnlyScripts,
 | 
			
		||||
                  Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map<std::string,std::string>& fallbackMap);
 | 
			
		||||
| 
						 | 
				
			
			@ -450,7 +451,6 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
    void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings
 | 
			
		||||
 | 
			
		||||
    int mShowFPSLevel;
 | 
			
		||||
    float mFPS;
 | 
			
		||||
    unsigned int mTriangleCount;
 | 
			
		||||
    unsigned int mBatchCount;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <list>
 | 
			
		||||
 | 
			
		||||
#include "movement.hpp"
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,8 @@
 | 
			
		|||
#include "creaturestats.hpp"
 | 
			
		||||
#include "security.hpp"
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwrender/animation.hpp"
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,9 +12,9 @@ namespace MWMechanics
 | 
			
		|||
{
 | 
			
		||||
 | 
			
		||||
    /// @return ID of resulting item, or empty if none
 | 
			
		||||
    inline std::string getLevelledItem (const ESM::LeveledListBase* levItem, bool creature, unsigned char failChance=0)
 | 
			
		||||
    inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature, unsigned char failChance=0)
 | 
			
		||||
    {
 | 
			
		||||
        const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList;
 | 
			
		||||
        const std::vector<ESM::LevelledListBase::LevelItem>& items = levItem->mList;
 | 
			
		||||
 | 
			
		||||
        const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr();
 | 
			
		||||
        int playerLevel = player.getClass().getCreatureStats(player).getLevel();
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
        std::vector<std::string> candidates;
 | 
			
		||||
        int highestLevel = 0;
 | 
			
		||||
        for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
 | 
			
		||||
        for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->mLevel > highestLevel && it->mLevel <= playerLevel)
 | 
			
		||||
                highestLevel = it->mLevel;
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ namespace MWMechanics
 | 
			
		|||
            allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;
 | 
			
		||||
 | 
			
		||||
        std::pair<int, std::string> highest = std::make_pair(-1, "");
 | 
			
		||||
        for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
 | 
			
		||||
        for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (playerLevel >= it->mLevel
 | 
			
		||||
                    && (allLevels || it->mLevel == highestLevel))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,8 @@
 | 
			
		|||
#include "mechanicsmanagerimp.hpp"
 | 
			
		||||
#include "npcstats.hpp"
 | 
			
		||||
 | 
			
		||||
#include <components/esm/stolenitems.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwworld/esmstore.hpp"
 | 
			
		||||
#include "../mwworld/inventorystore.hpp"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -873,31 +875,31 @@ namespace MWMechanics
 | 
			
		|||
        mAI = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool MechanicsManager::isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim)
 | 
			
		||||
    bool MechanicsManager::isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::CellRef& cellref, MWWorld::Ptr& victim)
 | 
			
		||||
    {
 | 
			
		||||
        const std::string& owner = item.getCellRef().getOwner();
 | 
			
		||||
        const std::string& owner = cellref.getOwner();
 | 
			
		||||
        bool isOwned = !owner.empty() && owner != "player";
 | 
			
		||||
 | 
			
		||||
        const std::string& faction = item.getCellRef().getFaction();
 | 
			
		||||
        const std::string& faction = cellref.getFaction();
 | 
			
		||||
        bool isFactionOwned = false;
 | 
			
		||||
        if (!faction.empty() && ptr.getClass().isNpc())
 | 
			
		||||
        {
 | 
			
		||||
            const std::map<std::string, int>& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks();
 | 
			
		||||
            std::map<std::string, int>::const_iterator found = factions.find(Misc::StringUtils::lowerCase(faction));
 | 
			
		||||
            if (found == factions.end()
 | 
			
		||||
                    || found->second < item.getCellRef().getFactionRank())
 | 
			
		||||
                    || found->second < cellref.getFactionRank())
 | 
			
		||||
                isFactionOwned = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const std::string& globalVariable = item.getCellRef().getGlobalVariable();
 | 
			
		||||
        const std::string& globalVariable = cellref.getGlobalVariable();
 | 
			
		||||
        if (!globalVariable.empty() && MWBase::Environment::get().getWorld()->getGlobalInt(Misc::StringUtils::lowerCase(globalVariable)) == 1)
 | 
			
		||||
        {
 | 
			
		||||
            isOwned = false;
 | 
			
		||||
            isFactionOwned = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!item.getCellRef().getOwner().empty())
 | 
			
		||||
            victim = MWBase::Environment::get().getWorld()->searchPtr(item.getCellRef().getOwner(), true);
 | 
			
		||||
        if (!cellref.getOwner().empty())
 | 
			
		||||
            victim = MWBase::Environment::get().getWorld()->searchPtr(cellref.getOwner(), true);
 | 
			
		||||
 | 
			
		||||
        return (!isOwned && !isFactionOwned);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -916,7 +918,7 @@ namespace MWMechanics
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        MWWorld::Ptr victim;
 | 
			
		||||
        if (isAllowedToUse(ptr, bed, victim))
 | 
			
		||||
        if (isAllowedToUse(ptr, bed.getCellRef(), victim))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        if(commitCrime(ptr, victim, OT_SleepingInOwnedBed))
 | 
			
		||||
| 
						 | 
				
			
			@ -931,16 +933,103 @@ namespace MWMechanics
 | 
			
		|||
    void MechanicsManager::objectOpened(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item)
 | 
			
		||||
    {
 | 
			
		||||
        MWWorld::Ptr victim;
 | 
			
		||||
        if (isAllowedToUse(ptr, item, victim))
 | 
			
		||||
        if (isAllowedToUse(ptr, item.getCellRef(), victim))
 | 
			
		||||
            return;
 | 
			
		||||
        commitCrime(ptr, victim, OT_Trespassing);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count)
 | 
			
		||||
    std::vector<std::pair<std::string, int> > MechanicsManager::getStolenItemOwners(const std::string& itemid)
 | 
			
		||||
    {
 | 
			
		||||
        MWWorld::Ptr victim;
 | 
			
		||||
        if (isAllowedToUse(ptr, item, victim))
 | 
			
		||||
        std::vector<std::pair<std::string, int> > result;
 | 
			
		||||
        StolenItemsMap::const_iterator it = mStolenItems.find(Misc::StringUtils::lowerCase(itemid));
 | 
			
		||||
        if (it == mStolenItems.end())
 | 
			
		||||
            return result;
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            const OwnerMap& owners = it->second;
 | 
			
		||||
            for (OwnerMap::const_iterator ownerIt = owners.begin(); ownerIt != owners.end(); ++ownerIt)
 | 
			
		||||
                result.push_back(std::make_pair(ownerIt->first.first, ownerIt->second));
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool MechanicsManager::isItemStolenFrom(const std::string &itemid, const std::string &ownerid)
 | 
			
		||||
    {
 | 
			
		||||
        StolenItemsMap::const_iterator it = mStolenItems.find(Misc::StringUtils::lowerCase(itemid));
 | 
			
		||||
        if (it == mStolenItems.end())
 | 
			
		||||
            return false;
 | 
			
		||||
        const OwnerMap& owners = it->second;
 | 
			
		||||
        OwnerMap::const_iterator ownerFound = owners.find(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false));
 | 
			
		||||
        return ownerFound != owners.end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MechanicsManager::confiscateStolenItems(const MWWorld::Ptr &player, const MWWorld::Ptr &targetContainer)
 | 
			
		||||
    {
 | 
			
		||||
        MWWorld::ContainerStore& store = player.getClass().getContainerStore(player);
 | 
			
		||||
        for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            StolenItemsMap::iterator stolenIt = mStolenItems.find(Misc::StringUtils::lowerCase(it->getClass().getId(*it)));
 | 
			
		||||
            if (stolenIt == mStolenItems.end())
 | 
			
		||||
                continue;
 | 
			
		||||
            OwnerMap& owners = stolenIt->second;
 | 
			
		||||
            int itemCount = it->getRefData().getCount();
 | 
			
		||||
            for (OwnerMap::iterator ownerIt = owners.begin(); ownerIt != owners.end();)
 | 
			
		||||
            {
 | 
			
		||||
                int toRemove = std::min(itemCount, ownerIt->second);
 | 
			
		||||
                itemCount -= toRemove;
 | 
			
		||||
                ownerIt->second -= toRemove;
 | 
			
		||||
                if (ownerIt->second == 0)
 | 
			
		||||
                    owners.erase(ownerIt++);
 | 
			
		||||
                else
 | 
			
		||||
                    ++ownerIt;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int toMove = it->getRefData().getCount() - itemCount;
 | 
			
		||||
 | 
			
		||||
            targetContainer.getClass().getContainerStore(targetContainer).add(*it, toMove, targetContainer);
 | 
			
		||||
            store.remove(*it, toMove, player);
 | 
			
		||||
        }
 | 
			
		||||
        // TODO: unhardcode the locklevel
 | 
			
		||||
        targetContainer.getClass().lock(targetContainer,50);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, const MWWorld::Ptr& container,
 | 
			
		||||
                                     int count)
 | 
			
		||||
    {
 | 
			
		||||
        if (ptr != MWBase::Environment::get().getWorld()->getPlayerPtr())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        MWWorld::Ptr victim;
 | 
			
		||||
 | 
			
		||||
        const MWWorld::CellRef* ownerCellRef = &item.getCellRef();
 | 
			
		||||
        if (!container.isEmpty())
 | 
			
		||||
        {
 | 
			
		||||
            // Inherit the owner of the container
 | 
			
		||||
            ownerCellRef = &container.getCellRef();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (!item.getCellRef().hasContentFile())
 | 
			
		||||
            {
 | 
			
		||||
                // this is a manually placed item, which means it was already stolen
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isAllowedToUse(ptr, *ownerCellRef, victim))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        Owner owner;
 | 
			
		||||
        owner.first = ownerCellRef->getOwner();
 | 
			
		||||
        owner.second = false;
 | 
			
		||||
        if (owner.first.empty())
 | 
			
		||||
        {
 | 
			
		||||
            owner.first = ownerCellRef->getFaction();
 | 
			
		||||
            owner.second = true;
 | 
			
		||||
        }
 | 
			
		||||
        Misc::StringUtils::toLower(owner.first);
 | 
			
		||||
        mStolenItems[Misc::StringUtils::lowerCase(item.getClass().getId(item))][owner] += count;
 | 
			
		||||
 | 
			
		||||
        commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -949,7 +1038,7 @@ namespace MWMechanics
 | 
			
		|||
        // NOTE: victim may be empty
 | 
			
		||||
 | 
			
		||||
        // Only player can commit crime
 | 
			
		||||
        if (player.getRefData().getHandle() != "player")
 | 
			
		||||
        if (player != MWBase::Environment::get().getWorld()->getPlayerPtr())
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        // Find all the actors within the alarm radius
 | 
			
		||||
| 
						 | 
				
			
			@ -1351,22 +1440,37 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
    int MechanicsManager::countSavedGameRecords() const
 | 
			
		||||
    {
 | 
			
		||||
        return 1; // Death counter
 | 
			
		||||
        return 1 // Death counter
 | 
			
		||||
                +1; // Stolen items
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MechanicsManager::write(ESM::ESMWriter &writer, Loading::Listener &listener) const
 | 
			
		||||
    {
 | 
			
		||||
        mActors.write(writer, listener);
 | 
			
		||||
 | 
			
		||||
        ESM::StolenItems items;
 | 
			
		||||
        items.mStolenItems = mStolenItems;
 | 
			
		||||
        writer.startRecord(ESM::REC_STLN);
 | 
			
		||||
        items.write(writer);
 | 
			
		||||
        writer.endRecord(ESM::REC_STLN);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MechanicsManager::readRecord(ESM::ESMReader &reader, uint32_t type)
 | 
			
		||||
    {
 | 
			
		||||
        mActors.readRecord(reader, type);
 | 
			
		||||
        if (type == ESM::REC_STLN)
 | 
			
		||||
        {
 | 
			
		||||
            ESM::StolenItems items;
 | 
			
		||||
            items.load(reader);
 | 
			
		||||
            mStolenItems = items.mStolenItems;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            mActors.readRecord(reader, type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MechanicsManager::clear()
 | 
			
		||||
    {
 | 
			
		||||
        mActors.clear();
 | 
			
		||||
        mStolenItems.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool MechanicsManager::isAggressive(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,11 @@ namespace MWMechanics
 | 
			
		|||
            Objects mObjects;
 | 
			
		||||
            Actors mActors;
 | 
			
		||||
 | 
			
		||||
            typedef std::pair<std::string, bool> Owner; // < Owner id, bool isFaction >
 | 
			
		||||
            typedef std::map<Owner, int> OwnerMap; // < Owner, number of stolen items with this id from this owner >
 | 
			
		||||
            typedef std::map<std::string, OwnerMap> StolenItemsMap;
 | 
			
		||||
            StolenItemsMap mStolenItems;
 | 
			
		||||
 | 
			
		||||
        public:
 | 
			
		||||
 | 
			
		||||
            void buildPlayer();
 | 
			
		||||
| 
						 | 
				
			
			@ -121,16 +126,15 @@ namespace MWMechanics
 | 
			
		|||
            /// @return false if the attack was considered a "friendly hit" and forgiven
 | 
			
		||||
            virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker);
 | 
			
		||||
            /// 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);
 | 
			
		||||
            /// @param container The container the item is in; may be empty for an item in the world
 | 
			
		||||
            virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container,
 | 
			
		||||
                                    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? Also returns fail when enemies are nearby
 | 
			
		||||
            virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed);
 | 
			
		||||
 | 
			
		||||
            /// @return is \a ptr allowed to take/use \a item or is it a crime?
 | 
			
		||||
            virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim);
 | 
			
		||||
 | 
			
		||||
            virtual void forceStateUpdate(const MWWorld::Ptr &ptr);
 | 
			
		||||
 | 
			
		||||
            virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
 | 
			
		||||
| 
						 | 
				
			
			@ -168,9 +172,21 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
            virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const;
 | 
			
		||||
 | 
			
		||||
            virtual void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer);
 | 
			
		||||
 | 
			
		||||
            /// List the owners that the player has stolen this item from (the owner can be an NPC or a faction).
 | 
			
		||||
            /// <Owner, item count>
 | 
			
		||||
            virtual std::vector<std::pair<std::string, int> > getStolenItemOwners(const std::string& itemid);
 | 
			
		||||
 | 
			
		||||
            /// Has the player stolen this item from the given owner?
 | 
			
		||||
            virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid);
 | 
			
		||||
 | 
			
		||||
        private:
 | 
			
		||||
            void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
 | 
			
		||||
                                      OffenseType type, int arg=0);
 | 
			
		||||
 | 
			
		||||
            /// @return is \a ptr allowed to take/use \a cellref or is it a crime?
 | 
			
		||||
            virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::CellRef& cellref, MWWorld::Ptr& victim);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -125,32 +125,9 @@ bool MWMechanics::NpcStats::isInFaction (const std::string& faction) const
 | 
			
		|||
    return (mFactionRank.find(Misc::StringUtils::lowerCase(faction)) != mFactionRank.end());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& class_, int usageType,
 | 
			
		||||
    int level, float extraFactor) const
 | 
			
		||||
float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const ESM::Class& class_) const
 | 
			
		||||
{
 | 
			
		||||
    if (level<0)
 | 
			
		||||
        level = static_cast<int> (getSkill (skillIndex).getBase());
 | 
			
		||||
 | 
			
		||||
    const ESM::Skill *skill =
 | 
			
		||||
        MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
 | 
			
		||||
 | 
			
		||||
    float skillFactor = 1;
 | 
			
		||||
 | 
			
		||||
    if (usageType>=4)
 | 
			
		||||
        throw std::runtime_error ("skill usage type out of range");
 | 
			
		||||
 | 
			
		||||
    if (usageType>=0)
 | 
			
		||||
    {
 | 
			
		||||
        skillFactor = skill->mData.mUseValue[usageType];
 | 
			
		||||
 | 
			
		||||
        if (skillFactor<0)
 | 
			
		||||
            throw std::runtime_error ("invalid skill gain factor");
 | 
			
		||||
 | 
			
		||||
        if (skillFactor==0)
 | 
			
		||||
            return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    skillFactor *= extraFactor;
 | 
			
		||||
    float progressRequirement = 1 + getSkill (skillIndex).getBase();
 | 
			
		||||
 | 
			
		||||
    const MWWorld::Store<ESM::GameSetting> &gmst =
 | 
			
		||||
        MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
 | 
			
		||||
| 
						 | 
				
			
			@ -173,11 +150,15 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla
 | 
			
		|||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    progressRequirement *= typeFactor;
 | 
			
		||||
 | 
			
		||||
    if (typeFactor<=0)
 | 
			
		||||
        throw std::runtime_error ("invalid skill type factor");
 | 
			
		||||
 | 
			
		||||
    float specialisationFactor = 1;
 | 
			
		||||
 | 
			
		||||
    const ESM::Skill *skill =
 | 
			
		||||
        MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
 | 
			
		||||
    if (skill->mData.mSpecialization==class_.mData.mSpecialization)
 | 
			
		||||
    {
 | 
			
		||||
        specialisationFactor = gmst.find ("fSpecialSkillBonus")->getFloat();
 | 
			
		||||
| 
						 | 
				
			
			@ -185,7 +166,9 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla
 | 
			
		|||
        if (specialisationFactor<=0)
 | 
			
		||||
            throw std::runtime_error ("invalid skill specialisation factor");
 | 
			
		||||
    }
 | 
			
		||||
    return 1.0 / ((level+1) * (1.0/skillFactor) * typeFactor * specialisationFactor);
 | 
			
		||||
    progressRequirement *= specialisationFactor;
 | 
			
		||||
 | 
			
		||||
    return progressRequirement;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType, float extraFactor)
 | 
			
		||||
| 
						 | 
				
			
			@ -194,13 +177,26 @@ void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_,
 | 
			
		|||
    if(mIsWerewolf)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    const ESM::Skill *skill =
 | 
			
		||||
        MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
 | 
			
		||||
    float skillGain = 1;
 | 
			
		||||
    if (usageType>=4)
 | 
			
		||||
        throw std::runtime_error ("skill usage type out of range");
 | 
			
		||||
    if (usageType>=0)
 | 
			
		||||
    {
 | 
			
		||||
        skillGain = skill->mData.mUseValue[usageType];
 | 
			
		||||
        if (skillGain<0)
 | 
			
		||||
            throw std::runtime_error ("invalid skill gain factor");
 | 
			
		||||
    }
 | 
			
		||||
    skillGain *= extraFactor;
 | 
			
		||||
 | 
			
		||||
    MWMechanics::SkillValue& value = getSkill (skillIndex);
 | 
			
		||||
 | 
			
		||||
    value.setProgress(value.getProgress() + getSkillGain (skillIndex, class_, usageType, -1, extraFactor));
 | 
			
		||||
    value.setProgress(value.getProgress() + skillGain);
 | 
			
		||||
 | 
			
		||||
    if (value.getProgress()>=1)
 | 
			
		||||
    if (int(value.getProgress())>=int(getSkillProgressRequirement(skillIndex, class_)))
 | 
			
		||||
    {
 | 
			
		||||
        // skill leveled up
 | 
			
		||||
        // skill levelled up
 | 
			
		||||
        increaseSkill(skillIndex, class_, false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -256,7 +252,7 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas
 | 
			
		|||
        MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", MWGui::ShowInDialogueMode_Never);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getSkill (skillIndex).setBase (base);
 | 
			
		||||
    getSkill(skillIndex).setBase (base);
 | 
			
		||||
    if (!preserveProgress)
 | 
			
		||||
        getSkill(skillIndex).setProgress(0);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -268,13 +264,15 @@ int MWMechanics::NpcStats::getLevelProgress () const
 | 
			
		|||
 | 
			
		||||
void MWMechanics::NpcStats::levelUp()
 | 
			
		||||
{
 | 
			
		||||
    mLevelProgress -= 10;
 | 
			
		||||
    for (int i=0; i<ESM::Attribute::Length; ++i)
 | 
			
		||||
        mSkillIncreases[i] = 0;
 | 
			
		||||
 | 
			
		||||
    const MWWorld::Store<ESM::GameSetting> &gmst =
 | 
			
		||||
        MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
 | 
			
		||||
 | 
			
		||||
    mLevelProgress -= gmst.find("iLevelUpTotal")->getInt();
 | 
			
		||||
    mLevelProgress = std::max(0, mLevelProgress); // might be necessary when levelup was invoked via console
 | 
			
		||||
 | 
			
		||||
    for (int i=0; i<ESM::Attribute::Length; ++i)
 | 
			
		||||
        mSkillIncreases[i] = 0;
 | 
			
		||||
 | 
			
		||||
    const int endurance = getAttribute(ESM::Attribute::Endurance).getBase();
 | 
			
		||||
 | 
			
		||||
    // "When you gain a level, in addition to increasing three primary attributes, your Health
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ namespace MWMechanics
 | 
			
		|||
    class NpcStats : public CreatureStats
 | 
			
		||||
    {
 | 
			
		||||
            int mDisposition;
 | 
			
		||||
            SkillValue mSkill[ESM::Skill::Length];
 | 
			
		||||
            SkillValue mSkill[ESM::Skill::Length]; // SkillValue.mProgress used by the player only
 | 
			
		||||
            SkillValue mWerewolfSkill[ESM::Skill::Length];
 | 
			
		||||
            int mReputation;
 | 
			
		||||
            int mCrimeId;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,11 +74,7 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
            bool isInFaction (const std::string& faction) const;
 | 
			
		||||
 | 
			
		||||
            float getSkillGain (int skillIndex, const ESM::Class& class_, int usageType = -1,
 | 
			
		||||
                int level = -1, float extraFactor=1.f) const;
 | 
			
		||||
            ///< \param usageType: Usage specific factor, specified in the respective skill record;
 | 
			
		||||
            /// -1: use a factor of 1.0 instead.
 | 
			
		||||
            /// \param level Level to base calculation on; -1: use current level.
 | 
			
		||||
            float getSkillProgressRequirement (int skillIndex, const ESM::Class& class_) const;
 | 
			
		||||
 | 
			
		||||
            void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1, float extraFactor=1.f);
 | 
			
		||||
            ///< Increase skill by usage.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
#include <components/esm/loadench.hpp>
 | 
			
		||||
#include <components/esm/loadstat.hpp>
 | 
			
		||||
#include <components/misc/resourcehelpers.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include <libs/openengine/ogre/lights.hpp>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@
 | 
			
		|||
#include <OgreHardwarePixelBuffer.h>
 | 
			
		||||
 | 
			
		||||
#include <components/loadinglistener/loadinglistener.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include <components/esm/globalmap.hpp>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
#include "animationextensions.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <limits>
 | 
			
		||||
 | 
			
		||||
#include <components/compiler/extensions.hpp>
 | 
			
		||||
#include <components/compiler/opcodes.hpp>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,24 +34,24 @@
 | 
			
		|||
namespace
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    void addToLevList(ESM::LeveledListBase* list, const std::string& itemId, int level)
 | 
			
		||||
    void addToLevList(ESM::LevelledListBase* list, const std::string& itemId, int level)
 | 
			
		||||
    {
 | 
			
		||||
        for (std::vector<ESM::LeveledListBase::LevelItem>::iterator it = list->mList.begin(); it != list->mList.end();)
 | 
			
		||||
        for (std::vector<ESM::LevelledListBase::LevelItem>::iterator it = list->mList.begin(); it != list->mList.end();)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->mLevel == level && itemId == it->mId)
 | 
			
		||||
                return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ESM::LeveledListBase::LevelItem item;
 | 
			
		||||
        ESM::LevelledListBase::LevelItem item;
 | 
			
		||||
        item.mId = itemId;
 | 
			
		||||
        item.mLevel = level;
 | 
			
		||||
        list->mList.push_back(item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void removeFromLevList(ESM::LeveledListBase* list, const std::string& itemId, int level)
 | 
			
		||||
    void removeFromLevList(ESM::LevelledListBase* list, const std::string& itemId, int level)
 | 
			
		||||
    {
 | 
			
		||||
        // level of -1 removes all items with that itemId
 | 
			
		||||
        for (std::vector<ESM::LeveledListBase::LevelItem>::iterator it = list->mList.begin(); it != list->mList.end();)
 | 
			
		||||
        for (std::vector<ESM::LevelledListBase::LevelItem>::iterator it = list->mList.begin(); it != list->mList.end();)
 | 
			
		||||
        {
 | 
			
		||||
            if (level != -1 && it->mLevel != level)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -348,29 +348,12 @@ namespace MWScript
 | 
			
		|||
 | 
			
		||||
                    MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats (ptr);
 | 
			
		||||
 | 
			
		||||
                    MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
 | 
			
		||||
 | 
			
		||||
                    assert (ref);
 | 
			
		||||
 | 
			
		||||
                    const ESM::Class& class_ =
 | 
			
		||||
                        *MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find (ref->mBase->mClass);
 | 
			
		||||
 | 
			
		||||
                    float level = stats.getSkill(mIndex).getBase();
 | 
			
		||||
                    float progress = stats.getSkill(mIndex).getProgress();
 | 
			
		||||
 | 
			
		||||
                    int newLevel = value - (stats.getSkill(mIndex).getModified() - stats.getSkill(mIndex).getBase());
 | 
			
		||||
 | 
			
		||||
                    if (newLevel<0)
 | 
			
		||||
                        newLevel = 0;
 | 
			
		||||
 | 
			
		||||
                    progress = (progress / stats.getSkillGain (mIndex, class_, -1, level))
 | 
			
		||||
                        * stats.getSkillGain (mIndex, class_, -1, newLevel);
 | 
			
		||||
 | 
			
		||||
                    if (progress>=1)
 | 
			
		||||
                        progress = 0.999999999;
 | 
			
		||||
 | 
			
		||||
                    stats.getSkill (mIndex).setBase (newLevel);
 | 
			
		||||
                    stats.getSkill (mIndex).setProgress(progress);
 | 
			
		||||
                }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -691,10 +691,10 @@ namespace MWScript
 | 
			
		|||
                    if (!ptr.getRefData().getBaseNode())
 | 
			
		||||
                        return;
 | 
			
		||||
 | 
			
		||||
                    Ogre::Vector3 worldPos = ptr.getRefData().getBaseNode()->convertLocalToWorldPosition(posChange);
 | 
			
		||||
 | 
			
		||||
                    dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(
 | 
			
		||||
                                MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x, worldPos.y, worldPos.z));
 | 
			
		||||
                    Ogre::Vector3 diff = ptr.getRefData().getBaseNode()->getOrientation() * posChange;
 | 
			
		||||
                    Ogre::Vector3 worldPos(ptr.getRefData().getPosition().pos);
 | 
			
		||||
                    worldPos += diff;
 | 
			
		||||
                    MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x, worldPos.y, worldPos.z);
 | 
			
		||||
                }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@
 | 
			
		|||
#include <OgreImage.h>
 | 
			
		||||
 | 
			
		||||
#include <boost/filesystem/fstream.hpp>
 | 
			
		||||
#include <boost/filesystem/operations.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -420,6 +421,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
 | 
			
		|||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ESM::REC_DCOU:
 | 
			
		||||
                case ESM::REC_STLN:
 | 
			
		||||
 | 
			
		||||
                    MWBase::Environment::get().getMechanicsManager()->readRecord(reader, n.val);
 | 
			
		||||
                    break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ namespace MWWorld
 | 
			
		|||
    void ActionTake::executeImp (const Ptr& actor)
 | 
			
		||||
    {
 | 
			
		||||
        MWBase::Environment::get().getMechanicsManager()->itemTaken(
 | 
			
		||||
                    actor, getTarget(), getTarget().getRefData().getCount());
 | 
			
		||||
                    actor, getTarget(), MWWorld::Ptr(), getTarget().getRefData().getCount());
 | 
			
		||||
        actor.getClass().getContainerStore (actor).add (getTarget(), getTarget().getRefData().getCount(), actor);
 | 
			
		||||
        MWBase::Environment::get().getWorld()->deleteObject (getTarget());
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,6 +117,15 @@ namespace MWWorld
 | 
			
		|||
        return mCellRef.mGlobalVariable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void CellRef::resetGlobalVariable()
 | 
			
		||||
    {
 | 
			
		||||
        if (!mCellRef.mGlobalVariable.empty())
 | 
			
		||||
        {
 | 
			
		||||
            mChanged = true;
 | 
			
		||||
            mCellRef.mGlobalVariable.erase();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void CellRef::setFactionRank(int factionRank)
 | 
			
		||||
    {
 | 
			
		||||
        if (factionRank != mCellRef.mFactionRank)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,8 @@ namespace MWWorld
 | 
			
		|||
        // Used by bed rent scripts to allow the player to use the bed for the duration of the rent.
 | 
			
		||||
        std::string getGlobalVariable() const;
 | 
			
		||||
 | 
			
		||||
        void resetGlobalVariable();
 | 
			
		||||
 | 
			
		||||
        // ID of creature trapped in this soul gem
 | 
			
		||||
        std::string getSoul() const;
 | 
			
		||||
        void setSoul(const std::string& soul);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,6 +80,8 @@ namespace MWWorld
 | 
			
		|||
            virtual std::string getId (const Ptr& ptr) const;
 | 
			
		||||
            ///< Return ID of \a ptr or throw an exception, if class does not support ID retrieval
 | 
			
		||||
            /// (default implementation: throw an exception)
 | 
			
		||||
            /// @note This function is currently redundant; the same ID can be retrieved by CellRef::getRefId.
 | 
			
		||||
            ///       Leaving it here for now in case we want to optimize later.
 | 
			
		||||
 | 
			
		||||
            virtual void insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const;
 | 
			
		||||
            virtual void insertObject(const Ptr& ptr, const std::string& mesh, MWWorld::PhysicsSystem& physics) const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -222,29 +222,22 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
 | 
			
		|||
 | 
			
		||||
    MWWorld::ContainerStoreIterator it = end();
 | 
			
		||||
 | 
			
		||||
    if (setOwner && actorPtr.getClass().isActor())
 | 
			
		||||
    // HACK: Set owner on the original item, then reset it after we have copied it
 | 
			
		||||
    // If we set the owner on the copied item, it would not stack correctly...
 | 
			
		||||
    std::string oldOwner = itemPtr.getCellRef().getOwner();
 | 
			
		||||
    if (!setOwner || actorPtr == MWBase::Environment::get().getWorld()->getPlayerPtr()) // No point in setting owner to the player - NPCs will not respect this anyway
 | 
			
		||||
    {
 | 
			
		||||
        // HACK: Set owner on the original item, then reset it after we have copied it
 | 
			
		||||
        // If we set the owner on the copied item, it would not stack correctly...
 | 
			
		||||
        std::string oldOwner = itemPtr.getCellRef().getOwner();
 | 
			
		||||
        if (actorPtr == player)
 | 
			
		||||
        {
 | 
			
		||||
            // No point in setting owner to the player - NPCs will not respect this anyway
 | 
			
		||||
            // Additionally, setting it to "player" would make those items not stack with items that don't have an owner
 | 
			
		||||
            itemPtr.getCellRef().setOwner("");
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            itemPtr.getCellRef().setOwner(actorPtr.getCellRef().getRefId());
 | 
			
		||||
 | 
			
		||||
        it = addImp(itemPtr, count);
 | 
			
		||||
 | 
			
		||||
        itemPtr.getCellRef().setOwner(oldOwner);
 | 
			
		||||
        itemPtr.getCellRef().setOwner("");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        it = addImp(itemPtr, count);
 | 
			
		||||
        itemPtr.getCellRef().setOwner(actorPtr.getCellRef().getRefId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    it = addImp(itemPtr, count);
 | 
			
		||||
 | 
			
		||||
    itemPtr.getCellRef().setOwner(oldOwner);
 | 
			
		||||
 | 
			
		||||
    // The copy of the original item we just made
 | 
			
		||||
    MWWorld::Ptr item = *it;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -258,6 +251,14 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
 | 
			
		|||
    pos.pos[1] = 0;
 | 
			
		||||
    pos.pos[2] = 0;
 | 
			
		||||
    item.getCellRef().setPosition(pos);
 | 
			
		||||
 | 
			
		||||
    // reset ownership stuff, owner was already handled above
 | 
			
		||||
    item.getCellRef().resetGlobalVariable();
 | 
			
		||||
    item.getCellRef().setFaction("");
 | 
			
		||||
    item.getCellRef().setFactionRank(-1);
 | 
			
		||||
 | 
			
		||||
    // must reset the RefNum on the copied item, so that the RefNum on the original item stays unique
 | 
			
		||||
    // maybe we should do this in the copy constructor instead?
 | 
			
		||||
    item.getCellRef().unsetRefNum(); // destroy link to content file
 | 
			
		||||
 | 
			
		||||
    std::string script = item.getClass().getScript(item);
 | 
			
		||||
| 
						 | 
				
			
			@ -399,19 +400,19 @@ 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 std::string& faction, int factionRank, const MWWorld::ESMStore& store)
 | 
			
		||||
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner)
 | 
			
		||||
{
 | 
			
		||||
    for (std::vector<ESM::ContItem>::const_iterator iter (items.mList.begin()); iter!=items.mList.end();
 | 
			
		||||
        ++iter)
 | 
			
		||||
    {
 | 
			
		||||
        std::string id = Misc::StringUtils::lowerCase(iter->mItem.toString());
 | 
			
		||||
        addInitialItem(id, owner, faction, factionRank, iter->mCount);
 | 
			
		||||
        addInitialItem(id, owner, iter->mCount);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    flagAsModified();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, const std::string& faction, int factionRank,
 | 
			
		||||
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner,
 | 
			
		||||
                                              int count, bool topLevel, const std::string& levItem)
 | 
			
		||||
{
 | 
			
		||||
    ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count);
 | 
			
		||||
| 
						 | 
				
			
			@ -423,7 +424,7 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
 | 
			
		|||
        if (topLevel && std::abs(count) > 1 && levItem->mFlags & ESM::ItemLevList::Each)
 | 
			
		||||
        {
 | 
			
		||||
            for (int i=0; i<std::abs(count); ++i)
 | 
			
		||||
                addInitialItem(id, owner, faction, factionRank, count > 0 ? 1 : -1, true, levItem->mId);
 | 
			
		||||
                addInitialItem(id, owner, count > 0 ? 1 : -1, true, levItem->mId);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -431,7 +432,7 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
 | 
			
		|||
            std::string id = MWMechanics::getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false);
 | 
			
		||||
            if (id.empty())
 | 
			
		||||
                return;
 | 
			
		||||
            addInitialItem(id, owner, faction, factionRank, count, false, levItem->mId);
 | 
			
		||||
            addInitialItem(id, owner, count, false, levItem->mId);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			@ -447,13 +448,11 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
 | 
			
		|||
        count = std::abs(count);
 | 
			
		||||
 | 
			
		||||
        ref.getPtr().getCellRef().setOwner(owner);
 | 
			
		||||
        ref.getPtr().getCellRef().setFaction(faction);
 | 
			
		||||
        ref.getPtr().getCellRef().setFactionRank(factionRank);
 | 
			
		||||
        addImp (ref.getPtr(), count);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner, const std::string& faction, int factionRank)
 | 
			
		||||
void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner)
 | 
			
		||||
{
 | 
			
		||||
    // Remove the items already spawned by levelled items that will restock
 | 
			
		||||
    for (std::map<std::string, int>::iterator it = mLevelledItemMap.begin(); it != mLevelledItemMap.end(); ++it)
 | 
			
		||||
| 
						 | 
				
			
			@ -472,13 +471,13 @@ void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MW
 | 
			
		|||
 | 
			
		||||
        if (MWBase::Environment::get().getWorld()->getStore().get<ESM::ItemLevList>().search(it->mItem.toString()))
 | 
			
		||||
        {
 | 
			
		||||
            addInitialItem(item, owner, faction, factionRank, it->mCount, true);
 | 
			
		||||
            addInitialItem(item, owner, it->mCount, true);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            int currentCount = count(item);
 | 
			
		||||
            if (currentCount < std::abs(it->mCount))
 | 
			
		||||
                addInitialItem(item, owner, faction, factionRank, std::abs(it->mCount) - currentCount, true);
 | 
			
		||||
                addInitialItem(item, owner, std::abs(it->mCount) - currentCount, true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    flagAsModified();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,7 +75,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 factionRank, int count, bool topLevel=true, const std::string& levItem = "");
 | 
			
		||||
            void addInitialItem (const std::string& id, const std::string& owner, int count, bool topLevel=true, const std::string& levItem = "");
 | 
			
		||||
 | 
			
		||||
            template<typename T>
 | 
			
		||||
            ContainerStoreIterator getState (CellRefList<T>& collection,
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ namespace MWWorld
 | 
			
		|||
            /// \attention Do not add items to an existing stack by increasing the count instead of
 | 
			
		||||
            /// calling this function!
 | 
			
		||||
            ///
 | 
			
		||||
            /// @param setOwner Set the owner of the added item to \a actorPtr?
 | 
			
		||||
            /// @param setOwner Set the owner of the added item to \a actorPtr? If false, the owner is reset to "".
 | 
			
		||||
            ///
 | 
			
		||||
            /// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to the newly inserted item.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -151,10 +151,10 @@ namespace MWWorld
 | 
			
		|||
            virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2);
 | 
			
		||||
            ///< @return true if the two specified objects can stack with each other
 | 
			
		||||
 | 
			
		||||
            void fill (const ESM::InventoryList& items, const std::string& owner, const std::string& faction, int factionRank, const MWWorld::ESMStore& store);
 | 
			
		||||
            void fill (const ESM::InventoryList& items, const std::string& owner);
 | 
			
		||||
            ///< Insert items into *this.
 | 
			
		||||
 | 
			
		||||
            void restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner, const std::string& faction, int factionRank);
 | 
			
		||||
            void restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner);
 | 
			
		||||
 | 
			
		||||
            virtual void clear();
 | 
			
		||||
            ///< Empty container.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,12 +133,11 @@ 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 or weapon item is added, but not for the player nor werewolves
 | 
			
		||||
    if ((actorPtr.getRefData().getHandle() != "player")
 | 
			
		||||
            && !(actorPtr.getClass().isNpc() && actorPtr.getClass().getNpcStats(actorPtr).isWerewolf())
 | 
			
		||||
            && !actorPtr.getClass().getCreatureStats(actorPtr).isDead())
 | 
			
		||||
    if (actorPtr.getRefData().getHandle() != "player"
 | 
			
		||||
            && !(actorPtr.getClass().isNpc() && actorPtr.getClass().getNpcStats(actorPtr).isWerewolf()))
 | 
			
		||||
    {
 | 
			
		||||
        std::string type = itemPtr.getTypeName();
 | 
			
		||||
        if ((type == typeid(ESM::Armor).name()) || (type == typeid(ESM::Clothing).name()) || (type == typeid(ESM::Weapon).name()))
 | 
			
		||||
        if (type == typeid(ESM::Armor).name() || type == typeid(ESM::Clothing).name())
 | 
			
		||||
            autoEquip(actorPtr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -234,7 +233,9 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
 | 
			
		|||
        // ...unless this is a companion, he should always equip items given to him.
 | 
			
		||||
        if (!Misc::StringUtils::ciEqual(test.getCellRef().getOwner(), actor.getCellRef().getRefId()) &&
 | 
			
		||||
                (actor.getClass().getScript(actor).empty() ||
 | 
			
		||||
                !actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion")))
 | 
			
		||||
                !actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion"))
 | 
			
		||||
                && !actor.getClass().getCreatureStats(actor).isDead() // Corpses can be dressed up by the player as desired
 | 
			
		||||
                )
 | 
			
		||||
        {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -506,8 +507,7 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor
 | 
			
		|||
            && !(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()))
 | 
			
		||||
    {
 | 
			
		||||
        std::string type = item.getTypeName();
 | 
			
		||||
        if (((type == typeid(ESM::Armor).name()) || (type == typeid(ESM::Clothing).name()))
 | 
			
		||||
                && !actor.getClass().getCreatureStats(actor).isDead())
 | 
			
		||||
        if (type == typeid(ESM::Armor).name() || type == typeid(ESM::Clothing).name())
 | 
			
		||||
            autoEquip(actor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
 | 
			
		||||
#include "livecellref.hpp"
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <components/esm/objectstate.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -260,9 +260,20 @@ namespace MWWorld
 | 
			
		|||
                mCellStore = world.getExterior(0,0);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!player.mBirthsign.empty() &&
 | 
			
		||||
                !world.getStore().get<ESM::BirthSign>().search (player.mBirthsign))
 | 
			
		||||
                throw std::runtime_error ("invalid player state record (birthsign)");
 | 
			
		||||
            if (!player.mBirthsign.empty())
 | 
			
		||||
            {
 | 
			
		||||
                const ESM::BirthSign* sign = world.getStore().get<ESM::BirthSign>().search (player.mBirthsign);
 | 
			
		||||
                if (!sign)
 | 
			
		||||
                    throw std::runtime_error ("invalid player state record (birthsign does not exist)");
 | 
			
		||||
 | 
			
		||||
                // To handle the case where a birth sign was edited in between play sessions (does not yet handle removing the old spells)
 | 
			
		||||
                // Also needed for ess-imported savegames which do not specify the birtsign spells in the player's spell list.
 | 
			
		||||
                for (std::vector<std::string>::const_iterator iter (sign->mPowers.mList.begin());
 | 
			
		||||
                    iter!=sign->mPowers.mList.end(); ++iter)
 | 
			
		||||
                {
 | 
			
		||||
                    getPlayer().getClass().getCreatureStats(getPlayer()).getSpells().add (*iter);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            mCurrentCrimeId = player.mCurrentCrimeId;
 | 
			
		||||
            mPaidCrimeId = player.mPaidCrimeId;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2988,18 +2988,10 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
        if (!closestChest.isEmpty()) //Found a close chest
 | 
			
		||||
        {
 | 
			
		||||
            ContainerStore& store = ptr.getClass().getContainerStore(ptr);
 | 
			
		||||
            for (ContainerStoreIterator it = store.begin(); it != store.end(); ++it) //Move all stolen stuff into chest
 | 
			
		||||
            {
 | 
			
		||||
                MWWorld::Ptr dummy;
 | 
			
		||||
                if (!MWBase::Environment::get().getMechanicsManager()->isAllowedToUse(getPlayerPtr(), *it, dummy))
 | 
			
		||||
                {
 | 
			
		||||
                    closestChest.getClass().getContainerStore(closestChest).add(*it, it->getRefData().getCount(), closestChest);
 | 
			
		||||
                    store.remove(*it, it->getRefData().getCount(), ptr);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            closestChest.getClass().lock(closestChest,50);
 | 
			
		||||
            MWBase::Environment::get().getMechanicsManager()->confiscateStolenItems(ptr, closestChest);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            std::cerr << "Failed to confiscate items: no stolen_goods container found" << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void World::goToJail()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,7 +63,7 @@ add_component_dir (esm
 | 
			
		|||
    loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
 | 
			
		||||
    savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap inventorystate containerstate npcstate creaturestate dialoguestate statstate
 | 
			
		||||
    npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile
 | 
			
		||||
    aisequence magiceffects util custommarkerstate
 | 
			
		||||
    aisequence magiceffects util custommarkerstate stolenitems
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
add_component_dir (esmterrain
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,8 +15,7 @@ ContentSelectorModel::ContentModel::ContentModel(QObject *parent, QIcon warningI
 | 
			
		|||
    mMimeType ("application/omwcontent"),
 | 
			
		||||
    mMimeTypes (QStringList() << mMimeType),
 | 
			
		||||
    mColumnCount (1),
 | 
			
		||||
    mDragDropFlags (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled),
 | 
			
		||||
    mDropActions (Qt::CopyAction | Qt::MoveAction)
 | 
			
		||||
    mDropActions (Qt::MoveAction)
 | 
			
		||||
{
 | 
			
		||||
    setEncoding ("win1252");
 | 
			
		||||
    uncheckAll();
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +103,7 @@ QModelIndex ContentSelectorModel::ContentModel::indexFromItem(const EsmFile *ite
 | 
			
		|||
Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index) const
 | 
			
		||||
{
 | 
			
		||||
    if (!index.isValid())
 | 
			
		||||
        return Qt::NoItemFlags;
 | 
			
		||||
        return Qt::ItemIsDropEnabled;
 | 
			
		||||
 | 
			
		||||
    const EsmFile *file = item(index.row());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +151,7 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index
 | 
			
		|||
    if (gamefileChecked)
 | 
			
		||||
    {
 | 
			
		||||
        if (allDependenciesFound)
 | 
			
		||||
            returnFlags = returnFlags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | mDragDropFlags;
 | 
			
		||||
            returnFlags = returnFlags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
 | 
			
		||||
        else
 | 
			
		||||
            returnFlags = Qt::ItemIsSelectable;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -443,11 +442,6 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path)
 | 
			
		|||
    filters << "*.esp" << "*.esm" << "*.omwgame" << "*.omwaddon";
 | 
			
		||||
    dir.setNameFilters(filters);
 | 
			
		||||
 | 
			
		||||
    QTextCodec *codec = QTextCodec::codecForName("UTF8");
 | 
			
		||||
 | 
			
		||||
    // Create a decoder for non-latin characters in esx metadata
 | 
			
		||||
    QTextDecoder *decoder = codec->makeDecoder();
 | 
			
		||||
 | 
			
		||||
    foreach (const QString &path, dir.entryList())
 | 
			
		||||
    {
 | 
			
		||||
        QFileInfo info(dir.absoluteFilePath(path));
 | 
			
		||||
| 
						 | 
				
			
			@ -467,11 +461,11 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path)
 | 
			
		|||
            foreach (const ESM::Header::MasterData &item, fileReader.getGameFiles())
 | 
			
		||||
                file->addGameFile(QString::fromStdString(item.name));
 | 
			
		||||
 | 
			
		||||
            file->setAuthor     (decoder->toUnicode(fileReader.getAuthor().c_str()));
 | 
			
		||||
            file->setAuthor     (QString::fromUtf8(fileReader.getAuthor().c_str()));
 | 
			
		||||
            file->setDate       (info.lastModified());
 | 
			
		||||
            file->setFormat     (fileReader.getFormat());
 | 
			
		||||
            file->setFilePath       (info.absoluteFilePath());
 | 
			
		||||
            file->setDescription(decoder->toUnicode(fileReader.getDesc().c_str()));
 | 
			
		||||
            file->setDescription(QString::fromUtf8(fileReader.getDesc().c_str()));
 | 
			
		||||
 | 
			
		||||
            // Put the file in the table
 | 
			
		||||
            addFile(file);
 | 
			
		||||
| 
						 | 
				
			
			@ -484,8 +478,6 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path)
 | 
			
		|||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    delete decoder;
 | 
			
		||||
 | 
			
		||||
    sortFiles();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,7 +89,6 @@ namespace ContentSelectorModel
 | 
			
		|||
        QString mMimeType;
 | 
			
		||||
        QStringList mMimeTypes;
 | 
			
		||||
        int mColumnCount;
 | 
			
		||||
        Qt::ItemFlags mDragDropFlags;
 | 
			
		||||
        Qt::DropActions mDropActions;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,8 @@
 | 
			
		|||
ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) :
 | 
			
		||||
    QObject(parent)
 | 
			
		||||
{
 | 
			
		||||
    ui.setupUi (parent);
 | 
			
		||||
    ui.setupUi(parent);
 | 
			
		||||
    ui.addonView->setDragDropMode(QAbstractItemView::InternalMove);
 | 
			
		||||
 | 
			
		||||
    buildContentModel();
 | 
			
		||||
    buildGameFileView();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,6 +117,7 @@ enum RecNameInts
 | 
			
		|||
    REC_MARK = FourCC<'M','A','R','K'>::value,
 | 
			
		||||
    REC_ENAB = FourCC<'E','N','A','B'>::value,
 | 
			
		||||
    REC_CAM_ = FourCC<'C','A','M','_'>::value,
 | 
			
		||||
    REC_STLN = FourCC<'S','T','L','N'>::value,
 | 
			
		||||
 | 
			
		||||
    // format 1
 | 
			
		||||
    REC_FILT = FourCC<'F','I','L','T'>::value,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@
 | 
			
		|||
namespace ESM
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
void LeveledListBase::load(ESMReader &esm)
 | 
			
		||||
void LevelledListBase::load(ESMReader &esm)
 | 
			
		||||
{
 | 
			
		||||
    esm.getHNT(mFlags, "DATA");
 | 
			
		||||
    esm.getHNT(mChanceNone, "NNAM");
 | 
			
		||||
| 
						 | 
				
			
			@ -19,13 +19,17 @@ void LeveledListBase::load(ESMReader &esm)
 | 
			
		|||
        mList.resize(len);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        esm.skipRecord();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: Merge with an existing lists here. This can be done
 | 
			
		||||
    // simply by adding the lists together, making sure that they are
 | 
			
		||||
    // sorted by level. A better way might be to exclude repeated
 | 
			
		||||
    // items. Also, some times we don't want to merge lists, just
 | 
			
		||||
    // overwrite. Figure out a way to give the user this option.
 | 
			
		||||
    // If this levelled list was already loaded by a previous content file,
 | 
			
		||||
    // we overwrite the list. Merging lists should probably be left to external tools,
 | 
			
		||||
    // with the limited amount of information there is in the records, all merging methods
 | 
			
		||||
    // will be flawed in some way. For a proper fix the ESM format would have to be changed
 | 
			
		||||
    // to actually track list changes instead of including the whole list for every file
 | 
			
		||||
    // that does something with that list.
 | 
			
		||||
 | 
			
		||||
    for (size_t i = 0; i < mList.size(); i++)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +38,7 @@ void LeveledListBase::load(ESMReader &esm)
 | 
			
		|||
        esm.getHNT(li.mLevel, "INTV");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
void LeveledListBase::save(ESMWriter &esm) const
 | 
			
		||||
void LevelledListBase::save(ESMWriter &esm) const
 | 
			
		||||
{
 | 
			
		||||
    esm.writeHNT("DATA", mFlags);
 | 
			
		||||
    esm.writeHNT("NNAM", mChanceNone);
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +51,7 @@ void LeveledListBase::save(ESMWriter &esm) const
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    void LeveledListBase::blank()
 | 
			
		||||
    void LevelledListBase::blank()
 | 
			
		||||
    {
 | 
			
		||||
        mFlags = 0;
 | 
			
		||||
        mChanceNone = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,14 +11,14 @@ class ESMReader;
 | 
			
		|||
class ESMWriter;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Leveled lists. Since these have identical layout, I only bothered
 | 
			
		||||
 * Levelled lists. Since these have identical layout, I only bothered
 | 
			
		||||
 * to implement it once.
 | 
			
		||||
 *
 | 
			
		||||
 * We should later implement the ability to merge leveled lists from
 | 
			
		||||
 * We should later implement the ability to merge levelled lists from
 | 
			
		||||
 * several files.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct LeveledListBase
 | 
			
		||||
struct LevelledListBase
 | 
			
		||||
{
 | 
			
		||||
    int mFlags;
 | 
			
		||||
    unsigned char mChanceNone; // Chance that none are selected (0-100)
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ struct LeveledListBase
 | 
			
		|||
    ///< Set record to default state (does not touch the ID).
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CreatureLevList: LeveledListBase
 | 
			
		||||
struct CreatureLevList: LevelledListBase
 | 
			
		||||
{
 | 
			
		||||
    static unsigned int sRecordId;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ struct CreatureLevList: LeveledListBase
 | 
			
		|||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ItemLevList: LeveledListBase
 | 
			
		||||
struct ItemLevList: LevelledListBase
 | 
			
		||||
{
 | 
			
		||||
    static unsigned int sRecordId;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ struct ItemLevList: LeveledListBase
 | 
			
		|||
                          // list is instantiated, instead of
 | 
			
		||||
                          // giving several identical items
 | 
			
		||||
                          // (used when a container has more
 | 
			
		||||
                          // than one instance of one leveled
 | 
			
		||||
                          // than one instance of one levelled
 | 
			
		||||
                          // list.)
 | 
			
		||||
        AllLevels = 0x02  // Calculate from all levels <= player
 | 
			
		||||
                          // level, not just the closest below
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										47
									
								
								components/esm/stolenitems.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								components/esm/stolenitems.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,47 @@
 | 
			
		|||
#include "stolenitems.hpp"
 | 
			
		||||
 | 
			
		||||
#include <components/esm/esmreader.hpp>
 | 
			
		||||
#include <components/esm/esmwriter.hpp>
 | 
			
		||||
 | 
			
		||||
namespace ESM
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    void StolenItems::write(ESMWriter &esm) const
 | 
			
		||||
    {
 | 
			
		||||
        for (StolenItemsMap::const_iterator it = mStolenItems.begin(); it != mStolenItems.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            esm.writeHNString("NAME", it->first);
 | 
			
		||||
            for (std::map<std::pair<std::string, bool>, int>::const_iterator ownerIt = it->second.begin();
 | 
			
		||||
                 ownerIt != it->second.end(); ++ownerIt)
 | 
			
		||||
            {
 | 
			
		||||
                if (ownerIt->first.second)
 | 
			
		||||
                    esm.writeHNString("FNAM", ownerIt->first.first);
 | 
			
		||||
                else
 | 
			
		||||
                    esm.writeHNString("ONAM", ownerIt->first.first);
 | 
			
		||||
                esm.writeHNT("COUN", ownerIt->second);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void StolenItems::load(ESMReader &esm)
 | 
			
		||||
    {
 | 
			
		||||
        while (esm.isNextSub("NAME"))
 | 
			
		||||
        {
 | 
			
		||||
            std::string itemid = esm.getHString();
 | 
			
		||||
 | 
			
		||||
            std::map<std::pair<std::string, bool>, int> ownerMap;
 | 
			
		||||
            while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
 | 
			
		||||
            {
 | 
			
		||||
                std::string subname = esm.retSubName().toString();
 | 
			
		||||
                std::string owner = esm.getHString();
 | 
			
		||||
                bool isFaction = (subname == "FNAM");
 | 
			
		||||
                int count;
 | 
			
		||||
                esm.getHNT(count, "COUN");
 | 
			
		||||
                ownerMap.insert(std::make_pair(std::make_pair(owner, isFaction), count));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            mStolenItems[itemid] = ownerMap;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								components/esm/stolenitems.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								components/esm/stolenitems.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
#ifndef OPENMW_COMPONENTS_ESM_STOLENITEMS_H
 | 
			
		||||
#define OPENMW_COMPONENTS_ESM_STOLENITEMS_H
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace ESM
 | 
			
		||||
{
 | 
			
		||||
    class ESMReader;
 | 
			
		||||
    class ESMWriter;
 | 
			
		||||
 | 
			
		||||
    // format 0, saved games only
 | 
			
		||||
    struct StolenItems
 | 
			
		||||
    {
 | 
			
		||||
        typedef std::map<std::string, std::map<std::pair<std::string, bool>, int> > StolenItemsMap;
 | 
			
		||||
        StolenItemsMap mStolenItems;
 | 
			
		||||
 | 
			
		||||
        void load(ESM::ESMReader& esm);
 | 
			
		||||
        void write(ESM::ESMWriter& esm) const;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,95 +1,144 @@
 | 
			
		|||
#include "settings.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <boost/filesystem/path.hpp>
 | 
			
		||||
#include <boost/filesystem/fstream.hpp>
 | 
			
		||||
 | 
			
		||||
#include <OgreResourceGroupManager.h>
 | 
			
		||||
#include <OgreStringConverter.h>
 | 
			
		||||
#include <OgreDataStream.h>
 | 
			
		||||
 | 
			
		||||
#include <components/files/constrainedfiledatastream.hpp>
 | 
			
		||||
#include <boost/filesystem/fstream.hpp>
 | 
			
		||||
#include <boost/filesystem/path.hpp>
 | 
			
		||||
#include <boost/algorithm/string.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Settings;
 | 
			
		||||
namespace Settings
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace bfs = boost::filesystem;
 | 
			
		||||
 | 
			
		||||
Ogre::ConfigFile Manager::mFile = Ogre::ConfigFile();
 | 
			
		||||
Ogre::ConfigFile Manager::mDefaultFile = Ogre::ConfigFile();
 | 
			
		||||
CategorySettingValueMap Manager::mDefaultSettings = CategorySettingValueMap();
 | 
			
		||||
CategorySettingValueMap Manager::mUserSettings = CategorySettingValueMap();
 | 
			
		||||
CategorySettingVector Manager::mChangedSettings = CategorySettingVector();
 | 
			
		||||
CategorySettingValueMap Manager::mNewSettings = CategorySettingValueMap();
 | 
			
		||||
 | 
			
		||||
void Manager::loadUser (const std::string& file)
 | 
			
		||||
 | 
			
		||||
class SettingsFileParser
 | 
			
		||||
{
 | 
			
		||||
    Ogre::DataStreamPtr stream = openConstrainedFileDataStream(file.c_str());
 | 
			
		||||
    mFile.load(stream);
 | 
			
		||||
}
 | 
			
		||||
public:
 | 
			
		||||
    SettingsFileParser() : mLine(0) {}
 | 
			
		||||
 | 
			
		||||
void Manager::loadDefault (const std::string& file)
 | 
			
		||||
{
 | 
			
		||||
    Ogre::DataStreamPtr stream = openConstrainedFileDataStream(file.c_str());
 | 
			
		||||
    mDefaultFile.load(stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Manager::saveUser(const std::string& file)
 | 
			
		||||
{
 | 
			
		||||
    bfs::ofstream fout((bfs::path(file)));
 | 
			
		||||
 | 
			
		||||
    Ogre::ConfigFile::SectionIterator seci = mFile.getSectionIterator();
 | 
			
		||||
 | 
			
		||||
    while (seci.hasMoreElements())
 | 
			
		||||
    void loadSettingsFile (const std::string& file, CategorySettingValueMap& settings)
 | 
			
		||||
    {
 | 
			
		||||
        Ogre::String sectionName = seci.peekNextKey();
 | 
			
		||||
 | 
			
		||||
        if (sectionName.length() > 0)
 | 
			
		||||
            fout << '\n' << '[' << seci.peekNextKey() << ']' << '\n';
 | 
			
		||||
 | 
			
		||||
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
 | 
			
		||||
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
 | 
			
		||||
        for (i = settings->begin(); i != settings->end(); ++i)
 | 
			
		||||
        mFile = file;
 | 
			
		||||
        boost::filesystem::ifstream stream;
 | 
			
		||||
        stream.open(boost::filesystem::path(file));
 | 
			
		||||
        std::string currentCategory;
 | 
			
		||||
        mLine = 0;
 | 
			
		||||
        while (!stream.eof() && !stream.fail())
 | 
			
		||||
        {
 | 
			
		||||
            fout << i->first.c_str() << " = " << i->second.c_str() << '\n';
 | 
			
		||||
        }
 | 
			
		||||
            ++mLine;
 | 
			
		||||
            std::string line;
 | 
			
		||||
            std::getline( stream, line );
 | 
			
		||||
 | 
			
		||||
        CategorySettingValueMap::iterator it = mNewSettings.begin();
 | 
			
		||||
        while (it != mNewSettings.end())
 | 
			
		||||
        {
 | 
			
		||||
            if (it->first.first == sectionName)
 | 
			
		||||
            size_t i = 0;
 | 
			
		||||
            if (!skipWhiteSpace(i, line))
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (line[i] == '#') // skip comment
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (line[i] == '[')
 | 
			
		||||
            {
 | 
			
		||||
                fout << it->first.second << " = " << it->second << '\n';
 | 
			
		||||
                mNewSettings.erase(it++);
 | 
			
		||||
                size_t end = line.find(']', i);
 | 
			
		||||
                if (end == std::string::npos)
 | 
			
		||||
                    fail("unterminated category");
 | 
			
		||||
 | 
			
		||||
                currentCategory = line.substr(i+1, end - (i+1));
 | 
			
		||||
                boost::algorithm::trim(currentCategory);
 | 
			
		||||
                i = end+1;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                ++it;
 | 
			
		||||
 | 
			
		||||
            if (!skipWhiteSpace(i, line))
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (currentCategory.empty())
 | 
			
		||||
                fail("empty category name");
 | 
			
		||||
 | 
			
		||||
            size_t settingEnd = line.find('=', i);
 | 
			
		||||
            if (settingEnd == std::string::npos)
 | 
			
		||||
                fail("unterminated setting name");
 | 
			
		||||
 | 
			
		||||
            std::string setting = line.substr(i, (settingEnd-i));
 | 
			
		||||
            boost::algorithm::trim(setting);
 | 
			
		||||
 | 
			
		||||
            size_t valueBegin = settingEnd+1;
 | 
			
		||||
            std::string value = line.substr(valueBegin);
 | 
			
		||||
            boost::algorithm::trim(value);
 | 
			
		||||
 | 
			
		||||
            if (settings.insert(std::make_pair(std::make_pair(currentCategory, setting), value)).second == false)
 | 
			
		||||
                fail(std::string("duplicate setting: [" + currentCategory + "] " + setting));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string category = "";
 | 
			
		||||
    for (CategorySettingValueMap::iterator it = mNewSettings.begin();
 | 
			
		||||
            it != mNewSettings.end(); ++it)
 | 
			
		||||
private:
 | 
			
		||||
    /// Increment i until it longer points to a whitespace character
 | 
			
		||||
    /// in the string or has reached the end of the string.
 | 
			
		||||
    /// @return false if we have reached the end of the string
 | 
			
		||||
    bool skipWhiteSpace(size_t& i, std::string& str)
 | 
			
		||||
    {
 | 
			
		||||
        if (category != it->first.first)
 | 
			
		||||
        while (i < str.size() && std::isspace(str[i], std::locale::classic()))
 | 
			
		||||
        {
 | 
			
		||||
            category = it->first.first;
 | 
			
		||||
            fout << '\n' << '[' << category << ']' << '\n';
 | 
			
		||||
            ++i;
 | 
			
		||||
        }
 | 
			
		||||
        fout << it->first.second << " = " << it->second << '\n';
 | 
			
		||||
        return i < str.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fout.close();
 | 
			
		||||
    void fail(const std::string& message)
 | 
			
		||||
    {
 | 
			
		||||
        std::stringstream error;
 | 
			
		||||
        error << "Error on line " << mLine << " in " << mFile << ":\n" << message;
 | 
			
		||||
        throw std::runtime_error(error.str());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string mFile;
 | 
			
		||||
    int mLine;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void Manager::loadDefault(const std::string &file)
 | 
			
		||||
{
 | 
			
		||||
    SettingsFileParser parser;
 | 
			
		||||
    parser.loadSettingsFile(file, mDefaultSettings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Manager::getString (const std::string& setting, const std::string& category)
 | 
			
		||||
void Manager::loadUser(const std::string &file)
 | 
			
		||||
{
 | 
			
		||||
    if (mNewSettings.find(std::make_pair(category, setting)) != mNewSettings.end())
 | 
			
		||||
        return mNewSettings[std::make_pair(category, setting)];
 | 
			
		||||
    SettingsFileParser parser;
 | 
			
		||||
    parser.loadSettingsFile(file, mUserSettings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    std::string defaultval = mDefaultFile.getSetting(setting, category, "NOTFOUND");
 | 
			
		||||
    std::string val = mFile.getSetting(setting, category, defaultval);
 | 
			
		||||
void Manager::saveUser(const std::string &file)
 | 
			
		||||
{
 | 
			
		||||
    boost::filesystem::ofstream stream;
 | 
			
		||||
    stream.open(boost::filesystem::path(file));
 | 
			
		||||
    std::string currentCategory;
 | 
			
		||||
    for (CategorySettingValueMap::iterator it = mUserSettings.begin(); it != mUserSettings.end(); ++it)
 | 
			
		||||
    {
 | 
			
		||||
        if (it->first.first != currentCategory)
 | 
			
		||||
        {
 | 
			
		||||
            currentCategory = it->first.first;
 | 
			
		||||
            stream << "\n[" << currentCategory << "]\n";
 | 
			
		||||
        }
 | 
			
		||||
        stream << it->first.second << " = " << it->second << "\n";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    if (val == "NOTFOUND")
 | 
			
		||||
        throw std::runtime_error("Trying to retrieve a non-existing setting: " + setting + " Make sure the settings-default.cfg file was properly installed.");
 | 
			
		||||
    return val;
 | 
			
		||||
std::string Manager::getString(const std::string &setting, const std::string &category)
 | 
			
		||||
{
 | 
			
		||||
    CategorySettingValueMap::key_type key = std::make_pair(category, setting);
 | 
			
		||||
    CategorySettingValueMap::iterator it = mUserSettings.find(key);
 | 
			
		||||
    if (it != mUserSettings.end())
 | 
			
		||||
        return it->second;
 | 
			
		||||
 | 
			
		||||
    it = mDefaultSettings.find(key);
 | 
			
		||||
    if (it != mDefaultSettings.end())
 | 
			
		||||
        return it->second;
 | 
			
		||||
 | 
			
		||||
    throw std::runtime_error(std::string("Trying to retrieve a non-existing setting: ") + setting
 | 
			
		||||
                             + ".\nMake sure the settings-default.cfg file file was properly installed.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float Manager::getFloat (const std::string& setting, const std::string& category)
 | 
			
		||||
| 
						 | 
				
			
			@ -107,51 +156,20 @@ bool Manager::getBool (const std::string& setting, const std::string& category)
 | 
			
		|||
    return Ogre::StringConverter::parseBool( getString(setting, category) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Manager::setString (const std::string& setting, const std::string& category, const std::string& value)
 | 
			
		||||
void Manager::setString(const std::string &setting, const std::string &category, const std::string &value)
 | 
			
		||||
{
 | 
			
		||||
    CategorySetting s = std::make_pair(category, setting);
 | 
			
		||||
    CategorySettingValueMap::key_type key = std::make_pair(category, setting);
 | 
			
		||||
 | 
			
		||||
    bool found=false;
 | 
			
		||||
    try
 | 
			
		||||
    CategorySettingValueMap::iterator found = mUserSettings.find(key);
 | 
			
		||||
    if (found != mUserSettings.end())
 | 
			
		||||
    {
 | 
			
		||||
        Ogre::ConfigFile::SettingsIterator it = mFile.getSettingsIterator(category);
 | 
			
		||||
        while (it.hasMoreElements())
 | 
			
		||||
        {
 | 
			
		||||
            Ogre::ConfigFile::SettingsMultiMap::iterator i = it.current();
 | 
			
		||||
 | 
			
		||||
            if ((*i).first == setting)
 | 
			
		||||
            {
 | 
			
		||||
                if ((*i).second != value)
 | 
			
		||||
                {
 | 
			
		||||
                    mChangedSettings.push_back(std::make_pair(category, setting));
 | 
			
		||||
                    (*i).second = value;
 | 
			
		||||
                }
 | 
			
		||||
                found = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            it.getNext();
 | 
			
		||||
        }
 | 
			
		||||
        if (found->second == value)
 | 
			
		||||
            return;
 | 
			
		||||
    }
 | 
			
		||||
    catch (Ogre::Exception&)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    if (!found)
 | 
			
		||||
    {
 | 
			
		||||
        if (mNewSettings.find(s) != mNewSettings.end())
 | 
			
		||||
        {
 | 
			
		||||
            if (mNewSettings[s] != value)
 | 
			
		||||
            {
 | 
			
		||||
                mChangedSettings.push_back(std::make_pair(category, setting));
 | 
			
		||||
                mNewSettings[s] = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (mDefaultFile.getSetting(setting, category) != value)
 | 
			
		||||
                mChangedSettings.push_back(std::make_pair(category, setting));
 | 
			
		||||
            mNewSettings[s] = value;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    mUserSettings[key] = value;
 | 
			
		||||
 | 
			
		||||
    mChangedSettings.insert(key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Manager::setInt (const std::string& setting, const std::string& category, const int value)
 | 
			
		||||
| 
						 | 
				
			
			@ -159,12 +177,12 @@ void Manager::setInt (const std::string& setting, const std::string& category, c
 | 
			
		|||
    setString(setting, category, Ogre::StringConverter::toString(value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Manager::setFloat (const std::string& setting, const std::string& category, const float value)
 | 
			
		||||
void Manager::setFloat (const std::string &setting, const std::string &category, const float value)
 | 
			
		||||
{
 | 
			
		||||
    setString(setting, category, Ogre::StringConverter::toString(value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Manager::setBool (const std::string& setting, const std::string& category, const bool value)
 | 
			
		||||
void Manager::setBool(const std::string &setting, const std::string &category, const bool value)
 | 
			
		||||
{
 | 
			
		||||
    setString(setting, category, Ogre::StringConverter::toString(value));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -175,3 +193,5 @@ const CategorySettingVector Manager::apply()
 | 
			
		|||
    mChangedSettings.clear();
 | 
			
		||||
    return vec;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,14 @@
 | 
			
		|||
#ifndef COMPONENTS_SETTINGS_H
 | 
			
		||||
#define COMPONENTS_SETTINGS_H
 | 
			
		||||
 | 
			
		||||
#include <OgreConfigFile.h>
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace Settings
 | 
			
		||||
{
 | 
			
		||||
    typedef std::pair < std::string, std::string > CategorySetting; 
 | 
			
		||||
    typedef std::vector< std::pair<std::string, std::string> > CategorySettingVector;
 | 
			
		||||
    typedef std::set< std::pair<std::string, std::string> > CategorySettingVector;
 | 
			
		||||
    typedef std::map < CategorySetting, std::string > CategorySettingValueMap;
 | 
			
		||||
 | 
			
		||||
    ///
 | 
			
		||||
| 
						 | 
				
			
			@ -15,15 +17,12 @@ namespace Settings
 | 
			
		|||
    class Manager
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        static Ogre::ConfigFile mFile;
 | 
			
		||||
        static Ogre::ConfigFile mDefaultFile;
 | 
			
		||||
        static CategorySettingValueMap mDefaultSettings;
 | 
			
		||||
        static CategorySettingValueMap mUserSettings;
 | 
			
		||||
 | 
			
		||||
        static CategorySettingVector mChangedSettings;
 | 
			
		||||
        ///< tracks all the settings that were changed since the last apply() call
 | 
			
		||||
 | 
			
		||||
        static CategorySettingValueMap mNewSettings;
 | 
			
		||||
        ///< tracks all the settings that are in the default file, but not in user file yet
 | 
			
		||||
 | 
			
		||||
        void loadDefault (const std::string& file);
 | 
			
		||||
        ///< load file as the default settings (can be overridden by user settings)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,7 +98,6 @@ namespace Terrain
 | 
			
		|||
        DefaultWorld* getTerrain() { return mTerrain; }
 | 
			
		||||
 | 
			
		||||
        /// Adjust LODs for the given camera position, possibly splitting up chunks or merging them.
 | 
			
		||||
        /// @param force Always choose to render this node, even if not the perfect LOD.
 | 
			
		||||
        /// @return Did we (or all of our children) choose to render?
 | 
			
		||||
        bool update (const Ogre::Vector3& cameraPos);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,7 +123,6 @@ namespace Terrain
 | 
			
		|||
        /// call this method on their children.
 | 
			
		||||
        /// @note Do not call this before World::areLayersLoaded() == true
 | 
			
		||||
        /// @param area area in image space to put the quad
 | 
			
		||||
        /// @param quads collect quads here so they can be deleted later
 | 
			
		||||
        void prepareForCompositeMap(Ogre::TRect<float> area);
 | 
			
		||||
 | 
			
		||||
        /// Create a chunk for this node from the given data.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								extern/sdl4ogre/events.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								extern/sdl4ogre/events.h
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
#ifndef _SFO_EVENTS_H
 | 
			
		||||
#define _SFO_EVENTS_H
 | 
			
		||||
 | 
			
		||||
#include <SDL.h>
 | 
			
		||||
 | 
			
		||||
#include <SDL_types.h>
 | 
			
		||||
#include <SDL_events.h>
 | 
			
		||||
 | 
			
		||||
////////////
 | 
			
		||||
// Events //
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ public:
 | 
			
		|||
    virtual ~WindowListener() {}
 | 
			
		||||
 | 
			
		||||
    /** @remarks The window's visibility changed */
 | 
			
		||||
    virtual void windowVisibilityChange( bool visible ) {};
 | 
			
		||||
    virtual void windowVisibilityChange( bool visible ) {}
 | 
			
		||||
 | 
			
		||||
    /** @remarks The window got / lost input focus */
 | 
			
		||||
    virtual void windowFocusChange( bool have_focus ) {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								extern/sdl4ogre/sdlcursormanager.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								extern/sdl4ogre/sdlcursormanager.cpp
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -4,6 +4,9 @@
 | 
			
		|||
#include <OgreTextureManager.h>
 | 
			
		||||
#include <OgreRoot.h>
 | 
			
		||||
 | 
			
		||||
#include <SDL_mouse.h>
 | 
			
		||||
#include <SDL_endian.h>
 | 
			
		||||
 | 
			
		||||
#include <openengine/ogre/imagerotate.hpp>
 | 
			
		||||
 | 
			
		||||
namespace SFO
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								extern/sdl4ogre/sdlcursormanager.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								extern/sdl4ogre/sdlcursormanager.hpp
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,11 +1,12 @@
 | 
			
		|||
#ifndef SDL4OGRE_CURSORMANAGER_H
 | 
			
		||||
#define SDL4OGRE_CURSORMANAGER_H
 | 
			
		||||
 | 
			
		||||
#include <SDL.h>
 | 
			
		||||
 | 
			
		||||
#include "cursormanager.hpp"
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
struct SDL_Cursor;
 | 
			
		||||
struct SDL_Surface;
 | 
			
		||||
 | 
			
		||||
namespace SFO
 | 
			
		||||
{
 | 
			
		||||
    class SDLCursorManager :
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,7 +50,7 @@
 | 
			
		|||
                    <UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_strength.dds"/>
 | 
			
		||||
                    <Property key="Caption" value="#{sAttributeStrength}"/>
 | 
			
		||||
                </Widget>
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal1">
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal1">
 | 
			
		||||
                </Widget>
 | 
			
		||||
            </Widget>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,7 @@
 | 
			
		|||
                    <UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_int.dds"/>
 | 
			
		||||
                    <Property key="Caption" value="#{sAttributeIntelligence}"/>
 | 
			
		||||
                </Widget>
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal2">
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal2">
 | 
			
		||||
                </Widget>
 | 
			
		||||
            </Widget>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,7 @@
 | 
			
		|||
                    <UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_wilpower.dds"/>
 | 
			
		||||
                    <Property key="Caption" value="#{sAttributeWillpower}"/>
 | 
			
		||||
                </Widget>
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal3">
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal3">
 | 
			
		||||
                </Widget>
 | 
			
		||||
            </Widget>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +92,7 @@
 | 
			
		|||
                    <UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_agility.dds"/>
 | 
			
		||||
                    <Property key="Caption" value="#{sAttributeAgility}"/>
 | 
			
		||||
                </Widget>
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal4">
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal4">
 | 
			
		||||
                </Widget>
 | 
			
		||||
            </Widget>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +107,7 @@
 | 
			
		|||
                    <UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_speed.dds"/>
 | 
			
		||||
                    <Property key="Caption" value="#{sAttributeSpeed}"/>
 | 
			
		||||
                </Widget>
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal5">
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal5">
 | 
			
		||||
                </Widget>
 | 
			
		||||
            </Widget>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +121,7 @@
 | 
			
		|||
                    <UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_endurance.dds"/>
 | 
			
		||||
                    <Property key="Caption" value="#{sAttributeEndurance}"/>
 | 
			
		||||
                </Widget>
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal6">
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal6">
 | 
			
		||||
                </Widget>
 | 
			
		||||
            </Widget>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +135,7 @@
 | 
			
		|||
                <UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_personality.dds"/>
 | 
			
		||||
                    <Property key="Caption" value="#{sAttributePersonality}"/>
 | 
			
		||||
                </Widget>
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal7">
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal7">
 | 
			
		||||
                </Widget>
 | 
			
		||||
            </Widget>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,7 +149,7 @@
 | 
			
		|||
                <UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_luck.dds"/>
 | 
			
		||||
                    <Property key="Caption" value="#{sAttributeLuck}"/>
 | 
			
		||||
                </Widget>
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal8">
 | 
			
		||||
                <Widget type="AutoSizedTextBox" skin="SandTextButton" name="AttribVal8">
 | 
			
		||||
                </Widget>
 | 
			
		||||
            </Widget>
 | 
			
		||||
        </Widget>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue