mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 01:26:39 +00:00 
			
		
		
		
	Merge branch 'master' of github.com:OpenMW/openmw
This commit is contained in:
		
						commit
						c5e85ebddc
					
				
					 117 changed files with 1322 additions and 497 deletions
				
			
		| 
						 | 
				
			
			@ -259,20 +259,36 @@ int CS::Editor::run()
 | 
			
		|||
 | 
			
		||||
std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
 | 
			
		||||
{
 | 
			
		||||
    // TODO: setting
 | 
			
		||||
    Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName("OpenGL Rendering Subsystem"));
 | 
			
		||||
    std::string renderer =
 | 
			
		||||
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
 | 
			
		||||
        "Direct3D9 Rendering Subsystem";
 | 
			
		||||
#else
 | 
			
		||||
        "OpenGL Rendering Subsystem";
 | 
			
		||||
#endif
 | 
			
		||||
    std::string renderSystem = mUserSettings.setting("Video/render system", renderer.c_str()).toStdString();
 | 
			
		||||
 | 
			
		||||
    Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName(renderSystem));
 | 
			
		||||
 | 
			
		||||
    Ogre::Root::getSingleton().initialise(false);
 | 
			
		||||
 | 
			
		||||
    // Create a hidden background window to keep resources
 | 
			
		||||
    Ogre::NameValuePairList params;
 | 
			
		||||
    params.insert(std::make_pair("title", ""));
 | 
			
		||||
    params.insert(std::make_pair("FSAA", "0"));
 | 
			
		||||
 | 
			
		||||
    std::string antialiasing = mUserSettings.settingValue("Video/antialiasing").toStdString();
 | 
			
		||||
    if(antialiasing == "MSAA 16")     antialiasing = "16";
 | 
			
		||||
    else if(antialiasing == "MSAA 8") antialiasing = "8";
 | 
			
		||||
    else if(antialiasing == "MSAA 4") antialiasing = "4";
 | 
			
		||||
    else if(antialiasing == "MSAA 2") antialiasing = "2";
 | 
			
		||||
    else                              antialiasing = "0";
 | 
			
		||||
    params.insert(std::make_pair("FSAA", antialiasing));
 | 
			
		||||
 | 
			
		||||
    params.insert(std::make_pair("vsync", "false"));
 | 
			
		||||
    params.insert(std::make_pair("hidden", "true"));
 | 
			
		||||
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
 | 
			
		||||
    params.insert(std::make_pair("macAPI", "cocoa"));
 | 
			
		||||
#endif
 | 
			
		||||
    // NOTE: fullscreen mode not supported (doesn't really make sense for opencs)
 | 
			
		||||
    Ogre::RenderWindow* hiddenWindow = Ogre::Root::getSingleton().createRenderWindow("InactiveHidden", 1, 1, false, ¶ms);
 | 
			
		||||
    hiddenWindow->setActive(false);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -286,7 +302,28 @@ std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
 | 
			
		|||
 | 
			
		||||
    std::auto_ptr<sh::Factory> factory (new sh::Factory (platform));
 | 
			
		||||
 | 
			
		||||
    factory->setCurrentLanguage (sh::Language_GLSL); /// \todo make this configurable
 | 
			
		||||
    QString shLang = mUserSettings.settingValue("General/shader mode");
 | 
			
		||||
    QString rend = renderSystem.c_str();
 | 
			
		||||
    bool openGL = rend.contains(QRegExp("^OpenGL", Qt::CaseInsensitive));
 | 
			
		||||
    bool glES = rend.contains(QRegExp("^OpenGL ES", Qt::CaseInsensitive));
 | 
			
		||||
 | 
			
		||||
    // force shader language based on render system
 | 
			
		||||
    if(shLang == ""
 | 
			
		||||
            || (openGL && shLang == "hlsl")
 | 
			
		||||
            || (!openGL && shLang == "glsl")
 | 
			
		||||
            || (glES && shLang != "glsles"))
 | 
			
		||||
    {
 | 
			
		||||
        shLang = openGL ? (glES ? "glsles" : "glsl") : "hlsl";
 | 
			
		||||
        //no group means "General" group in the "ini" file standard
 | 
			
		||||
        mUserSettings.setDefinitions("shader mode", (QStringList() << shLang));
 | 
			
		||||
    }
 | 
			
		||||
    enum sh::Language lang;
 | 
			
		||||
    if(shLang == "glsl")        lang = sh::Language_GLSL;
 | 
			
		||||
    else if(shLang == "glsles") lang = sh::Language_GLSLES;
 | 
			
		||||
    else if(shLang == "hlsl")   lang = sh::Language_HLSL;
 | 
			
		||||
    else                        lang = sh::Language_CG;
 | 
			
		||||
 | 
			
		||||
    factory->setCurrentLanguage (lang);
 | 
			
		||||
    factory->setWriteSourceCache (true);
 | 
			
		||||
    factory->setReadSourceCache (true);
 | 
			
		||||
    factory->setReadMicrocodeCache (true);
 | 
			
		||||
| 
						 | 
				
			
			@ -294,16 +331,27 @@ std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
 | 
			
		|||
 | 
			
		||||
    factory->loadAllFiles();
 | 
			
		||||
 | 
			
		||||
    sh::Factory::getInstance().setGlobalSetting ("fog", "true");
 | 
			
		||||
    bool shaders = mUserSettings.setting("Objects/shaders", QString("true")) == "true" ? true : false;
 | 
			
		||||
    sh::Factory::getInstance ().setShadersEnabled (shaders);
 | 
			
		||||
 | 
			
		||||
    sh::Factory::getInstance().setGlobalSetting ("shadows", "false");
 | 
			
		||||
    sh::Factory::getInstance().setGlobalSetting ("shadows_pssm", "false");
 | 
			
		||||
    std::string fog = mUserSettings.setting("Shader/fog", QString("true")).toStdString();
 | 
			
		||||
    sh::Factory::getInstance().setGlobalSetting ("fog", fog);
 | 
			
		||||
 | 
			
		||||
    sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false");
 | 
			
		||||
 | 
			
		||||
    std::string shadows = mUserSettings.setting("Shader/shadows", QString("false")).toStdString();
 | 
			
		||||
    sh::Factory::getInstance().setGlobalSetting ("shadows", shadows);
 | 
			
		||||
 | 
			
		||||
    std::string shadows_pssm = mUserSettings.setting("Shader/shadows_pssm", QString("false")).toStdString();
 | 
			
		||||
    sh::Factory::getInstance().setGlobalSetting ("shadows_pssm", shadows_pssm);
 | 
			
		||||
 | 
			
		||||
    std::string render_refraction = mUserSettings.setting("Shader/render_refraction", QString("false")).toStdString();
 | 
			
		||||
    sh::Factory::getInstance ().setGlobalSetting ("render_refraction", render_refraction);
 | 
			
		||||
 | 
			
		||||
    // internal setting - may be switched on or off by the use of shader configurations
 | 
			
		||||
    sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false");
 | 
			
		||||
 | 
			
		||||
    sh::Factory::getInstance ().setGlobalSetting ("num_lights", "8");
 | 
			
		||||
    std::string num_lights = mUserSettings.setting("Objects/num_lights", QString("8")).toStdString();
 | 
			
		||||
    sh::Factory::getInstance ().setGlobalSetting ("num_lights", num_lights);
 | 
			
		||||
 | 
			
		||||
    /// \todo add more configurable shiny settings
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -194,6 +194,16 @@ QString CSMSettings::Setting::page() const
 | 
			
		|||
    return property (Property_Page).at(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSMSettings::Setting::setStyleSheet (const QString &value)
 | 
			
		||||
{
 | 
			
		||||
    setProperty (Property_StyleSheet, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString CSMSettings::Setting::styleSheet() const
 | 
			
		||||
{
 | 
			
		||||
    return property (Property_StyleSheet).at(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSMSettings::Setting::setPrefix (const QString &value)
 | 
			
		||||
{
 | 
			
		||||
    setProperty (Property_Prefix, value);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,6 +80,9 @@ namespace CSMSettings
 | 
			
		|||
        void setPage (const QString &value);
 | 
			
		||||
        QString page() const;
 | 
			
		||||
 | 
			
		||||
        void setStyleSheet (const QString &value);
 | 
			
		||||
        QString styleSheet() const;
 | 
			
		||||
 | 
			
		||||
        void setPrefix (const QString &value);
 | 
			
		||||
        QString prefix() const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,12 +35,13 @@ namespace CSMSettings
 | 
			
		|||
        Property_TickInterval = 19,
 | 
			
		||||
        Property_TicksAbove = 20,
 | 
			
		||||
        Property_TicksBelow = 21,
 | 
			
		||||
        Property_StyleSheet = 22,
 | 
			
		||||
 | 
			
		||||
        //Stringlists should always be the last items
 | 
			
		||||
        Property_DefaultValues = 22,
 | 
			
		||||
        Property_DeclaredValues = 23,
 | 
			
		||||
        Property_DefinedValues = 24,
 | 
			
		||||
        Property_Proxies = 25
 | 
			
		||||
        Property_DefaultValues = 23,
 | 
			
		||||
        Property_DeclaredValues = 24,
 | 
			
		||||
        Property_DefinedValues = 25,
 | 
			
		||||
        Property_Proxies = 26
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ///Basic setting widget types.
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +107,7 @@ namespace CSMSettings
 | 
			
		|||
        "is_multi_line", "widget_width", "view_row", "view_column", "delimiter",
 | 
			
		||||
        "is_serializable","column_span", "row_span", "minimum", "maximum",
 | 
			
		||||
        "special_value_text", "prefix", "suffix", "single_step", "wrapping",
 | 
			
		||||
        "tick_interval", "ticks_above", "ticks_below",
 | 
			
		||||
        "tick_interval", "ticks_above", "ticks_below", "stylesheet",
 | 
			
		||||
        "defaults", "declarations", "definitions", "proxies"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -135,6 +136,7 @@ namespace CSMSettings
 | 
			
		|||
        "1",        //tick interval
 | 
			
		||||
        "false",    //ticks above
 | 
			
		||||
        "true",     //ticks below
 | 
			
		||||
        "",         //StyleSheet
 | 
			
		||||
        "",         //default values
 | 
			
		||||
        "",         //declared values
 | 
			
		||||
        "",         //defined values
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,12 +4,16 @@
 | 
			
		|||
#include <QFile>
 | 
			
		||||
 | 
			
		||||
#include <components/files/configurationmanager.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
#include <boost/version.hpp>
 | 
			
		||||
 | 
			
		||||
#include "setting.hpp"
 | 
			
		||||
#include "support.hpp"
 | 
			
		||||
#include <QTextCodec>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
#include <extern/shiny/Main/Factory.hpp>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Workaround for problems with whitespaces in paths in older versions of Boost library
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -28,20 +32,111 @@ namespace boost
 | 
			
		|||
 | 
			
		||||
CSMSettings::UserSettings *CSMSettings::UserSettings::mUserSettingsInstance = 0;
 | 
			
		||||
 | 
			
		||||
CSMSettings::UserSettings::UserSettings (const Files::ConfigurationManager& configurationManager)
 | 
			
		||||
: mCfgMgr (configurationManager)
 | 
			
		||||
    CSMSettings::UserSettings::UserSettings (const Files::ConfigurationManager& configurationManager)
 | 
			
		||||
    : mCfgMgr (configurationManager)
 | 
			
		||||
    , mSettingDefinitions(NULL)
 | 
			
		||||
    , mSettingCfgDefinitions(NULL)
 | 
			
		||||
{
 | 
			
		||||
    assert(!mUserSettingsInstance);
 | 
			
		||||
    mUserSettingsInstance = this;
 | 
			
		||||
 | 
			
		||||
    mSettingDefinitions = 0;
 | 
			
		||||
 | 
			
		||||
    buildSettingModelDefaults();
 | 
			
		||||
 | 
			
		||||
    // for overriding opencs.ini settings with those from settings.cfg
 | 
			
		||||
    mSettingCfgDefinitions = new QSettings(QSettings::IniFormat, QSettings::UserScope, "", QString(), this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSMSettings::UserSettings::buildSettingModelDefaults()
 | 
			
		||||
{
 | 
			
		||||
    QString section = "Window Size";
 | 
			
		||||
    QString section;
 | 
			
		||||
 | 
			
		||||
    section = "Objects";
 | 
			
		||||
    {
 | 
			
		||||
        Setting *numLights = createSetting (Type_SpinBox, section, "num_lights");
 | 
			
		||||
        numLights->setDefaultValue(8);
 | 
			
		||||
        numLights->setEditorSetting(true);
 | 
			
		||||
        numLights->setColumnSpan (1);
 | 
			
		||||
        numLights->setMinimum (0);
 | 
			
		||||
        numLights->setMaximum (100); // FIXME: not sure what the max value should be
 | 
			
		||||
        numLights->setWidgetWidth (10);
 | 
			
		||||
        numLights->setViewLocation(1, 2);
 | 
			
		||||
 | 
			
		||||
        Setting *shaders = createSetting (Type_CheckBox, section, "shaders");
 | 
			
		||||
        shaders->setDeclaredValues(QStringList() << "true" << "false");
 | 
			
		||||
        shaders->setDefaultValue("true");
 | 
			
		||||
        shaders->setEditorSetting(true);
 | 
			
		||||
        shaders->setSpecialValueText("Enable Shaders");
 | 
			
		||||
        shaders->setWidgetWidth(25);
 | 
			
		||||
        shaders->setColumnSpan (3);
 | 
			
		||||
        shaders->setStyleSheet ("QGroupBox { border: 0px; }");
 | 
			
		||||
        shaders->setViewLocation(2, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    section = "Scene";
 | 
			
		||||
    {
 | 
			
		||||
        Setting *fastFactor = createSetting (Type_SpinBox, section, "fast factor");
 | 
			
		||||
        fastFactor->setDefaultValue(4);
 | 
			
		||||
        fastFactor->setEditorSetting(true);
 | 
			
		||||
        fastFactor->setColumnSpan (1);
 | 
			
		||||
        fastFactor->setMinimum (1);
 | 
			
		||||
        fastFactor->setSpecialValueText ("1"); // FIXME: workaround
 | 
			
		||||
        fastFactor->setMaximum (100); // FIXME: not sure what the max value should be
 | 
			
		||||
        fastFactor->setWidgetWidth (10);
 | 
			
		||||
        fastFactor->setViewLocation(1, 2);
 | 
			
		||||
 | 
			
		||||
        Setting *farClipDist = createSetting (Type_DoubleSpinBox, section, "far clip distance");
 | 
			
		||||
        farClipDist->setDefaultValue(300000);
 | 
			
		||||
        farClipDist->setEditorSetting(true);
 | 
			
		||||
        farClipDist->setColumnSpan (1);
 | 
			
		||||
        farClipDist->setMinimum (0);
 | 
			
		||||
        farClipDist->setMaximum (1000000); // FIXME: not sure what the max value should be
 | 
			
		||||
        farClipDist->setWidgetWidth (10);
 | 
			
		||||
        farClipDist->setViewLocation(2, 2);
 | 
			
		||||
 | 
			
		||||
        Setting *timerStart = createSetting (Type_SpinBox, section, "timer start");
 | 
			
		||||
        timerStart->setDefaultValue(20);
 | 
			
		||||
        timerStart->setEditorSetting(true);
 | 
			
		||||
        timerStart->setColumnSpan (1);
 | 
			
		||||
        timerStart->setMinimum (0);
 | 
			
		||||
        timerStart->setMaximum (100); // FIXME: not sure what the max value should be
 | 
			
		||||
        timerStart->setWidgetWidth (10);
 | 
			
		||||
        timerStart->setViewLocation(3, 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    section = "SubView";
 | 
			
		||||
    {
 | 
			
		||||
        Setting *maxSubView = createSetting (Type_SpinBox, section, "max subviews");
 | 
			
		||||
        maxSubView->setDefaultValue(256);
 | 
			
		||||
        maxSubView->setEditorSetting(true);
 | 
			
		||||
        maxSubView->setColumnSpan (1);
 | 
			
		||||
        maxSubView->setMinimum (1);
 | 
			
		||||
        maxSubView->setSpecialValueText ("1");
 | 
			
		||||
        maxSubView->setMaximum (256); // FIXME: not sure what the max value should be
 | 
			
		||||
        maxSubView->setWidgetWidth (10);
 | 
			
		||||
        maxSubView->setViewLocation(1, 2);
 | 
			
		||||
 | 
			
		||||
        Setting *minWidth = createSetting (Type_SpinBox, section, "minimum width");
 | 
			
		||||
        minWidth->setDefaultValue(325);
 | 
			
		||||
        minWidth->setEditorSetting(true);
 | 
			
		||||
        minWidth->setColumnSpan (1);
 | 
			
		||||
        minWidth->setMinimum (50);
 | 
			
		||||
        minWidth->setSpecialValueText ("50");
 | 
			
		||||
        minWidth->setMaximum (10000); // FIXME: not sure what the max value should be
 | 
			
		||||
        minWidth->setWidgetWidth (10);
 | 
			
		||||
        minWidth->setViewLocation(2, 2);
 | 
			
		||||
 | 
			
		||||
        Setting *reuse = createSetting (Type_CheckBox, section, "reuse");
 | 
			
		||||
        reuse->setDeclaredValues(QStringList() << "true" << "false");
 | 
			
		||||
        reuse->setDefaultValue("true");
 | 
			
		||||
        reuse->setEditorSetting(true);
 | 
			
		||||
        reuse->setSpecialValueText("Reuse SubView");
 | 
			
		||||
        reuse->setWidgetWidth(25);
 | 
			
		||||
        reuse->setColumnSpan (3);
 | 
			
		||||
        reuse->setStyleSheet ("QGroupBox { border: 0px; }");
 | 
			
		||||
        reuse->setViewLocation(3, 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    section = "Window Size";
 | 
			
		||||
    {
 | 
			
		||||
        Setting *width = createSetting (Type_LineEdit, section, "Width");
 | 
			
		||||
        Setting *height = createSetting (Type_LineEdit, section, "Height");
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +195,17 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
 | 
			
		|||
        ritd->setEditorSetting (true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    section = "Video";
 | 
			
		||||
    {
 | 
			
		||||
        QString defaultValue = "None";
 | 
			
		||||
        QStringList values = QStringList()
 | 
			
		||||
                        << defaultValue << "MSAA 2" << "MSAA 4" << "MSAA 8" << "MSAA 16";
 | 
			
		||||
        Setting *antialiasing = createSetting (Type_SpinBox, section, "antialiasing");
 | 
			
		||||
        antialiasing->setDeclaredValues (values);
 | 
			
		||||
        antialiasing->setEditorSetting (true);
 | 
			
		||||
        antialiasing->setWidgetWidth(15);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    section = "Proxy Selection Test";
 | 
			
		||||
    {
 | 
			
		||||
        /******************************************************************
 | 
			
		||||
| 
						 | 
				
			
			@ -305,10 +411,27 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName)
 | 
			
		|||
 | 
			
		||||
    mSettingDefinitions = new QSettings
 | 
			
		||||
        (QSettings::IniFormat, QSettings::UserScope, "opencs", QString(), this);
 | 
			
		||||
 | 
			
		||||
    // check if override entry exists (default: disabled)
 | 
			
		||||
    if(!mSettingDefinitions->childGroups().contains("Video", Qt::CaseInsensitive))
 | 
			
		||||
        mSettingDefinitions->setValue("Video/use settings.cfg", "false");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CSMSettings::UserSettings::hasSettingDefinitions
 | 
			
		||||
                                                (const QString &viewKey) const
 | 
			
		||||
// if the key is not found create one with a defaut value
 | 
			
		||||
QString CSMSettings::UserSettings::setting(const QString &viewKey, const QString &value)
 | 
			
		||||
{
 | 
			
		||||
    if(mSettingDefinitions->contains(viewKey))
 | 
			
		||||
        return settingValue(viewKey);
 | 
			
		||||
    else if(value != QString())
 | 
			
		||||
    {
 | 
			
		||||
        mSettingDefinitions->setValue (viewKey, QStringList() << value);
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return QString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CSMSettings::UserSettings::hasSettingDefinitions (const QString &viewKey) const
 | 
			
		||||
{
 | 
			
		||||
    return (mSettingDefinitions->contains (viewKey));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -326,10 +449,25 @@ void CSMSettings::UserSettings::saveDefinitions() const
 | 
			
		|||
 | 
			
		||||
QString CSMSettings::UserSettings::settingValue (const QString &settingKey)
 | 
			
		||||
{
 | 
			
		||||
    if (!mSettingDefinitions->contains (settingKey))
 | 
			
		||||
        return QString();
 | 
			
		||||
    QStringList defs;
 | 
			
		||||
 | 
			
		||||
    QStringList defs = mSettingDefinitions->value (settingKey).toStringList();
 | 
			
		||||
    // check if video settings are overriden
 | 
			
		||||
    if(settingKey.contains(QRegExp("^Video\\b", Qt::CaseInsensitive)) &&
 | 
			
		||||
       mSettingDefinitions->value("Video/use settings.cfg") == "true" &&
 | 
			
		||||
       settingKey.contains(QRegExp("^Video/\\brender|antialiasing|vsync|fullscreen\\b", Qt::CaseInsensitive)))
 | 
			
		||||
    {
 | 
			
		||||
        if (!mSettingCfgDefinitions->contains (settingKey))
 | 
			
		||||
            return QString();
 | 
			
		||||
        else
 | 
			
		||||
            defs = mSettingCfgDefinitions->value (settingKey).toStringList();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        if (!mSettingDefinitions->contains (settingKey))
 | 
			
		||||
            return QString();
 | 
			
		||||
 | 
			
		||||
        defs = mSettingDefinitions->value (settingKey).toStringList();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (defs.isEmpty())
 | 
			
		||||
        return QString();
 | 
			
		||||
| 
						 | 
				
			
			@ -348,6 +486,15 @@ void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey,
 | 
			
		|||
{
 | 
			
		||||
    mSettingDefinitions->setValue (settingKey ,list);
 | 
			
		||||
 | 
			
		||||
    if(settingKey == "Objects/num_lights" && !list.empty())
 | 
			
		||||
    {
 | 
			
		||||
        sh::Factory::getInstance ().setGlobalSetting ("num_lights", list.at(0).toStdString());
 | 
			
		||||
    }
 | 
			
		||||
    else if(settingKey == "Objects/shaders" && !list.empty())
 | 
			
		||||
    {
 | 
			
		||||
        sh::Factory::getInstance ().setShadersEnabled (list.at(0).toStdString() == "true" ? true : false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    emit userSettingUpdated (settingKey, list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -387,7 +534,6 @@ void CSMSettings::UserSettings::removeSetting
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CSMSettings::SettingPageMap CSMSettings::UserSettings::settingPageMap() const
 | 
			
		||||
{
 | 
			
		||||
    SettingPageMap pageMap;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,8 +33,10 @@ namespace CSMSettings {
 | 
			
		|||
        const Files::ConfigurationManager& mCfgMgr;
 | 
			
		||||
 | 
			
		||||
        QSettings *mSettingDefinitions;
 | 
			
		||||
        QSettings *mSettingCfgDefinitions;
 | 
			
		||||
        QList <Setting *> mSettings;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        /// Singleton implementation
 | 
			
		||||
| 
						 | 
				
			
			@ -75,6 +77,8 @@ namespace CSMSettings {
 | 
			
		|||
        ///Save any unsaved changes in the QSettings object
 | 
			
		||||
        void saveDefinitions() const;
 | 
			
		||||
 | 
			
		||||
        QString setting(const QString &viewKey, const QString &value = QString());
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        void buildSettingModelDefaults();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,6 +71,14 @@ namespace CSMWorld
 | 
			
		|||
 | 
			
		||||
            record.load (reader);
 | 
			
		||||
 | 
			
		||||
            if (index==-1)
 | 
			
		||||
            {
 | 
			
		||||
                std::string newId = IdAccessorT().getId(record);
 | 
			
		||||
                int newIndex = this->searchId(newId);
 | 
			
		||||
                if (newIndex != -1 && id != newId)
 | 
			
		||||
                    index = newIndex;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            load (record, base, index);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,18 +6,20 @@
 | 
			
		|||
void CSMWorld::ResourcesManager::addResources (const Resources& resources)
 | 
			
		||||
{
 | 
			
		||||
    mResources.insert (std::make_pair (resources.getType(), resources));
 | 
			
		||||
    mResources.insert (std::make_pair (UniversalId::getParentType (resources.getType()),
 | 
			
		||||
        resources));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSMWorld::ResourcesManager::listResources()
 | 
			
		||||
{
 | 
			
		||||
    static const char * const sMeshTypes[] = { "nif", 0 };
 | 
			
		||||
 | 
			
		||||
    addResources (Resources ("meshes", UniversalId::Type_Meshes, sMeshTypes));
 | 
			
		||||
    addResources (Resources ("icons", UniversalId::Type_Icons));
 | 
			
		||||
    addResources (Resources ("music", UniversalId::Type_Musics));
 | 
			
		||||
    addResources (Resources ("sound", UniversalId::Type_SoundsRes));
 | 
			
		||||
    addResources (Resources ("textures", UniversalId::Type_Textures));
 | 
			
		||||
    addResources (Resources ("videos", UniversalId::Type_Videos));
 | 
			
		||||
    addResources (Resources ("meshes", UniversalId::Type_Mesh, sMeshTypes));
 | 
			
		||||
    addResources (Resources ("icons", UniversalId::Type_Icon));
 | 
			
		||||
    addResources (Resources ("music", UniversalId::Type_Music));
 | 
			
		||||
    addResources (Resources ("sound", UniversalId::Type_SoundRes));
 | 
			
		||||
    addResources (Resources ("textures", UniversalId::Type_Texture));
 | 
			
		||||
    addResources (Resources ("videos", UniversalId::Type_Video));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const CSMWorld::Resources& CSMWorld::ResourcesManager::get (UniversalId::Type type) const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
#include "subview.hpp"
 | 
			
		||||
 | 
			
		||||
#include "view.hpp"
 | 
			
		||||
 | 
			
		||||
CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
 | 
			
		||||
{
 | 
			
		||||
    /// \todo  add a button to the title bar that clones this sub view
 | 
			
		||||
| 
						 | 
				
			
			@ -25,3 +27,10 @@ void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id)
 | 
			
		|||
    mUniversalId = id;
 | 
			
		||||
    setWindowTitle (mUniversalId.toString().c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVDoc::SubView::closeEvent (QCloseEvent *event)
 | 
			
		||||
{
 | 
			
		||||
    // update title bars of view and subviews
 | 
			
		||||
    if(mParent)
 | 
			
		||||
        mParent->updateSubViewIndicies(this);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,11 +18,14 @@ namespace CSMWorld
 | 
			
		|||
 | 
			
		||||
namespace CSVDoc
 | 
			
		||||
{
 | 
			
		||||
    class View;
 | 
			
		||||
 | 
			
		||||
    class SubView : public QDockWidget
 | 
			
		||||
    {
 | 
			
		||||
            Q_OBJECT
 | 
			
		||||
 | 
			
		||||
            CSMWorld::UniversalId mUniversalId;
 | 
			
		||||
            View *mParent;
 | 
			
		||||
 | 
			
		||||
            // not implemented
 | 
			
		||||
            SubView (const SubView&);
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +47,12 @@ namespace CSVDoc
 | 
			
		|||
            virtual void useHint (const std::string& hint);
 | 
			
		||||
            ///< Default implementation: ignored
 | 
			
		||||
 | 
			
		||||
            void setParent(View *parent) { mParent = parent; }
 | 
			
		||||
 | 
			
		||||
        private:
 | 
			
		||||
 | 
			
		||||
            void closeEvent (QCloseEvent *event);
 | 
			
		||||
 | 
			
		||||
        signals:
 | 
			
		||||
 | 
			
		||||
            void focusId (const CSMWorld::UniversalId& universalId, const std::string& hint);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
#include <QMdiArea>
 | 
			
		||||
#include <QDockWidget>
 | 
			
		||||
#include <QtGui/QApplication>
 | 
			
		||||
#include <QDesktopWidget>
 | 
			
		||||
 | 
			
		||||
#include "../../model/doc/document.hpp"
 | 
			
		||||
#include "../../model/settings/usersettings.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +104,10 @@ void CSVDoc::View::setupViewMenu()
 | 
			
		|||
    mShowStatusBar = new QAction (tr ("Show Status Bar"), this);
 | 
			
		||||
    mShowStatusBar->setCheckable (true);
 | 
			
		||||
    connect (mShowStatusBar, SIGNAL (toggled (bool)), this, SLOT (toggleShowStatusBar (bool)));
 | 
			
		||||
    std::string showStatusBar =
 | 
			
		||||
        CSMSettings::UserSettings::instance().settingValue("Display/show statusbar").toStdString();
 | 
			
		||||
    if(showStatusBar == "true")
 | 
			
		||||
        mShowStatusBar->setChecked(true);
 | 
			
		||||
    view->addAction (mShowStatusBar);
 | 
			
		||||
 | 
			
		||||
    QAction *filters = new QAction (tr ("Filters"), this);
 | 
			
		||||
| 
						 | 
				
			
			@ -283,7 +288,7 @@ void CSVDoc::View::setupUi()
 | 
			
		|||
    setupDebugMenu();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVDoc::View::updateTitle()
 | 
			
		||||
void CSVDoc::View::updateTitle(const std::string subview)
 | 
			
		||||
{
 | 
			
		||||
    std::ostringstream stream;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -295,9 +300,40 @@ void CSVDoc::View::updateTitle()
 | 
			
		|||
    if (mViewTotal>1)
 | 
			
		||||
        stream << " [" << (mViewIndex+1) << "/" << mViewTotal << "]";
 | 
			
		||||
 | 
			
		||||
    if (subview != "")
 | 
			
		||||
        stream << " - " << subview;
 | 
			
		||||
 | 
			
		||||
    setWindowTitle (stream.str().c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVDoc::View::updateSubViewIndicies(SubView *view)
 | 
			
		||||
{
 | 
			
		||||
    if(view && mSubViews.contains(view))
 | 
			
		||||
        mSubViews.removeOne(view);
 | 
			
		||||
 | 
			
		||||
    if(mSubViews.size() == 1)
 | 
			
		||||
    {
 | 
			
		||||
        if(!mSubViews.at(0)->isFloating())
 | 
			
		||||
        {
 | 
			
		||||
            mSubViews.at(0)->setTitleBarWidget(new QWidget(this));
 | 
			
		||||
            updateTitle(mSubViews.at(0)->getUniversalId().getTypeName().c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        updateTitle();
 | 
			
		||||
        if(mSubViews.size() > 1)
 | 
			
		||||
        {
 | 
			
		||||
            foreach(SubView * sb, mSubViews)
 | 
			
		||||
            {
 | 
			
		||||
                QWidget * tb = sb->titleBarWidget();
 | 
			
		||||
                if(tb) delete tb;
 | 
			
		||||
                sb->setTitleBarWidget(0);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVDoc::View::updateActions()
 | 
			
		||||
{
 | 
			
		||||
    bool editing = !(mDocument->getState() & CSMDoc::State_Locked);
 | 
			
		||||
| 
						 | 
				
			
			@ -326,7 +362,11 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
 | 
			
		|||
    QString height = CSMSettings::UserSettings::instance().settingValue
 | 
			
		||||
                                    ("Window Size/Height");
 | 
			
		||||
 | 
			
		||||
    resize (width.toInt(), height.toInt());
 | 
			
		||||
    // trick to get the window decorations and their sizes
 | 
			
		||||
    show();
 | 
			
		||||
    hide();
 | 
			
		||||
    resize (width.toInt() - (frameGeometry().width() - geometry().width()),
 | 
			
		||||
            height.toInt() - (frameGeometry().height() - geometry().height()));
 | 
			
		||||
 | 
			
		||||
    mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -400,31 +440,64 @@ void CSVDoc::View::updateProgress (int current, int max, int type, int threads)
 | 
			
		|||
 | 
			
		||||
void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::string& hint)
 | 
			
		||||
{
 | 
			
		||||
    /// \todo add an user setting for limiting the number of sub views per top level view. Automatically open a new top level view if this
 | 
			
		||||
    /// number is exceeded
 | 
			
		||||
 | 
			
		||||
    /// \todo if the sub view limit setting is one, the sub view title bar should be hidden and the text in the main title bar adjusted
 | 
			
		||||
    /// accordingly
 | 
			
		||||
 | 
			
		||||
    /// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
 | 
			
		||||
    CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
 | 
			
		||||
 | 
			
		||||
    const std::vector<CSMWorld::UniversalId::Type> referenceables(CSMWorld::UniversalId::listReferenceableTypes());
 | 
			
		||||
    bool isReferenceable = std::find(referenceables.begin(), referenceables.end(), id.getType()) != referenceables.end();
 | 
			
		||||
 | 
			
		||||
    // User setting to reuse sub views (on a per top level view basis)
 | 
			
		||||
    bool reuse =
 | 
			
		||||
        userSettings.setting("SubView/reuse", QString("true")) == "true" ? true : false;
 | 
			
		||||
    if(reuse)
 | 
			
		||||
    {
 | 
			
		||||
        foreach(SubView *sb, mSubViews)
 | 
			
		||||
        {
 | 
			
		||||
            if((isReferenceable && (CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()) == CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, sb->getUniversalId().getId())))
 | 
			
		||||
                || (!isReferenceable && (id == sb->getUniversalId())))
 | 
			
		||||
            {
 | 
			
		||||
                sb->setFocus(Qt::OtherFocusReason); // FIXME: focus not quite working
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // User setting for limiting the number of sub views per top level view.
 | 
			
		||||
    // Automatically open a new top level view if this number is exceeded
 | 
			
		||||
    //
 | 
			
		||||
    // If the sub view limit setting is one, the sub view title bar is hidden and the
 | 
			
		||||
    // text in the main title bar is adjusted accordingly
 | 
			
		||||
    int maxSubView = userSettings.setting("SubView/max subviews", QString("256")).toInt();
 | 
			
		||||
    if(mSubViews.size() >= maxSubView) // create a new top level view
 | 
			
		||||
    {
 | 
			
		||||
        mViewManager.addView(mDocument, id, hint);
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SubView *view = NULL;
 | 
			
		||||
    if(std::find(referenceables.begin(), referenceables.end(), id.getType()) != referenceables.end())
 | 
			
		||||
    {
 | 
			
		||||
        view = mSubViewFactory.makeSubView (CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()), *mDocument);
 | 
			
		||||
    } else
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        view = mSubViewFactory.makeSubView (id, *mDocument);
 | 
			
		||||
    }
 | 
			
		||||
    assert(view);
 | 
			
		||||
    view->setParent(this);
 | 
			
		||||
    mSubViews.append(view); // only after assert
 | 
			
		||||
    if (!hint.empty())
 | 
			
		||||
        view->useHint (hint);
 | 
			
		||||
 | 
			
		||||
    int minWidth = userSettings.setting("SubView/minimum width", QString("325")).toInt();
 | 
			
		||||
    view->setMinimumWidth(minWidth);
 | 
			
		||||
 | 
			
		||||
    view->setStatusBar (mShowStatusBar->isChecked());
 | 
			
		||||
 | 
			
		||||
    mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
 | 
			
		||||
 | 
			
		||||
    updateSubViewIndicies();
 | 
			
		||||
 | 
			
		||||
    connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)), this,
 | 
			
		||||
        SLOT (addSubView (const CSMWorld::UniversalId&, const std::string&)));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -642,6 +715,11 @@ void CSVDoc::View::toggleShowStatusBar (bool show)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVDoc::View::toggleStatusBar(bool checked)
 | 
			
		||||
{
 | 
			
		||||
    mShowStatusBar->setChecked(checked);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVDoc::View::loadErrorLog()
 | 
			
		||||
{
 | 
			
		||||
    addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_LoadErrorLog, 0));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,7 @@ namespace CSVDoc
 | 
			
		|||
            CSMDoc::Document *mDocument;
 | 
			
		||||
            int mViewIndex;
 | 
			
		||||
            int mViewTotal;
 | 
			
		||||
            QList<SubView *> mSubViews;
 | 
			
		||||
            QAction *mUndo;
 | 
			
		||||
            QAction *mRedo;
 | 
			
		||||
            QAction *mSave;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +75,7 @@ namespace CSVDoc
 | 
			
		|||
 | 
			
		||||
            void setupUi();
 | 
			
		||||
 | 
			
		||||
            void updateTitle();
 | 
			
		||||
            void updateTitle(const std::string subview = "");
 | 
			
		||||
 | 
			
		||||
            void updateActions();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -106,11 +107,16 @@ namespace CSVDoc
 | 
			
		|||
 | 
			
		||||
            void updateProgress (int current, int max, int type, int threads);
 | 
			
		||||
 | 
			
		||||
            void toggleStatusBar(bool checked);
 | 
			
		||||
 | 
			
		||||
            Operations *getOperations() const;
 | 
			
		||||
 | 
			
		||||
            /// Function called by view manager when user preferences are updated
 | 
			
		||||
            void updateEditorSetting (const QString &, const QString &);
 | 
			
		||||
 | 
			
		||||
            // called when subviews are added or removed
 | 
			
		||||
            void updateSubViewIndicies(SubView *view = 0);
 | 
			
		||||
 | 
			
		||||
        signals:
 | 
			
		||||
 | 
			
		||||
            void newGameRequest();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@
 | 
			
		|||
#include "../../model/doc/documentmanager.hpp"
 | 
			
		||||
#include "../../model/doc/document.hpp"
 | 
			
		||||
#include "../../model/world/columns.hpp"
 | 
			
		||||
#include "../../model/world/universalid.hpp"
 | 
			
		||||
 | 
			
		||||
#include "../world/util.hpp"
 | 
			
		||||
#include "../world/enumdelegate.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +141,10 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
 | 
			
		|||
 | 
			
		||||
    mViews.push_back (view);
 | 
			
		||||
 | 
			
		||||
    std::string showStatusBar =
 | 
			
		||||
        CSMSettings::UserSettings::instance().settingValue("Display/show statusbar").toStdString();
 | 
			
		||||
 | 
			
		||||
    view->toggleStatusBar (showStatusBar == "true");
 | 
			
		||||
    view->show();
 | 
			
		||||
 | 
			
		||||
    connect (view, SIGNAL (newGameRequest ()), this, SIGNAL (newGameRequest()));
 | 
			
		||||
| 
						 | 
				
			
			@ -157,6 +162,14 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
 | 
			
		|||
    return view;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document, const CSMWorld::UniversalId& id, const std::string& hint)
 | 
			
		||||
{
 | 
			
		||||
    View* view = addView(document);
 | 
			
		||||
    view->addSubView(id, hint);
 | 
			
		||||
 | 
			
		||||
    return view;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CSVDoc::ViewManager::countViews (const CSMDoc::Document *document) const
 | 
			
		||||
{
 | 
			
		||||
    int count = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,11 @@ namespace CSVWorld
 | 
			
		|||
    class CommandDelegateFactoryCollection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace CSMWorld
 | 
			
		||||
{
 | 
			
		||||
    class UniversalId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace CSVDoc
 | 
			
		||||
{
 | 
			
		||||
    class View;
 | 
			
		||||
| 
						 | 
				
			
			@ -52,6 +57,8 @@ namespace CSVDoc
 | 
			
		|||
            View *addView (CSMDoc::Document *document);
 | 
			
		||||
            ///< The ownership of the returned view is not transferred.
 | 
			
		||||
 | 
			
		||||
            View *addView (CSMDoc::Document *document, const CSMWorld::UniversalId& id, const std::string& hint);
 | 
			
		||||
 | 
			
		||||
            int countViews (const CSMDoc::Document *document) const;
 | 
			
		||||
            ///< Return number of views for \a document.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@ CSVFilter::RecordFilterBox::RecordFilterBox (CSMWorld::Data& data, QWidget *pare
 | 
			
		|||
{
 | 
			
		||||
    QHBoxLayout *layout = new QHBoxLayout (this);
 | 
			
		||||
 | 
			
		||||
    layout->setContentsMargins (0, 0, 0, 0);
 | 
			
		||||
    layout->setContentsMargins (0, 6, 5, 0);
 | 
			
		||||
 | 
			
		||||
    QLabel *label = new QLabel("Record Filter", this);
 | 
			
		||||
    label->setIndent(2);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@
 | 
			
		|||
#include <OgreViewport.h>
 | 
			
		||||
 | 
			
		||||
#include "../widget/scenetoolmode.hpp"
 | 
			
		||||
#include "../../model/settings/usersettings.hpp"
 | 
			
		||||
 | 
			
		||||
#include "navigation.hpp"
 | 
			
		||||
#include "lighting.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +28,7 @@ namespace CSVRender
 | 
			
		|||
        , mKeyForward (false), mKeyBackward (false), mKeyLeft (false), mKeyRight (false)
 | 
			
		||||
        , mKeyRollLeft (false), mKeyRollRight (false)
 | 
			
		||||
        , mFast (false), mDragging (false), mMod1 (false)
 | 
			
		||||
        , mFastFactor (4) /// \todo make this configurable
 | 
			
		||||
        , mFastFactor (4)
 | 
			
		||||
        , mDefaultAmbient (0, 0, 0, 0), mHasDefaultAmbient (false)
 | 
			
		||||
    {
 | 
			
		||||
        setAttribute(Qt::WA_PaintOnScreen);
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +45,14 @@ namespace CSVRender
 | 
			
		|||
        mCamera->setPosition (300, 0, 0);
 | 
			
		||||
        mCamera->lookAt (0, 0, 0);
 | 
			
		||||
        mCamera->setNearClipDistance (0.1);
 | 
			
		||||
        mCamera->setFarClipDistance (300000); ///< \todo make this configurable
 | 
			
		||||
 | 
			
		||||
        CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
 | 
			
		||||
 | 
			
		||||
        float farClipDist = userSettings.setting("Scene/far clip distance", QString("300000")).toFloat();
 | 
			
		||||
        mCamera->setFarClipDistance (farClipDist);
 | 
			
		||||
 | 
			
		||||
        mFastFactor = userSettings.setting("Scene/fast factor", QString("4")).toInt();
 | 
			
		||||
 | 
			
		||||
        mCamera->roll (Ogre::Degree (90));
 | 
			
		||||
 | 
			
		||||
        setLighting (&mLightingDay);
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +60,9 @@ namespace CSVRender
 | 
			
		|||
        QTimer *timer = new QTimer (this);
 | 
			
		||||
 | 
			
		||||
        connect (timer, SIGNAL (timeout()), this, SLOT (update()));
 | 
			
		||||
        timer->start (20); ///< \todo make this configurable
 | 
			
		||||
 | 
			
		||||
        int timerStart = userSettings.setting("Scene/timer start", QString("20")).toInt();
 | 
			
		||||
        timer->start (timerStart);
 | 
			
		||||
 | 
			
		||||
        /// \todo make shortcut configurable
 | 
			
		||||
        QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +128,16 @@ namespace CSVRender
 | 
			
		|||
 | 
			
		||||
        params.insert(std::make_pair("externalWindowHandle",  windowHandle.str()));
 | 
			
		||||
        params.insert(std::make_pair("title", windowTitle.str()));
 | 
			
		||||
        params.insert(std::make_pair("FSAA", "0")); // TODO setting
 | 
			
		||||
 | 
			
		||||
        std::string antialiasing =
 | 
			
		||||
            CSMSettings::UserSettings::instance().settingValue("Video/antialiasing").toStdString();
 | 
			
		||||
        if(antialiasing == "MSAA 16")     antialiasing = "16";
 | 
			
		||||
        else if(antialiasing == "MSAA 8") antialiasing = "8";
 | 
			
		||||
        else if(antialiasing == "MSAA 4") antialiasing = "4";
 | 
			
		||||
        else if(antialiasing == "MSAA 2") antialiasing = "2";
 | 
			
		||||
        else                              antialiasing = "0";
 | 
			
		||||
        params.insert(std::make_pair("FSAA", antialiasing));
 | 
			
		||||
 | 
			
		||||
        params.insert(std::make_pair("vsync", "false")); // TODO setting
 | 
			
		||||
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
 | 
			
		||||
        params.insert(std::make_pair("macAPI", "cocoa"));
 | 
			
		||||
| 
						 | 
				
			
			@ -382,4 +401,32 @@ namespace CSVRender
 | 
			
		|||
        else if (mode=="bright")
 | 
			
		||||
            setLighting (&mLightingBright);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SceneWidget::updateUserSetting (const QString &key, const QStringList &list)
 | 
			
		||||
    {
 | 
			
		||||
        if(key.contains(QRegExp("^\\b(Objects|Shader|Scene)", Qt::CaseInsensitive)))
 | 
			
		||||
            flagAsModified();
 | 
			
		||||
 | 
			
		||||
        if(key == "Scene/far clip distance" && !list.empty())
 | 
			
		||||
        {
 | 
			
		||||
            if(mCamera->getFarClipDistance() != list.at(0).toFloat())
 | 
			
		||||
                mCamera->setFarClipDistance(list.at(0).toFloat());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // minimise unnecessary ogre window creation by updating only when there is a change
 | 
			
		||||
        if(key == "Video/antialiasing")
 | 
			
		||||
        {
 | 
			
		||||
            unsigned int aa = mWindow->getFSAA();
 | 
			
		||||
            unsigned int antialiasing = 0;
 | 
			
		||||
            if(!list.empty())
 | 
			
		||||
            {
 | 
			
		||||
                if(list.at(0) == "MSAA 16")     antialiasing = 16;
 | 
			
		||||
                else if(list.at(0) == "MSAA 8") antialiasing = 8;
 | 
			
		||||
                else if(list.at(0) == "MSAA 4") antialiasing = 4;
 | 
			
		||||
                else if(list.at(0) == "MSAA 2") antialiasing = 2;
 | 
			
		||||
            }
 | 
			
		||||
            if(aa != antialiasing)
 | 
			
		||||
                updateOgreWindow();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -108,6 +108,10 @@ namespace CSVRender
 | 
			
		|||
            LightingNight mLightingNight;
 | 
			
		||||
            LightingBright mLightingBright;
 | 
			
		||||
 | 
			
		||||
        public slots:
 | 
			
		||||
 | 
			
		||||
            void updateUserSetting (const QString &key, const QStringList &list);
 | 
			
		||||
 | 
			
		||||
        private slots:
 | 
			
		||||
 | 
			
		||||
            void update();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,16 +12,27 @@
 | 
			
		|||
 | 
			
		||||
CSVSettings::BooleanView::BooleanView (CSMSettings::Setting *setting,
 | 
			
		||||
                                       Page *parent)
 | 
			
		||||
    : View (setting, parent)
 | 
			
		||||
    : mType(setting->type()), View (setting, parent)
 | 
			
		||||
{
 | 
			
		||||
    foreach (const QString &value, setting->declaredValues())
 | 
			
		||||
    {
 | 
			
		||||
        QAbstractButton *button = 0;
 | 
			
		||||
 | 
			
		||||
        switch (setting->type())
 | 
			
		||||
        switch (mType)
 | 
			
		||||
        {
 | 
			
		||||
        case CSMSettings::Type_CheckBox:
 | 
			
		||||
            button = new QCheckBox (value, this);
 | 
			
		||||
        case CSMSettings::Type_CheckBox: {
 | 
			
		||||
                if(mButtons.empty()) // show only one for checkboxes
 | 
			
		||||
                {
 | 
			
		||||
                    button = new QCheckBox (value, this);
 | 
			
		||||
                    button->setChecked (setting->defaultValues().at(0) == "true" ? true : false);
 | 
			
		||||
 | 
			
		||||
                    // special visual treatment option for checkboxes
 | 
			
		||||
                    if(setting->specialValueText() != "") {
 | 
			
		||||
                        Frame::setTitle("");
 | 
			
		||||
                        button->setText(setting->specialValueText());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case CSMSettings::Type_RadioButton:
 | 
			
		||||
| 
						 | 
				
			
			@ -32,14 +43,17 @@ CSVSettings::BooleanView::BooleanView (CSMSettings::Setting *setting,
 | 
			
		|||
        break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        connect (button, SIGNAL (clicked (bool)),
 | 
			
		||||
                this, SLOT (slotToggled (bool)));
 | 
			
		||||
        if(button && (mType != CSMSettings::Type_CheckBox || mButtons.empty()))
 | 
			
		||||
        {
 | 
			
		||||
            connect (button, SIGNAL (clicked (bool)),
 | 
			
		||||
                    this, SLOT (slotToggled (bool)));
 | 
			
		||||
 | 
			
		||||
        button->setObjectName (value);
 | 
			
		||||
            button->setObjectName (value);
 | 
			
		||||
 | 
			
		||||
        addWidget (button);
 | 
			
		||||
            addWidget (button);
 | 
			
		||||
 | 
			
		||||
        mButtons[value] = button;
 | 
			
		||||
            mButtons[value] = button;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,8 +67,14 @@ void CSVSettings::BooleanView::slotToggled (bool state)
 | 
			
		|||
 | 
			
		||||
    foreach (QString key, mButtons.keys())
 | 
			
		||||
    {
 | 
			
		||||
        if (mButtons.value(key)->isChecked())
 | 
			
		||||
            values.append (key);
 | 
			
		||||
        // checkbox values are true/false unlike radio buttons
 | 
			
		||||
        if(mType == CSMSettings::Type_CheckBox)
 | 
			
		||||
            values.append(mButtons.value(key)->isChecked() ? "true" : "false");
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (mButtons.value(key)->isChecked())
 | 
			
		||||
                values.append (key);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    setSelectedValues (values, false);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@ namespace CSVSettings
 | 
			
		|||
        Q_OBJECT
 | 
			
		||||
 | 
			
		||||
        QMap <QString, QAbstractButton *> mButtons;
 | 
			
		||||
        enum CSMSettings::SettingType mType;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        explicit BooleanView (CSMSettings::Setting *setting,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
#include <QWidget>
 | 
			
		||||
 | 
			
		||||
const QString CSVSettings::Frame::sInvisibleBoxStyle =
 | 
			
		||||
    QString::fromUtf8("Frame { border:2px; padding 2px; margin: 2px;}");
 | 
			
		||||
    QString::fromUtf8("Frame { border:2px; padding: 2px; margin: 2px;}");
 | 
			
		||||
 | 
			
		||||
CSVSettings::Frame::Frame (bool isVisible, const QString &title,
 | 
			
		||||
                                                               QWidget *parent)
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +14,11 @@ CSVSettings::Frame::Frame (bool isVisible, const QString &title,
 | 
			
		|||
    mVisibleBoxStyle = styleSheet();
 | 
			
		||||
 | 
			
		||||
    if (!isVisible)
 | 
			
		||||
    {
 | 
			
		||||
        // must be Page, not a View
 | 
			
		||||
        setStyleSheet (sInvisibleBoxStyle);
 | 
			
		||||
        mLayout->setContentsMargins(10, 15, 10, 15);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setLayout (mLayout);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,7 @@
 | 
			
		|||
#include "page.hpp"
 | 
			
		||||
 | 
			
		||||
#include <QLabel>
 | 
			
		||||
 | 
			
		||||
#include "view.hpp"
 | 
			
		||||
#include "booleanview.hpp"
 | 
			
		||||
#include "textview.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +41,18 @@ void CSVSettings::Page::setupViews
 | 
			
		|||
void CSVSettings::Page::addView (CSMSettings::Setting *setting)
 | 
			
		||||
{
 | 
			
		||||
    if (setting->viewType() == ViewType_Undefined)
 | 
			
		||||
        return;
 | 
			
		||||
    {
 | 
			
		||||
        if(setting->specialValueText() != "")
 | 
			
		||||
        {
 | 
			
		||||
            // hack to put a label
 | 
			
		||||
            addWidget(new QLabel(setting->specialValueText()),
 | 
			
		||||
                setting->viewRow(), setting->viewColumn(),
 | 
			
		||||
                setting->rowSpan(), setting->columnSpan());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    View *view = mViewFactories[setting->viewType()]->createView(setting, this);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,8 +36,11 @@ CSVSettings::RangeView::RangeView (CSMSettings::Setting *setting,
 | 
			
		|||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mRangeWidget->setFixedWidth (widgetWidth (setting->widgetWidth()));
 | 
			
		||||
    mRangeWidget->setObjectName (setting->name());
 | 
			
		||||
    if(mRangeWidget)
 | 
			
		||||
    {
 | 
			
		||||
        mRangeWidget->setFixedWidth (widgetWidth (setting->widgetWidth()));
 | 
			
		||||
        mRangeWidget->setObjectName (setting->name());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addWidget (mRangeWidget);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -75,13 +78,16 @@ void CSVSettings::RangeView::buildSlider (CSMSettings::Setting *setting)
 | 
			
		|||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mRangeWidget->setProperty ("minimum", setting->minimum());
 | 
			
		||||
    mRangeWidget->setProperty ("maximum", setting->maximum());
 | 
			
		||||
    mRangeWidget->setProperty ("tracking", false);
 | 
			
		||||
    mRangeWidget->setProperty ("singleStep", setting->singleStep());
 | 
			
		||||
    if(mRangeWidget)
 | 
			
		||||
    {
 | 
			
		||||
        mRangeWidget->setProperty ("minimum", setting->minimum());
 | 
			
		||||
        mRangeWidget->setProperty ("maximum", setting->maximum());
 | 
			
		||||
        mRangeWidget->setProperty ("tracking", false);
 | 
			
		||||
        mRangeWidget->setProperty ("singleStep", setting->singleStep());
 | 
			
		||||
 | 
			
		||||
    connect (mRangeWidget, SIGNAL (valueChanged (int)),
 | 
			
		||||
             this, SLOT (slotUpdateView (int)));
 | 
			
		||||
        connect (mRangeWidget, SIGNAL (valueChanged (int)),
 | 
			
		||||
                 this, SLOT (slotUpdateView (int)));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVSettings::RangeView::buildSpinBox (CSMSettings::Setting *setting)
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +133,10 @@ void CSVSettings::RangeView::buildSpinBox (CSMSettings::Setting *setting)
 | 
			
		|||
    mRangeWidget->setProperty ("prefix", setting->prefix());
 | 
			
		||||
    mRangeWidget->setProperty ("suffix", setting->suffix());
 | 
			
		||||
    mRangeWidget->setProperty ("wrapping", setting->wrapping());
 | 
			
		||||
    dynamic_cast<QAbstractSpinBox *> (mRangeWidget)->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
 | 
			
		||||
 | 
			
		||||
    if(setting->type()  == CSMSettings::Type_SpinBox && setting->declaredValues().isEmpty())
 | 
			
		||||
        dynamic_cast<QSpinBox *> (mRangeWidget)->setValue (setting->defaultValues().at(0).toInt());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVSettings::RangeView::slotUpdateView (int value)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ void CSVSettings::SettingWindow::createPages()
 | 
			
		|||
    QList <CSMSettings::Setting *> connectedSettings;
 | 
			
		||||
 | 
			
		||||
    foreach (const QString &pageName, pageMap.keys())
 | 
			
		||||
    {        
 | 
			
		||||
    {
 | 
			
		||||
        QList <CSMSettings::Setting *> pageSettings = pageMap.value (pageName);
 | 
			
		||||
 | 
			
		||||
        mPages.append (new Page (pageName, pageSettings, this));
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +129,3 @@ void CSVSettings::SettingWindow::saveSettings()
 | 
			
		|||
    mModel->saveDefinitions();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVSettings::SettingWindow::closeEvent (QCloseEvent *event)
 | 
			
		||||
{
 | 
			
		||||
    QApplication::focusWidget()->clearFocus();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,8 +36,6 @@ namespace CSVSettings {
 | 
			
		|||
 | 
			
		||||
    protected:
 | 
			
		||||
 | 
			
		||||
        virtual void closeEvent (QCloseEvent *event);
 | 
			
		||||
 | 
			
		||||
        ///construct the pages to be displayed in the dialog
 | 
			
		||||
        void createPages();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ QString CSVSettings::SpinBox::textFromValue(int val) const
 | 
			
		|||
int CSVSettings::SpinBox::valueFromText(const QString &text) const
 | 
			
		||||
{
 | 
			
		||||
    if (mValueList.isEmpty())
 | 
			
		||||
        return -1;
 | 
			
		||||
        return text.toInt(); // TODO: assumed integer, untested error handling for alpha types
 | 
			
		||||
 | 
			
		||||
    if (mValueList.contains (text))
 | 
			
		||||
        return mValueList.indexOf(text);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,9 @@ CSVSettings::View::View(CSMSettings::Setting *setting,
 | 
			
		|||
    setObjectName (setting->name());
 | 
			
		||||
    buildView();
 | 
			
		||||
    buildModel (setting);
 | 
			
		||||
    // apply stylesheet to view's frame if exists
 | 
			
		||||
    if(setting->styleSheet() != "")
 | 
			
		||||
        Frame::setStyleSheet (setting->styleSheet());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVSettings::View::buildModel (const CSMSettings::Setting *setting)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -392,7 +392,6 @@ void CSVWorld::EditWidget::remake(int row)
 | 
			
		|||
 | 
			
		||||
    mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0));
 | 
			
		||||
 | 
			
		||||
    this->setMinimumWidth(325); /// \todo replace hardcoded value with a user setting
 | 
			
		||||
    this->setWidget(mMainWidget);
 | 
			
		||||
    this->setWidgetResizable(true);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -247,6 +247,8 @@ void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceW
 | 
			
		|||
    mToolbar = toolbar;
 | 
			
		||||
 | 
			
		||||
    connect (mScene, SIGNAL (focusToolbarRequest()), mToolbar, SLOT (setFocus()));
 | 
			
		||||
    connect (this, SIGNAL (updateSceneUserSetting(const QString &, const QStringList &)),
 | 
			
		||||
            mScene, SLOT (updateUserSetting(const QString &, const QStringList &)));
 | 
			
		||||
    connect (mToolbar, SIGNAL (focusSceneRequest()), mScene, SLOT (setFocus()));
 | 
			
		||||
 | 
			
		||||
    mLayout->addWidget (mToolbar, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -254,4 +256,9 @@ void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceW
 | 
			
		|||
 | 
			
		||||
    mScene->selectDefaultNavigationMode();
 | 
			
		||||
    setFocusProxy (mScene);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSVWorld::SceneSubView::updateUserSetting (const QString &key, const QStringList &list)
 | 
			
		||||
{
 | 
			
		||||
    emit updateSceneUserSetting(key, list);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,6 +82,14 @@ namespace CSVWorld
 | 
			
		|||
            void cellSelectionChanged (const CSMWorld::UniversalId& id);
 | 
			
		||||
 | 
			
		||||
            void handleDrop(const std::vector<CSMWorld::UniversalId>& data);
 | 
			
		||||
 | 
			
		||||
        public slots:
 | 
			
		||||
 | 
			
		||||
            void updateUserSetting (const QString &, const QStringList &);
 | 
			
		||||
 | 
			
		||||
        signals:
 | 
			
		||||
 | 
			
		||||
            void updateSceneUserSetting (const QString &, const QStringList &);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ add_openmw_dir (mwgui
 | 
			
		|||
    merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
 | 
			
		||||
    keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
 | 
			
		||||
    tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
 | 
			
		||||
    recharge mode videowidget backgroundimage itemwidget screenfader
 | 
			
		||||
    recharge mode videowidget backgroundimage itemwidget screenfader debugwindow
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
add_openmw_dir (mwdialogue
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -177,7 +177,7 @@ namespace MWBase
 | 
			
		|||
            virtual void changeCell(MWWorld::CellStore* cell) = 0;
 | 
			
		||||
            ///< change the active cell
 | 
			
		||||
 | 
			
		||||
            virtual void setPlayerPos(const float x, const float y) = 0;
 | 
			
		||||
            virtual void setPlayerPos(int cellX, int cellY, const float x, const float y) = 0;
 | 
			
		||||
            ///< set player position in map space
 | 
			
		||||
 | 
			
		||||
            virtual void setPlayerDir(const float x, const float y) = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -337,6 +337,8 @@ namespace MWBase
 | 
			
		|||
            virtual void fadeScreenTo(const int percent, const float time) = 0;
 | 
			
		||||
            /// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading.
 | 
			
		||||
            virtual void setScreenFactor (float factor) = 0;
 | 
			
		||||
 | 
			
		||||
            virtual void toggleDebugWindow() = 0;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -119,6 +119,7 @@ namespace MWBase
 | 
			
		|||
            virtual void setWaterHeight(const float height) = 0;
 | 
			
		||||
 | 
			
		||||
            virtual bool toggleWater() = 0;
 | 
			
		||||
            virtual bool toggleWorld() = 0;
 | 
			
		||||
 | 
			
		||||
            virtual void adjustSky() = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +137,7 @@ namespace MWBase
 | 
			
		|||
            virtual MWWorld::LocalScripts& getLocalScripts() = 0;
 | 
			
		||||
 | 
			
		||||
            virtual bool hasCellChanged() const = 0;
 | 
			
		||||
            ///< Has the player moved to a different cell, since the last frame?
 | 
			
		||||
            ///< Has the set of active cells changed, since the last frame?
 | 
			
		||||
 | 
			
		||||
            virtual bool isCellExterior() const = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ MWWorld::Ptr ContainerItemModel::copyItem (const ItemStack& item, size_t count,
 | 
			
		|||
    const MWWorld::Ptr& source = mItemSources[mItemSources.size()-1];
 | 
			
		||||
    if (item.mBase.getContainerStore() == &source.getClass().getContainerStore(source))
 | 
			
		||||
        throw std::runtime_error("Item to copy needs to be from a different container!");
 | 
			
		||||
    return *source.getClass().getContainerStore(source).add(item.mBase, count, source, setNewOwner);
 | 
			
		||||
    return *source.getClass().getContainerStore(source).add(item.mBase, count, source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										116
									
								
								apps/openmw/mwgui/debugwindow.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								apps/openmw/mwgui/debugwindow.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,116 @@
 | 
			
		|||
#include "debugwindow.hpp"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <LinearMath/btQuickprof.h>
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
    void bulletDumpRecursive(CProfileIterator* pit, int spacing, std::stringstream& os)
 | 
			
		||||
    {
 | 
			
		||||
        pit->First();
 | 
			
		||||
        if (pit->Is_Done())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        float accumulated_time=0,parent_time = pit->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : pit->Get_Current_Parent_Total_Time();
 | 
			
		||||
        int i,j;
 | 
			
		||||
        int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
 | 
			
		||||
        for (i=0;i<spacing;i++)	os << ".";
 | 
			
		||||
        os << "----------------------------------\n";
 | 
			
		||||
        for (i=0;i<spacing;i++)	os << ".";
 | 
			
		||||
        std::string s = "Profiling: "+
 | 
			
		||||
                std::string(pit->Get_Current_Parent_Name())+" (total running time: "+MyGUI::utility::toString(parent_time,3)+" ms) ---\n";
 | 
			
		||||
        os << s;
 | 
			
		||||
        //float totalTime = 0.f;
 | 
			
		||||
 | 
			
		||||
        int numChildren = 0;
 | 
			
		||||
 | 
			
		||||
        for (i = 0; !pit->Is_Done(); i++,pit->Next())
 | 
			
		||||
        {
 | 
			
		||||
            numChildren++;
 | 
			
		||||
            float current_total_time = pit->Get_Current_Total_Time();
 | 
			
		||||
            accumulated_time += current_total_time;
 | 
			
		||||
            float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
 | 
			
		||||
 | 
			
		||||
            for (j=0;j<spacing;j++)	os << ".";
 | 
			
		||||
            double ms = (current_total_time / (double)frames_since_reset);
 | 
			
		||||
            s = MyGUI::utility::toString(i)+" -- "+pit->Get_Current_Name()+" ("+MyGUI::utility::toString(fraction,2)+" %) :: "+MyGUI::utility::toString(ms,3)+" ms / frame ("+MyGUI::utility::toString(pit->Get_Current_Total_Calls())+" calls)\n";
 | 
			
		||||
            os << s;
 | 
			
		||||
            //totalTime += current_total_time;
 | 
			
		||||
            //recurse into children
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (parent_time < accumulated_time)
 | 
			
		||||
        {
 | 
			
		||||
            os << "what's wrong\n";
 | 
			
		||||
        }
 | 
			
		||||
        for (i=0;i<spacing;i++)	os << ".";
 | 
			
		||||
        double unaccounted=  parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f;
 | 
			
		||||
        s = "Unaccounted: ("+MyGUI::utility::toString(unaccounted,3)+" %) :: "+MyGUI::utility::toString(parent_time - accumulated_time,3)+" ms\n";
 | 
			
		||||
        os << s;
 | 
			
		||||
 | 
			
		||||
        for (i=0;i<numChildren;i++)
 | 
			
		||||
        {
 | 
			
		||||
            pit->Enter_Child(i);
 | 
			
		||||
            bulletDumpRecursive(pit, spacing+3, os);
 | 
			
		||||
            pit->Enter_Parent();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void bulletDumpAll(std::stringstream& os)
 | 
			
		||||
    {
 | 
			
		||||
        CProfileIterator* profileIterator = 0;
 | 
			
		||||
        profileIterator = CProfileManager::Get_Iterator();
 | 
			
		||||
 | 
			
		||||
        bulletDumpRecursive(profileIterator, 0, os);
 | 
			
		||||
 | 
			
		||||
        CProfileManager::Release_Iterator(profileIterator);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace MWGui
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    DebugWindow::DebugWindow()
 | 
			
		||||
        : WindowBase("openmw_debug_window.layout")
 | 
			
		||||
    {
 | 
			
		||||
        getWidget(mTabControl, "TabControl");
 | 
			
		||||
 | 
			
		||||
        // Ideas for other tabs:
 | 
			
		||||
        // - Texture / compositor texture viewer
 | 
			
		||||
        // - Log viewer
 | 
			
		||||
        // - Material editor
 | 
			
		||||
        // - Shader editor
 | 
			
		||||
 | 
			
		||||
        MyGUI::TabItem* item = mTabControl->addItem("Physics Profiler");
 | 
			
		||||
        mBulletProfilerEdit = item->createWidgetReal<MyGUI::EditBox>
 | 
			
		||||
                ("LogEdit", MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Stretch);
 | 
			
		||||
 | 
			
		||||
        MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
 | 
			
		||||
        mMainWidget->setSize(viewSize);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void DebugWindow::onFrame(float dt)
 | 
			
		||||
    {
 | 
			
		||||
        if (!isVisible())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        static float timer = 0;
 | 
			
		||||
        timer -= dt;
 | 
			
		||||
 | 
			
		||||
        if (timer > 0)
 | 
			
		||||
            return;
 | 
			
		||||
        timer = 1;
 | 
			
		||||
 | 
			
		||||
        std::stringstream stream;
 | 
			
		||||
        bulletDumpAll(stream);
 | 
			
		||||
 | 
			
		||||
        if (mBulletProfilerEdit->isTextSelection()) // pause updating while user is trying to copy text
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        size_t previousPos = mBulletProfilerEdit->getVScrollPosition();
 | 
			
		||||
        mBulletProfilerEdit->setCaption(stream.str());
 | 
			
		||||
        mBulletProfilerEdit->setVScrollPosition(std::min(previousPos, mBulletProfilerEdit->getVScrollRange()-1));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								apps/openmw/mwgui/debugwindow.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								apps/openmw/mwgui/debugwindow.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
#ifndef OPENMW_MWGUI_DEBUGWINDOW_H
 | 
			
		||||
#define OPENMW_MWGUI_DEBUGWINDOW_H
 | 
			
		||||
 | 
			
		||||
#include "windowbase.hpp"
 | 
			
		||||
 | 
			
		||||
namespace MWGui
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    class DebugWindow : public WindowBase
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        DebugWindow();
 | 
			
		||||
 | 
			
		||||
        void onFrame(float dt);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        MyGUI::TabControl* mTabControl;
 | 
			
		||||
 | 
			
		||||
        MyGUI::EditBox* mBulletProfilerEdit;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -562,12 +562,11 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
        MyGUI::Button* byeButton;
 | 
			
		||||
        getWidget(byeButton, "ByeButton");
 | 
			
		||||
        if(MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye) {
 | 
			
		||||
            byeButton->setEnabled(false);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            byeButton->setEnabled(true);
 | 
			
		||||
        }
 | 
			
		||||
        bool goodbyeEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() || mGoodbye;
 | 
			
		||||
        byeButton->setEnabled(goodbyeEnabled);
 | 
			
		||||
 | 
			
		||||
        bool topicsEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye;
 | 
			
		||||
        mTopicsList->setEnabled(topicsEnabled);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void DialogueWindow::notifyLinkClicked (TypesetBook::InteractiveId link)
 | 
			
		||||
| 
						 | 
				
			
			@ -657,7 +656,6 @@ namespace MWGui
 | 
			
		|||
    {
 | 
			
		||||
        mLinks.push_back(new Goodbye());
 | 
			
		||||
        mGoodbye = true;
 | 
			
		||||
        mTopicsList->setEnabled(false);
 | 
			
		||||
        mEnabled = false;
 | 
			
		||||
        updateHistory();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -201,12 +201,23 @@ struct JournalViewModelImpl : JournalViewModel
 | 
			
		|||
 | 
			
		||||
        std::set<std::string> visitedQuests;
 | 
			
		||||
 | 
			
		||||
        // Note that for purposes of the journal GUI, quests are identified by the name, not the ID, so several
 | 
			
		||||
        // different quest IDs can end up in the same quest log. A quest log should be considered finished
 | 
			
		||||
        // when any quest ID in that log is finished.
 | 
			
		||||
        for (MWBase::Journal::TQuestIter i = journal->questBegin (); i != journal->questEnd (); ++i)
 | 
			
		||||
        {
 | 
			
		||||
            if (active_only && i->second.isFinished ())
 | 
			
		||||
            const MWDialogue::Quest& quest = i->second;
 | 
			
		||||
 | 
			
		||||
            bool isFinished = false;
 | 
			
		||||
            for (MWBase::Journal::TQuestIter j = journal->questBegin (); j != journal->questEnd (); ++j)
 | 
			
		||||
            {
 | 
			
		||||
                if (quest.getName() == j->second.getName() && j->second.isFinished())
 | 
			
		||||
                    isFinished = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (active_only && isFinished)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            const MWDialogue::Quest& quest = i->second;
 | 
			
		||||
            // Unfortunately Morrowind.esm has no quest names, since the quest book was added with tribunal.
 | 
			
		||||
            // Note that even with Tribunal, some quests still don't have quest names. I'm assuming those are not supposed
 | 
			
		||||
            // to appear in the quest book.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -490,7 +490,7 @@ namespace
 | 
			
		|||
                unsigned int  & page = mStates.top ().mPage;
 | 
			
		||||
                Book   book = mStates.top ().mBook;
 | 
			
		||||
 | 
			
		||||
                if (page < book->pageCount () - 2)
 | 
			
		||||
                if (page+2 < book->pageCount())
 | 
			
		||||
                {
 | 
			
		||||
                    page += 2;
 | 
			
		||||
                    updateShowingPages ();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -159,8 +159,6 @@ namespace MWGui
 | 
			
		|||
        , mLocalMap(NULL)
 | 
			
		||||
        , mPrefix()
 | 
			
		||||
        , mChanged(true)
 | 
			
		||||
        , mLastPositionX(0.0f)
 | 
			
		||||
        , mLastPositionY(0.0f)
 | 
			
		||||
        , mLastDirectionX(0.0f)
 | 
			
		||||
        , mLastDirectionY(0.0f)
 | 
			
		||||
        , mCompass(NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -425,24 +423,22 @@ namespace MWGui
 | 
			
		|||
        mLocalMap->getParent()->_updateChilds();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void LocalMapBase::setPlayerPos(const float x, const float y)
 | 
			
		||||
    void LocalMapBase::setPlayerPos(int cellX, int cellY, const float nx, const float ny)
 | 
			
		||||
    {
 | 
			
		||||
        updateMagicMarkers();
 | 
			
		||||
        MyGUI::IntPoint pos(widgetSize+nx*widgetSize-16, widgetSize+ny*widgetSize-16);
 | 
			
		||||
        pos.left += (cellX - mCurX) * widgetSize;
 | 
			
		||||
        pos.top -= (cellY - mCurY) * widgetSize;
 | 
			
		||||
 | 
			
		||||
        if (x == mLastPositionX && y == mLastPositionY)
 | 
			
		||||
            return;
 | 
			
		||||
        if (pos != mCompass->getPosition())
 | 
			
		||||
        {
 | 
			
		||||
            notifyPlayerUpdate ();
 | 
			
		||||
 | 
			
		||||
        notifyPlayerUpdate ();
 | 
			
		||||
 | 
			
		||||
        MyGUI::IntSize size = mLocalMap->getCanvasSize();
 | 
			
		||||
        MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
 | 
			
		||||
        MyGUI::IntCoord viewsize = mLocalMap->getCoord();
 | 
			
		||||
        MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
 | 
			
		||||
        mLocalMap->setViewOffset(pos);
 | 
			
		||||
 | 
			
		||||
        mCompass->setPosition(MyGUI::IntPoint(widgetSize+x*widgetSize-16, widgetSize+y*widgetSize-16));
 | 
			
		||||
        mLastPositionX = x;
 | 
			
		||||
        mLastPositionY = y;
 | 
			
		||||
            mCompass->setPosition(pos);
 | 
			
		||||
            MyGUI::IntPoint middle (pos.left+16, pos.top+16);
 | 
			
		||||
                    MyGUI::IntCoord viewsize = mLocalMap->getCoord();
 | 
			
		||||
            MyGUI::IntPoint viewOffset(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
 | 
			
		||||
            mLocalMap->setViewOffset(viewOffset);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void LocalMapBase::setPlayerDir(const float x, const float y)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ namespace MWGui
 | 
			
		|||
        void setCellPrefix(const std::string& prefix);
 | 
			
		||||
        void setActiveCell(const int x, const int y, bool interior=false);
 | 
			
		||||
        void setPlayerDir(const float x, const float y);
 | 
			
		||||
        void setPlayerPos(const float x, const float y);
 | 
			
		||||
        void setPlayerPos(int cellX, int cellY, const float nx, const float ny);
 | 
			
		||||
 | 
			
		||||
        void onFrame(float dt);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,8 +129,6 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
        float mMarkerUpdateTimer;
 | 
			
		||||
 | 
			
		||||
        float mLastPositionX;
 | 
			
		||||
        float mLastPositionY;
 | 
			
		||||
        float mLastDirectionX;
 | 
			
		||||
        float mLastDirectionY;
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -157,12 +157,11 @@ namespace MWGui
 | 
			
		|||
      , mMaxTime(0)
 | 
			
		||||
    {
 | 
			
		||||
        // defines
 | 
			
		||||
        mBottomPadding = 20;
 | 
			
		||||
        mNextBoxPadding = 20;
 | 
			
		||||
        mBottomPadding = 48;
 | 
			
		||||
        mNextBoxPadding = 4;
 | 
			
		||||
 | 
			
		||||
        getWidget(mMessageWidget, "message");
 | 
			
		||||
 | 
			
		||||
        mMessageWidget->setOverflowToTheLeft(true);
 | 
			
		||||
        mMessageWidget->setCaptionWithReplacing(mMessage);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -178,7 +177,7 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
    int MessageBox::getHeight ()
 | 
			
		||||
    {
 | 
			
		||||
        return mMainWidget->getHeight()+mNextBoxPadding; // 20 is the padding between this and the next MessageBox
 | 
			
		||||
        return mMainWidget->getHeight()+mNextBoxPadding;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +203,6 @@ namespace MWGui
 | 
			
		|||
        getWidget(mMessageWidget, "message");
 | 
			
		||||
        getWidget(mButtonsWidget, "buttons");
 | 
			
		||||
 | 
			
		||||
        mMessageWidget->setOverflowToTheLeft(true);
 | 
			
		||||
        mMessageWidget->setSize(400, mMessageWidget->getHeight());
 | 
			
		||||
        mMessageWidget->setCaptionWithReplacing(message);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,12 +41,11 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
        getWidget(mHeadRotate, "HeadRotate");
 | 
			
		||||
 | 
			
		||||
        // Mouse wheel step is hardcoded to 50 in MyGUI 3.2 ("FIXME").
 | 
			
		||||
        // Give other steps the same value to accomodate.
 | 
			
		||||
        mHeadRotate->setScrollRange(1000);
 | 
			
		||||
        mHeadRotate->setScrollPosition(500);
 | 
			
		||||
        mHeadRotate->setScrollViewPage(50);
 | 
			
		||||
        mHeadRotate->setScrollPage(50);
 | 
			
		||||
        mHeadRotate->setScrollWheelPage(50);
 | 
			
		||||
        mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate);
 | 
			
		||||
 | 
			
		||||
        // Set up next/previous buttons
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -322,7 +322,8 @@ namespace MWGui
 | 
			
		|||
            if (i == pos)
 | 
			
		||||
                mCurrentSlot = &*it;
 | 
			
		||||
        }
 | 
			
		||||
        assert(mCurrentSlot && "Can't find selected slot");
 | 
			
		||||
        if (!mCurrentSlot)
 | 
			
		||||
            throw std::runtime_error("Can't find selected slot");
 | 
			
		||||
 | 
			
		||||
        std::stringstream text;
 | 
			
		||||
        time_t time = mCurrentSlot->mTimeStamp;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,6 +100,15 @@ namespace MWGui
 | 
			
		|||
            if (spell->mData.mType!=ESM::Spell::ST_Spell)
 | 
			
		||||
                continue; // don't try to sell diseases, curses or powers
 | 
			
		||||
 | 
			
		||||
            if (actor.getClass().isNpc())
 | 
			
		||||
            {
 | 
			
		||||
                const ESM::Race* race =
 | 
			
		||||
                        MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(
 | 
			
		||||
                        actor.get<ESM::NPC>()->mBase->mRace);
 | 
			
		||||
                if (race->mPowers.exists(spell->mId))
 | 
			
		||||
                    continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (playerHasSpell(iter->first))
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -422,12 +422,12 @@ namespace MWGui
 | 
			
		|||
                y *= 1.5;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mSpell.mData.mCost = int(y);
 | 
			
		||||
 | 
			
		||||
        ESM::EffectList effectList;
 | 
			
		||||
        effectList.mList = mEffects;
 | 
			
		||||
        mSpell.mEffects = effectList;
 | 
			
		||||
        mSpell.mData.mCost = int(y);
 | 
			
		||||
        mSpell.mData.mType = ESM::Spell::ST_Spell;
 | 
			
		||||
        mSpell.mData.mFlags = 0;
 | 
			
		||||
 | 
			
		||||
        mMagickaCost->setCaption(boost::lexical_cast<std::string>(int(y)));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -119,7 +119,7 @@ namespace MWGui
 | 
			
		|||
        return mBorrowedToUs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void TradeItemModel::transferItems(const MWWorld::Ptr& transferFrom)
 | 
			
		||||
    void TradeItemModel::transferItems()
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<ItemStack>::iterator it = mBorrowedToUs.begin();
 | 
			
		||||
        for (; it != mBorrowedToUs.end(); ++it)
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
            bool setNewOwner = Misc::StringUtils::ciEqual(item.mBase.getCellRef().getOwner(), transferFrom.getCellRef().getRefId())
 | 
			
		||||
                    || item.mBase.getCellRef().getOwner().empty();
 | 
			
		||||
 | 
			
		||||
            // copy the borrowed items to our model
 | 
			
		||||
            copyItem(item, it->mCount, setNewOwner);
 | 
			
		||||
            // then remove them from the source model
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,8 +30,7 @@ namespace MWGui
 | 
			
		|||
        void returnItemBorrowedFromUs (ModelIndex itemIndex, ItemModel* source, size_t count);
 | 
			
		||||
 | 
			
		||||
        /// Permanently transfers items that were borrowed to us from another model to this model
 | 
			
		||||
        /// @param transferFrom the actor that lent us the items
 | 
			
		||||
        void transferItems (const MWWorld::Ptr& transferFrom);
 | 
			
		||||
        void transferItems ();
 | 
			
		||||
        /// Aborts trade
 | 
			
		||||
        void abort();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -370,8 +370,8 @@ namespace MWGui
 | 
			
		|||
            MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterSuccessDisposition);
 | 
			
		||||
 | 
			
		||||
        // make the item transfer
 | 
			
		||||
        mTradeModel->transferItems(player);
 | 
			
		||||
        playerItemModel->transferItems(mPtr);
 | 
			
		||||
        mTradeModel->transferItems();
 | 
			
		||||
        playerItemModel->transferItems();
 | 
			
		||||
 | 
			
		||||
        // transfer the gold
 | 
			
		||||
        if (mCurrentBalance != 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,8 @@ void WindowModal::close()
 | 
			
		|||
NoDrop::NoDrop(DragAndDrop *drag, MyGUI::Widget *widget)
 | 
			
		||||
    : mDrag(drag), mWidget(widget), mTransparent(false)
 | 
			
		||||
{
 | 
			
		||||
    if (!mWidget)
 | 
			
		||||
        throw std::runtime_error("NoDrop needs a non-NULL widget!");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NoDrop::onFrame(float dt)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,7 @@
 | 
			
		|||
#include "backgroundimage.hpp"
 | 
			
		||||
#include "itemwidget.hpp"
 | 
			
		||||
#include "screenfader.hpp"
 | 
			
		||||
#include "debugwindow.hpp"
 | 
			
		||||
 | 
			
		||||
namespace MWGui
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -120,6 +121,7 @@ namespace MWGui
 | 
			
		|||
      , mVideoBackground(NULL)
 | 
			
		||||
      , mVideoWidget(NULL)
 | 
			
		||||
      , mScreenFader(NULL)
 | 
			
		||||
      , mDebugWindow(NULL)
 | 
			
		||||
      , mTranslationDataStorage (translationDataStorage)
 | 
			
		||||
      , mCharGen(NULL)
 | 
			
		||||
      , mInputBlocker(NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -266,6 +268,7 @@ namespace MWGui
 | 
			
		|||
        mCompanionWindow = new CompanionWindow(mDragAndDrop, mMessageBoxManager);
 | 
			
		||||
        trackWindow(mCompanionWindow, "companion");
 | 
			
		||||
        mScreenFader = new ScreenFader();
 | 
			
		||||
        mDebugWindow = new DebugWindow();
 | 
			
		||||
 | 
			
		||||
        mInputBlocker = MyGUI::Gui::getInstance().createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Stretch,"Overlay");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -357,6 +360,7 @@ namespace MWGui
 | 
			
		|||
        delete mRecharge;
 | 
			
		||||
        delete mCompanionWindow;
 | 
			
		||||
        delete mScreenFader;
 | 
			
		||||
        delete mDebugWindow;
 | 
			
		||||
 | 
			
		||||
        cleanupGarbage();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -859,6 +863,8 @@ namespace MWGui
 | 
			
		|||
        mCompanionWindow->onFrame();
 | 
			
		||||
 | 
			
		||||
        mScreenFader->update(frameDuration);
 | 
			
		||||
 | 
			
		||||
        mDebugWindow->onFrame(frameDuration);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void WindowManager::changeCell(MWWorld::CellStore* cell)
 | 
			
		||||
| 
						 | 
				
			
			@ -874,9 +880,6 @@ namespace MWGui
 | 
			
		|||
                mMap->addVisitedLocation ("#{sCell=" + name + "}", cell->getCell()->getGridX (), cell->getCell()->getGridY ());
 | 
			
		||||
 | 
			
		||||
            mMap->cellExplored (cell->getCell()->getGridX(), cell->getCell()->getGridY());
 | 
			
		||||
 | 
			
		||||
            mMap->setCellPrefix("Cell");
 | 
			
		||||
            mHud->setCellPrefix("Cell");
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -894,14 +897,20 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
    void WindowManager::setActiveMap(int x, int y, bool interior)
 | 
			
		||||
    {
 | 
			
		||||
        if (!interior)
 | 
			
		||||
        {
 | 
			
		||||
            mMap->setCellPrefix("Cell");
 | 
			
		||||
            mHud->setCellPrefix("Cell");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mMap->setActiveCell(x,y, interior);
 | 
			
		||||
        mHud->setActiveCell(x,y, interior);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void WindowManager::setPlayerPos(const float x, const float y)
 | 
			
		||||
    void WindowManager::setPlayerPos(int cellX, int cellY, const float x, const float y)
 | 
			
		||||
    {
 | 
			
		||||
        mMap->setPlayerPos(x,y);
 | 
			
		||||
        mHud->setPlayerPos(x,y);
 | 
			
		||||
        mMap->setPlayerPos(cellX, cellY, x, y);
 | 
			
		||||
        mHud->setPlayerPos(cellX, cellY, x, y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void WindowManager::setPlayerDir(const float x, const float y)
 | 
			
		||||
| 
						 | 
				
			
			@ -1749,4 +1758,9 @@ namespace MWGui
 | 
			
		|||
        SDL_free(text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void WindowManager::toggleDebugWindow()
 | 
			
		||||
    {
 | 
			
		||||
        mDebugWindow->setVisible(!mDebugWindow->isVisible());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,6 +89,7 @@ namespace MWGui
 | 
			
		|||
  class VideoWidget;
 | 
			
		||||
  class WindowModal;
 | 
			
		||||
  class ScreenFader;
 | 
			
		||||
  class DebugWindow;
 | 
			
		||||
 | 
			
		||||
  class WindowManager : public MWBase::WindowManager
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -182,7 +183,7 @@ namespace MWGui
 | 
			
		|||
    virtual void updateSkillArea();                                                ///< update display of skills, factions, birth sign, reputation and bounty
 | 
			
		||||
 | 
			
		||||
    virtual void changeCell(MWWorld::CellStore* cell); ///< change the active cell
 | 
			
		||||
    virtual void setPlayerPos(const float x, const float y); ///< set player position in map space
 | 
			
		||||
    virtual void setPlayerPos(int cellX, int cellY, const float x, const float y); ///< set player position in map space
 | 
			
		||||
    virtual void setPlayerDir(const float x, const float y); ///< set player view direction in map space
 | 
			
		||||
 | 
			
		||||
    virtual void setFocusObject(const MWWorld::Ptr& focus);
 | 
			
		||||
| 
						 | 
				
			
			@ -333,6 +334,8 @@ namespace MWGui
 | 
			
		|||
    /// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading.
 | 
			
		||||
    virtual void setScreenFactor (float factor);
 | 
			
		||||
 | 
			
		||||
    virtual void toggleDebugWindow();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    bool mConsoleOnlyScripts;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -386,6 +389,7 @@ namespace MWGui
 | 
			
		|||
    MyGUI::ImageBox* mVideoBackground;
 | 
			
		||||
    VideoWidget* mVideoWidget;
 | 
			
		||||
    ScreenFader* mScreenFader;
 | 
			
		||||
    DebugWindow* mDebugWindow;
 | 
			
		||||
 | 
			
		||||
    Translation::Storage& mTranslationDataStorage;
 | 
			
		||||
    Cursor* mSoftwareCursor;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -279,6 +279,9 @@ namespace MWInput
 | 
			
		|||
            case A_ToggleHUD:
 | 
			
		||||
                MWBase::Environment::get().getWindowManager()->toggleGui();
 | 
			
		||||
                break;
 | 
			
		||||
            case A_ToggleDebug:
 | 
			
		||||
                MWBase::Environment::get().getWindowManager()->toggleDebugWindow();
 | 
			
		||||
                break;
 | 
			
		||||
            case A_QuickSave:
 | 
			
		||||
                quickSave();
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -902,6 +905,7 @@ namespace MWInput
 | 
			
		|||
        defaultKeyBindings[A_QuickKey10] = SDL_SCANCODE_0;
 | 
			
		||||
        defaultKeyBindings[A_Screenshot] = SDL_SCANCODE_F12;
 | 
			
		||||
        defaultKeyBindings[A_ToggleHUD] = SDL_SCANCODE_F11;
 | 
			
		||||
        defaultKeyBindings[A_ToggleDebug] = SDL_SCANCODE_F10;
 | 
			
		||||
        defaultKeyBindings[A_AlwaysRun] = SDL_SCANCODE_CAPSLOCK;
 | 
			
		||||
        defaultKeyBindings[A_QuickSave] = SDL_SCANCODE_F5;
 | 
			
		||||
        defaultKeyBindings[A_QuickLoad] = SDL_SCANCODE_F9;
 | 
			
		||||
| 
						 | 
				
			
			@ -932,9 +936,11 @@ namespace MWInput
 | 
			
		|||
            {
 | 
			
		||||
                clearAllBindings (control);
 | 
			
		||||
 | 
			
		||||
                if (defaultKeyBindings.find(i) != defaultKeyBindings.end())
 | 
			
		||||
                if (defaultKeyBindings.find(i) != defaultKeyBindings.end()
 | 
			
		||||
                        && !mInputBinder->isKeyBound(defaultKeyBindings[i]))
 | 
			
		||||
                    mInputBinder->addKeyBinding(control, defaultKeyBindings[i], ICS::Control::INCREASE);
 | 
			
		||||
                else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end())
 | 
			
		||||
                else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end()
 | 
			
		||||
                         && !mInputBinder->isMouseButtonBound(defaultMouseButtonBindings[i]))
 | 
			
		||||
                    mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -259,6 +259,8 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
            A_ToggleHUD,
 | 
			
		||||
 | 
			
		||||
            A_ToggleDebug,
 | 
			
		||||
 | 
			
		||||
            A_Last            // Marker for the last item
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -470,13 +470,13 @@ namespace MWMechanics
 | 
			
		|||
            return;
 | 
			
		||||
 | 
			
		||||
        MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
 | 
			
		||||
        const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
 | 
			
		||||
 | 
			
		||||
        int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
 | 
			
		||||
 | 
			
		||||
        // restore fatigue
 | 
			
		||||
        float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
 | 
			
		||||
        float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
 | 
			
		||||
        const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
 | 
			
		||||
        static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
 | 
			
		||||
        static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
 | 
			
		||||
 | 
			
		||||
        float x = fFatigueReturnBase + fFatigueReturnMult * endurance;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1122,20 +1122,21 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
            int hostilesCount = 0; // need to know this to play Battle music
 | 
			
		||||
 | 
			
		||||
            // AI processing is only done within distance of 7168 units to the player. Note the "AI distance" slider doesn't affect this
 | 
			
		||||
            // (it only does some throttling for targets beyond the "AI distance", so doesn't give any guarantees as to whether AI will be enabled or not)
 | 
			
		||||
            // This distance could be made configurable later, but the setting must be marked with a big warning:
 | 
			
		||||
            // using higher values will make a quest in Bloodmoon harder or impossible to complete (bug #1876)
 | 
			
		||||
            const float sqrProcessingDistance = 7168*7168;
 | 
			
		||||
 | 
			
		||||
             // AI and magic effects update
 | 
			
		||||
            for(PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
 | 
			
		||||
            {
 | 
			
		||||
                if (!iter->first.getClass().getCreatureStats(iter->first).isDead())
 | 
			
		||||
                {
 | 
			
		||||
                    updateActor(iter->first, duration);
 | 
			
		||||
 | 
			
		||||
                    // AI processing is only done within distance of 7168 units to the player. Note the "AI distance" slider doesn't affect this
 | 
			
		||||
                    // (it only does some throttling for targets beyond the "AI distance", so doesn't give any guarantees as to whether AI will be enabled or not)
 | 
			
		||||
                    // This distance could be made configurable later, but the setting must be marked with a big warning:
 | 
			
		||||
                    // using higher values will make a quest in Bloodmoon harder or impossible to complete (bug #1876)
 | 
			
		||||
                    if (MWBase::Environment::get().getMechanicsManager()->isAIActive() &&
 | 
			
		||||
                            Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(iter->first.getRefData().getPosition().pos))
 | 
			
		||||
                                    <= 7168*7168)
 | 
			
		||||
                                    <= sqrProcessingDistance)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (timerUpdateAITargets == 0)
 | 
			
		||||
                        {
 | 
			
		||||
| 
						 | 
				
			
			@ -1182,6 +1183,11 @@ namespace MWMechanics
 | 
			
		|||
            CharacterController* playerCharacter = NULL;
 | 
			
		||||
            for(PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
 | 
			
		||||
            {
 | 
			
		||||
                if (iter->first != player &&
 | 
			
		||||
                        Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(iter->first.getRefData().getPosition().pos))
 | 
			
		||||
                        > sqrProcessingDistance)
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                if (iter->first.getClass().getCreatureStats(iter->first).getMagicEffects().get(
 | 
			
		||||
                            ESM::MagicEffect::Paralyze).getMagnitude() > 0)
 | 
			
		||||
                    iter->second->skipAnim();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,7 +92,11 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
        if(distanceBetweenResult <= mMaxDist * mMaxDist)
 | 
			
		||||
        {
 | 
			
		||||
            if(pathTo(actor,ESM::Pathgrid::Point(mX,mY,mZ),duration)) //Returns true on path complete
 | 
			
		||||
            ESM::Pathgrid::Point point(mX,mY,mZ);
 | 
			
		||||
            point.mAutogenerated = 0;
 | 
			
		||||
            point.mConnectionNum = 0;
 | 
			
		||||
            point.mUnknown = 0;
 | 
			
		||||
            if(pathTo(actor,point,duration)) //Returns true on path complete
 | 
			
		||||
                return true;
 | 
			
		||||
            mMaxDist = 450;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -260,15 +260,14 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor)
 | 
			
		|||
 | 
			
		||||
    for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end(); ++it)
 | 
			
		||||
    {
 | 
			
		||||
        if(mPackages.front()->getPriority() <= package.getPriority())
 | 
			
		||||
        if((*it)->getPriority() <= package.getPriority())
 | 
			
		||||
        {
 | 
			
		||||
            mPackages.insert(it,package.clone());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(mPackages.empty())
 | 
			
		||||
        mPackages.push_front (package.clone());
 | 
			
		||||
    mPackages.push_front (package.clone());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AiPackage* MWMechanics::AiSequence::getActivePackage()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,7 +133,7 @@ void MWMechanics::Alchemy::updateEffects()
 | 
			
		|||
    std::set<EffectKey> effects (listEffects());
 | 
			
		||||
 | 
			
		||||
    // general alchemy factor
 | 
			
		||||
    float x = getChance();
 | 
			
		||||
    float x = getAlchemyFactor();
 | 
			
		||||
 | 
			
		||||
    x *= mTools[ESM::Apparatus::MortarPestle].get<ESM::Apparatus>()->mBase->mData.mQuality;
 | 
			
		||||
    x *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionStrengthMult")->getFloat();
 | 
			
		||||
| 
						 | 
				
			
			@ -306,18 +306,15 @@ void MWMechanics::Alchemy::increaseSkill()
 | 
			
		|||
    mAlchemist.getClass().skillUsageSucceeded (mAlchemist, ESM::Skill::Alchemy, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float MWMechanics::Alchemy::getChance() const
 | 
			
		||||
float MWMechanics::Alchemy::getAlchemyFactor() const
 | 
			
		||||
{
 | 
			
		||||
    const CreatureStats& creatureStats = mAlchemist.getClass().getCreatureStats (mAlchemist);
 | 
			
		||||
    const NpcStats& npcStats = mAlchemist.getClass().getNpcStats (mAlchemist);
 | 
			
		||||
 | 
			
		||||
    if (beginEffects() == endEffects())
 | 
			
		||||
        return 0.f;
 | 
			
		||||
 | 
			
		||||
    return
 | 
			
		||||
        (npcStats.getSkill (ESM::Skill::Alchemy).getModified() +
 | 
			
		||||
        0.1 * creatureStats.getAttribute (1).getModified()
 | 
			
		||||
        + 0.1 * creatureStats.getAttribute (7).getModified());
 | 
			
		||||
        0.1 * creatureStats.getAttribute (ESM::Attribute::Intelligence).getModified()
 | 
			
		||||
        + 0.1 * creatureStats.getAttribute (ESM::Attribute::Luck).getModified());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MWMechanics::Alchemy::countIngredients() const
 | 
			
		||||
| 
						 | 
				
			
			@ -461,7 +458,14 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na
 | 
			
		|||
    if (listEffects().empty())
 | 
			
		||||
        return Result_NoEffects;
 | 
			
		||||
 | 
			
		||||
    if (getChance()<std::rand()/static_cast<double> (RAND_MAX)*100)
 | 
			
		||||
    if (beginEffects() == endEffects())
 | 
			
		||||
    {
 | 
			
		||||
        // all effects were nullified due to insufficient skill
 | 
			
		||||
        removeIngredients();
 | 
			
		||||
        return Result_RandomFailure;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (getAlchemyFactor()<std::rand()/static_cast<double> (RAND_MAX)*100)
 | 
			
		||||
    {
 | 
			
		||||
        removeIngredients();
 | 
			
		||||
        return Result_RandomFailure;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,8 +69,7 @@ namespace MWMechanics
 | 
			
		|||
            void increaseSkill();
 | 
			
		||||
            ///< Increase alchemist's skill.
 | 
			
		||||
 | 
			
		||||
            float getChance() const;
 | 
			
		||||
            ///< Return chance of success.
 | 
			
		||||
            float getAlchemyFactor() const;
 | 
			
		||||
 | 
			
		||||
            int countIngredients() const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ namespace MWMechanics
 | 
			
		|||
            if (baseMagicka < iAutoSpellTimesCanCast * spell->mData.mCost)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (race && std::find(race->mPowers.mList.begin(), race->mPowers.mList.end(), spell->mId) != race->mPowers.mList.end())
 | 
			
		||||
            if (race && race->mPowers.exists(spell->mId))
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (!attrSkillCheck(spell, actorSkills, actorAttributes))
 | 
			
		||||
| 
						 | 
				
			
			@ -220,7 +220,7 @@ namespace MWMechanics
 | 
			
		|||
        if (spell->mData.mFlags & ESM::Spell::F_Always)
 | 
			
		||||
            return 100.f;
 | 
			
		||||
 | 
			
		||||
        float skillTerm;
 | 
			
		||||
        float skillTerm = 0;
 | 
			
		||||
        if (effectiveSchool != -1)
 | 
			
		||||
            skillTerm = 2.f * actorSkills[mapSchoolToSkill(effectiveSchool)];
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1611,7 +1611,7 @@ void CharacterController::update(float duration)
 | 
			
		|||
        if(mMovementAnimationControlled && mPtr.getClass().isActor())
 | 
			
		||||
            world->queueMovement(mPtr, moved);
 | 
			
		||||
    }
 | 
			
		||||
    else if (mAnimation)
 | 
			
		||||
    else
 | 
			
		||||
        mAnimation->updateEffects(duration);
 | 
			
		||||
    mSkipAnim = false;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,8 @@ namespace MWMechanics
 | 
			
		|||
                MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
 | 
			
		||||
                    "fDiseaseXferChance")->getFloat();
 | 
			
		||||
 | 
			
		||||
        MagicEffects& actorEffects = actor.getClass().getCreatureStats(actor).getMagicEffects();
 | 
			
		||||
 | 
			
		||||
        Spells& spells = carrier.getClass().getCreatureStats(carrier).getSpells();
 | 
			
		||||
        for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,26 +35,16 @@ namespace MWMechanics
 | 
			
		|||
            if (actor.getClass().getCreatureStats(actor).getSpells().hasSpell(spell->mId))
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            bool hasCorprusEffect = false;
 | 
			
		||||
            for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt)
 | 
			
		||||
            {
 | 
			
		||||
                if (effectIt->mEffectID == ESM::MagicEffect::Corprus)
 | 
			
		||||
                {
 | 
			
		||||
                    hasCorprusEffect = true;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            float resist = 0.f;
 | 
			
		||||
            if (hasCorprusEffect)
 | 
			
		||||
                resist = 1.f - 0.01 * (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::ResistCorprusDisease).getMagnitude()
 | 
			
		||||
                                        - actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude());
 | 
			
		||||
            if (spells.hasCorprusEffect(spell))
 | 
			
		||||
                resist = 1.f - 0.01 * (actorEffects.get(ESM::MagicEffect::ResistCorprusDisease).getMagnitude()
 | 
			
		||||
                                        - actorEffects.get(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude());
 | 
			
		||||
            else if (spell->mData.mType == ESM::Spell::ST_Disease)
 | 
			
		||||
                resist = 1.f - 0.01 * (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::ResistCommonDisease).getMagnitude()
 | 
			
		||||
                                        - actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::WeaknessToCommonDisease).getMagnitude());
 | 
			
		||||
                resist = 1.f - 0.01 * (actorEffects.get(ESM::MagicEffect::ResistCommonDisease).getMagnitude()
 | 
			
		||||
                                        - actorEffects.get(ESM::MagicEffect::WeaknessToCommonDisease).getMagnitude());
 | 
			
		||||
            else if (spell->mData.mType == ESM::Spell::ST_Blight)
 | 
			
		||||
                resist = 1.f - 0.01 * (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::ResistBlightDisease).getMagnitude()
 | 
			
		||||
                                        - actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::WeaknessToBlightDisease).getMagnitude());
 | 
			
		||||
                resist = 1.f - 0.01 * (actorEffects.get(ESM::MagicEffect::ResistBlightDisease).getMagnitude()
 | 
			
		||||
                                        - actorEffects.get(ESM::MagicEffect::WeaknessToBlightDisease).getMagnitude());
 | 
			
		||||
            else
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,6 +53,9 @@ namespace MWMechanics
 | 
			
		|||
        MWWorld::ContainerStore& store = player.getClass().getContainerStore(player);
 | 
			
		||||
        ESM::Enchantment enchantment;
 | 
			
		||||
        enchantment.mData.mCharge = getGemCharge();
 | 
			
		||||
        enchantment.mData.mAutocalc = 0;
 | 
			
		||||
        enchantment.mData.mType = mCastStyle;
 | 
			
		||||
        enchantment.mData.mCost = getEnchantPoints();
 | 
			
		||||
 | 
			
		||||
        store.remove(mSoulGemPtr, 1, player);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,8 +75,6 @@ namespace MWMechanics
 | 
			
		|||
        {
 | 
			
		||||
            enchantment.mData.mCharge=0;
 | 
			
		||||
        }
 | 
			
		||||
        enchantment.mData.mType = mCastStyle;
 | 
			
		||||
        enchantment.mData.mCost = getEnchantPoints();
 | 
			
		||||
        enchantment.mEffects = mEffectList;
 | 
			
		||||
 | 
			
		||||
        // Apply the enchantment
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -566,11 +566,14 @@ namespace MWMechanics
 | 
			
		|||
        MWWorld::LiveCellRef<ESM::NPC>* player = playerPtr.get<ESM::NPC>();
 | 
			
		||||
        const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr);
 | 
			
		||||
 | 
			
		||||
        const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
 | 
			
		||||
        static const float fDispRaceMod = gmst.find("fDispRaceMod")->getFloat();
 | 
			
		||||
        if (Misc::StringUtils::ciEqual(npc->mBase->mRace, player->mBase->mRace))
 | 
			
		||||
            x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispRaceMod")->getFloat();
 | 
			
		||||
            x += fDispRaceMod;
 | 
			
		||||
 | 
			
		||||
        x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispPersonalityMult")->getFloat()
 | 
			
		||||
            * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispPersonalityBase")->getFloat());
 | 
			
		||||
        static const float fDispPersonalityMult = gmst.find("fDispPersonalityMult")->getFloat();
 | 
			
		||||
        static const float fDispPersonalityBase = gmst.find("fDispPersonalityBase")->getFloat();
 | 
			
		||||
        x += fDispPersonalityMult * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - fDispPersonalityBase);
 | 
			
		||||
 | 
			
		||||
        float reaction = 0;
 | 
			
		||||
        int rank = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -606,16 +609,23 @@ namespace MWMechanics
 | 
			
		|||
            reaction = 0;
 | 
			
		||||
            rank = 0;
 | 
			
		||||
        }
 | 
			
		||||
        x += (MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispFactionRankMult")->getFloat() * rank
 | 
			
		||||
            + MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispFactionRankBase")->getFloat())
 | 
			
		||||
            * MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispFactionMod")->getFloat() * reaction;
 | 
			
		||||
 | 
			
		||||
        x -= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispCrimeMod")->getFloat() * playerStats.getBounty();
 | 
			
		||||
        static const float fDispFactionRankMult = gmst.find("fDispFactionRankMult")->getFloat();
 | 
			
		||||
        static const float fDispFactionRankBase = gmst.find("fDispFactionRankBase")->getFloat();
 | 
			
		||||
        static const float fDispFactionMod = gmst.find("fDispFactionMod")->getFloat();
 | 
			
		||||
        x += (fDispFactionRankMult * rank
 | 
			
		||||
            + fDispFactionRankBase)
 | 
			
		||||
            * fDispFactionMod * reaction;
 | 
			
		||||
 | 
			
		||||
        static const float fDispCrimeMod = gmst.find("fDispCrimeMod")->getFloat();
 | 
			
		||||
        static const float fDispDiseaseMod = gmst.find("fDispDiseaseMod")->getFloat();
 | 
			
		||||
        x -= fDispCrimeMod * playerStats.getBounty();
 | 
			
		||||
        if (playerStats.hasCommonDisease() || playerStats.hasBlightDisease())
 | 
			
		||||
            x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispDiseaseMod")->getFloat();
 | 
			
		||||
            x += fDispDiseaseMod;
 | 
			
		||||
 | 
			
		||||
        static const float fDispWeaponDrawn = gmst.find("fDispWeaponDrawn")->getFloat();
 | 
			
		||||
        if (playerStats.getDrawState() == MWMechanics::DrawState_Weapon)
 | 
			
		||||
            x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispWeaponDrawn")->getFloat();
 | 
			
		||||
            x += fDispWeaponDrawn;
 | 
			
		||||
 | 
			
		||||
        x += ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Charm).getMagnitude();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,7 +74,7 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
            TIterator end() const;
 | 
			
		||||
 | 
			
		||||
            bool hasSpell(const std::string& spell) { return mSpells.find(Misc::StringUtils::lowerCase(spell)) != mSpells.end(); }
 | 
			
		||||
            bool hasSpell(const std::string& spell) const { return mSpells.find(Misc::StringUtils::lowerCase(spell)) != mSpells.end(); }
 | 
			
		||||
 | 
			
		||||
            void add (const std::string& spell);
 | 
			
		||||
            ///< Adding a spell that is already listed in *this is a no-op.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@ namespace MWRender
 | 
			
		|||
    Camera::Camera (Ogre::Camera *camera)
 | 
			
		||||
    : mCamera(camera),
 | 
			
		||||
      mCameraNode(NULL),
 | 
			
		||||
      mCameraPosNode(NULL),
 | 
			
		||||
      mAnimation(NULL),
 | 
			
		||||
      mFirstPersonView(true),
 | 
			
		||||
      mPreviewMode(false),
 | 
			
		||||
| 
						 | 
				
			
			@ -26,8 +27,8 @@ namespace MWRender
 | 
			
		|||
      mNearest(30.f),
 | 
			
		||||
      mFurthest(800.f),
 | 
			
		||||
      mIsNearest(false),
 | 
			
		||||
      mHeight(128.f),
 | 
			
		||||
      mCameraDistance(300.f),
 | 
			
		||||
      mHeight(124.f),
 | 
			
		||||
      mCameraDistance(192.f),
 | 
			
		||||
      mDistanceAdjusted(false),
 | 
			
		||||
      mVanityToggleQueued(false),
 | 
			
		||||
      mViewModeToggleQueued(false)
 | 
			
		||||
| 
						 | 
				
			
			@ -66,12 +67,16 @@ namespace MWRender
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        Ogre::Quaternion xr(Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Vector3::UNIT_X);
 | 
			
		||||
        if (!mVanity.enabled && !mPreviewMode) {
 | 
			
		||||
            mCamera->getParentNode()->setOrientation(xr);
 | 
			
		||||
        } else {
 | 
			
		||||
        Ogre::Quaternion orient = xr;
 | 
			
		||||
        if (mVanity.enabled || mPreviewMode) {
 | 
			
		||||
            Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::UNIT_Z);
 | 
			
		||||
            mCamera->getParentNode()->setOrientation(zr * xr);
 | 
			
		||||
            orient = zr * xr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isFirstPerson())
 | 
			
		||||
            mCamera->getParentNode()->setOrientation(orient);
 | 
			
		||||
        else
 | 
			
		||||
            mCameraNode->setOrientation(orient);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const std::string &Camera::getHandle() const
 | 
			
		||||
| 
						 | 
				
			
			@ -79,20 +84,40 @@ namespace MWRender
 | 
			
		|||
        return mTrackingPtr.getRefData().getHandle();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Camera::attachTo(const MWWorld::Ptr &ptr)
 | 
			
		||||
    Ogre::SceneNode* Camera::attachTo(const MWWorld::Ptr &ptr)
 | 
			
		||||
    {
 | 
			
		||||
        mTrackingPtr = ptr;
 | 
			
		||||
        Ogre::SceneNode *node = mTrackingPtr.getRefData().getBaseNode()->createChildSceneNode(Ogre::Vector3(0.0f, 0.0f, mHeight));
 | 
			
		||||
        node->setInheritScale(false);
 | 
			
		||||
        Ogre::SceneNode *posNode = node->createChildSceneNode();
 | 
			
		||||
        posNode->setInheritScale(false);
 | 
			
		||||
        if(mCameraNode)
 | 
			
		||||
        {
 | 
			
		||||
            node->setOrientation(mCameraNode->getOrientation());
 | 
			
		||||
            node->setPosition(mCameraNode->getPosition());
 | 
			
		||||
            node->setScale(mCameraNode->getScale());
 | 
			
		||||
            posNode->setPosition(mCameraPosNode->getPosition());
 | 
			
		||||
            mCameraNode->getCreator()->destroySceneNode(mCameraNode);
 | 
			
		||||
            mCameraNode->getCreator()->destroySceneNode(mCameraPosNode);
 | 
			
		||||
        }
 | 
			
		||||
        mCameraNode = node;
 | 
			
		||||
        if(!mCamera->isAttached())
 | 
			
		||||
            mCameraNode->attachObject(mCamera);
 | 
			
		||||
        mCameraPosNode = posNode;
 | 
			
		||||
 | 
			
		||||
        if (!isFirstPerson())
 | 
			
		||||
        {
 | 
			
		||||
            mCamera->detachFromParent();
 | 
			
		||||
            mCameraPosNode->attachObject(mCamera);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return mCameraPosNode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Camera::setPosition(const Ogre::Vector3& position)
 | 
			
		||||
    {
 | 
			
		||||
        mCameraPosNode->setPosition(position);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Camera::setPosition(float x, float y, float z)
 | 
			
		||||
    {
 | 
			
		||||
        setPosition(Ogre::Vector3(x,y,z));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Camera::updateListener()
 | 
			
		||||
| 
						 | 
				
			
			@ -155,9 +180,9 @@ namespace MWRender
 | 
			
		|||
        processViewChange();
 | 
			
		||||
 | 
			
		||||
        if (mFirstPersonView) {
 | 
			
		||||
            mCamera->setPosition(0.f, 0.f, 0.f);
 | 
			
		||||
            setPosition(0.f, 0.f, 0.f);
 | 
			
		||||
        } else {
 | 
			
		||||
            mCamera->setPosition(0.f, 0.f, mCameraDistance);
 | 
			
		||||
            setPosition(0.f, 0.f, mCameraDistance);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +197,7 @@ namespace MWRender
 | 
			
		|||
    {
 | 
			
		||||
        // Changing the view will stop all playing animations, so if we are playing
 | 
			
		||||
        // anything important, queue the view change for later
 | 
			
		||||
        if (!mPreviewMode)
 | 
			
		||||
        if (isFirstPerson() && !mAnimation->upperBodyReady())
 | 
			
		||||
        {
 | 
			
		||||
            mVanityToggleQueued = true;
 | 
			
		||||
            return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -191,14 +216,14 @@ namespace MWRender
 | 
			
		|||
        Ogre::Vector3 rot(0.f, 0.f, 0.f);
 | 
			
		||||
        if (mVanity.enabled) {
 | 
			
		||||
            rot.x = Ogre::Degree(-30.f).valueRadians();
 | 
			
		||||
            mMainCam.offset = mCamera->getPosition().z;
 | 
			
		||||
            mMainCam.offset = mCameraPosNode->getPosition().z;
 | 
			
		||||
        } else {
 | 
			
		||||
            rot.x = getPitch();
 | 
			
		||||
            offset = mMainCam.offset;
 | 
			
		||||
        }
 | 
			
		||||
        rot.z = getYaw();
 | 
			
		||||
 | 
			
		||||
        mCamera->setPosition(0.f, 0.f, offset);
 | 
			
		||||
        setPosition(0.f, 0.f, offset);
 | 
			
		||||
        rotateCamera(rot, false);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +240,7 @@ namespace MWRender
 | 
			
		|||
        mPreviewMode = enable;
 | 
			
		||||
        processViewChange();
 | 
			
		||||
 | 
			
		||||
        float offset = mCamera->getPosition().z;
 | 
			
		||||
        float offset = mCameraPosNode->getPosition().z;
 | 
			
		||||
        if (mPreviewMode) {
 | 
			
		||||
            mMainCam.offset = offset;
 | 
			
		||||
            offset = mPreviewCam.offset;
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +249,7 @@ namespace MWRender
 | 
			
		|||
            offset = mMainCam.offset;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mCamera->setPosition(0.f, 0.f, offset);
 | 
			
		||||
        setPosition(0.f, 0.f, offset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Camera::setSneakOffset(float offset)
 | 
			
		||||
| 
						 | 
				
			
			@ -283,7 +308,7 @@ namespace MWRender
 | 
			
		|||
 | 
			
		||||
    float Camera::getCameraDistance() const
 | 
			
		||||
    {
 | 
			
		||||
        return mCamera->getPosition().z;
 | 
			
		||||
        return mCameraPosNode->getPosition().z;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Camera::setCameraDistance(float dist, bool adjust, bool override)
 | 
			
		||||
| 
						 | 
				
			
			@ -295,7 +320,7 @@ namespace MWRender
 | 
			
		|||
 | 
			
		||||
        Ogre::Vector3 v(0.f, 0.f, dist);
 | 
			
		||||
        if (adjust) {
 | 
			
		||||
            v += mCamera->getPosition();
 | 
			
		||||
            v += mCameraPosNode->getPosition();
 | 
			
		||||
        }
 | 
			
		||||
        if (v.z >= mFurthest) {
 | 
			
		||||
            v.z = mFurthest;
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +330,7 @@ namespace MWRender
 | 
			
		|||
            v.z = mNearest;
 | 
			
		||||
            mIsNearest = true;
 | 
			
		||||
        }
 | 
			
		||||
        mCamera->setPosition(v);
 | 
			
		||||
        setPosition(v);
 | 
			
		||||
 | 
			
		||||
        if (override) {
 | 
			
		||||
            if (mVanity.enabled || mPreviewMode) {
 | 
			
		||||
| 
						 | 
				
			
			@ -322,9 +347,9 @@ namespace MWRender
 | 
			
		|||
    {
 | 
			
		||||
        if (mDistanceAdjusted) {
 | 
			
		||||
            if (mVanity.enabled || mPreviewMode) {
 | 
			
		||||
                mCamera->setPosition(0, 0, mPreviewCam.offset);
 | 
			
		||||
                setPosition(0, 0, mPreviewCam.offset);
 | 
			
		||||
            } else if (!mFirstPersonView) {
 | 
			
		||||
                mCamera->setPosition(0, 0, mCameraDistance);
 | 
			
		||||
                setPosition(0, 0, mCameraDistance);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        mDistanceAdjusted = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -355,10 +380,10 @@ namespace MWRender
 | 
			
		|||
            Ogre::TagPoint *tag = mAnimation->attachObjectToBone("Head", mCamera);
 | 
			
		||||
            tag->setInheritOrientation(false);
 | 
			
		||||
        }
 | 
			
		||||
        else 
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            mAnimation->setViewMode(NpcAnimation::VM_Normal);
 | 
			
		||||
            mCameraNode->attachObject(mCamera);
 | 
			
		||||
            mCameraPosNode->attachObject(mCamera);
 | 
			
		||||
        }
 | 
			
		||||
        rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -368,8 +393,7 @@ namespace MWRender
 | 
			
		|||
        mCamera->getParentSceneNode()->needUpdate(true);
 | 
			
		||||
 | 
			
		||||
        camera = mCamera->getRealPosition();
 | 
			
		||||
        focal = Ogre::Vector3((mCamera->getParentNode()->_getFullTransform() *
 | 
			
		||||
                               Ogre::Vector4(0.0f, 0.0f, 0.0f, 1.0f)).ptr());
 | 
			
		||||
        focal = mCameraNode->_getDerivedPosition();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Camera::togglePlayerLooking(bool enable)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ namespace MWRender
 | 
			
		|||
 | 
			
		||||
        Ogre::Camera *mCamera;
 | 
			
		||||
        Ogre::SceneNode *mCameraNode;
 | 
			
		||||
        Ogre::SceneNode *mCameraPosNode;
 | 
			
		||||
 | 
			
		||||
        NpcAnimation *mAnimation;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -52,6 +53,9 @@ namespace MWRender
 | 
			
		|||
        /// Updates sound manager listener data
 | 
			
		||||
        void updateListener();
 | 
			
		||||
 | 
			
		||||
        void setPosition(const Ogre::Vector3& position);
 | 
			
		||||
        void setPosition(float x, float y, float z);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        Camera(Ogre::Camera *camera);
 | 
			
		||||
        ~Camera();
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +76,7 @@ namespace MWRender
 | 
			
		|||
        const std::string &getHandle() const;
 | 
			
		||||
 | 
			
		||||
        /// Attach camera to object
 | 
			
		||||
        void attachTo(const MWWorld::Ptr &);
 | 
			
		||||
        Ogre::SceneNode* attachTo(const MWWorld::Ptr &);
 | 
			
		||||
 | 
			
		||||
        /// @param Force view mode switch, even if currently not allowed by the animation.
 | 
			
		||||
        void toggleViewMode(bool force=false);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ using namespace MWRender;
 | 
			
		|||
using namespace Ogre;
 | 
			
		||||
 | 
			
		||||
LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering) :
 | 
			
		||||
    mInterior(false), mCellX(0), mCellY(0)
 | 
			
		||||
    mInterior(false)
 | 
			
		||||
{
 | 
			
		||||
    mRendering = rend;
 | 
			
		||||
    mRenderingManager = rendering;
 | 
			
		||||
| 
						 | 
				
			
			@ -522,10 +522,9 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
 | 
			
		|||
    {
 | 
			
		||||
        x = std::ceil(pos.x / sSize)-1;
 | 
			
		||||
        y = std::ceil(pos.y / sSize)-1;
 | 
			
		||||
        mCellX = x;
 | 
			
		||||
        mCellY = y;
 | 
			
		||||
    }
 | 
			
		||||
    MWBase::Environment::get().getWindowManager()->setActiveMap(x,y,mInterior);
 | 
			
		||||
    else
 | 
			
		||||
        MWBase::Environment::get().getWindowManager()->setActiveMap(x,y,mInterior);
 | 
			
		||||
 | 
			
		||||
    // convert from world coordinates to texture UV coordinates
 | 
			
		||||
    std::string texBaseName;
 | 
			
		||||
| 
						 | 
				
			
			@ -540,7 +539,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
 | 
			
		|||
        texBaseName = mInteriorName + "_";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v);
 | 
			
		||||
    MWBase::Environment::get().getWindowManager()->setPlayerPos(x, y, u, v);
 | 
			
		||||
    MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, playerdirection.y);
 | 
			
		||||
 | 
			
		||||
    // explore radius (squared)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,7 +134,6 @@ namespace MWRender
 | 
			
		|||
        Ogre::RenderTarget* mRenderTarget;
 | 
			
		||||
 | 
			
		||||
        bool mInterior;
 | 
			
		||||
        int mCellX, mCellY;
 | 
			
		||||
        Ogre::AxisAlignedBox mBounds;
 | 
			
		||||
        std::string mInteriorName;
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,7 +50,8 @@ namespace MWRender
 | 
			
		|||
 | 
			
		||||
    void Refraction::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
 | 
			
		||||
    {
 | 
			
		||||
        mParentCamera->getParentSceneNode ()->needUpdate ();
 | 
			
		||||
        if (mParentCamera->isAttached())
 | 
			
		||||
            mParentCamera->getParentSceneNode ()->needUpdate ();
 | 
			
		||||
        mCamera->setOrientation(mParentCamera->getDerivedOrientation());
 | 
			
		||||
        mCamera->setPosition(mParentCamera->getDerivedPosition());
 | 
			
		||||
        mCamera->setNearClipDistance(mParentCamera->getNearClipDistance());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,6 +63,7 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b
 | 
			
		|||
    , mPhysicsEngine(engine)
 | 
			
		||||
    , mTerrain(NULL)
 | 
			
		||||
    , mEffectManager(NULL)
 | 
			
		||||
    , mRenderWorld(true)
 | 
			
		||||
{
 | 
			
		||||
    mActors = new MWRender::Actors(mRendering, this);
 | 
			
		||||
    mObjects = new MWRender::Objects(mRendering);
 | 
			
		||||
| 
						 | 
				
			
			@ -232,6 +233,15 @@ bool RenderingManager::toggleWater()
 | 
			
		|||
    return mWater->toggle();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RenderingManager::toggleWorld()
 | 
			
		||||
{
 | 
			
		||||
    mRenderWorld = !mRenderWorld;
 | 
			
		||||
 | 
			
		||||
    int visibilityMask = mRenderWorld ? ~int(0) : 0;
 | 
			
		||||
    mRendering.getViewport()->setVisibilityMask(visibilityMask);
 | 
			
		||||
    return mRenderWorld;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RenderingManager::cellAdded (MWWorld::CellStore *store)
 | 
			
		||||
{
 | 
			
		||||
    if (store->isExterior())
 | 
			
		||||
| 
						 | 
				
			
			@ -302,7 +312,7 @@ void RenderingManager::updatePlayerPtr(const MWWorld::Ptr &ptr)
 | 
			
		|||
    if(mPlayerAnimation)
 | 
			
		||||
        mPlayerAnimation->updatePtr(ptr);
 | 
			
		||||
    if(mCamera->getHandle() == ptr.getRefData().getHandle())
 | 
			
		||||
        mCamera->attachTo(ptr);
 | 
			
		||||
        attachCameraTo(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RenderingManager::rebuildPtr(const MWWorld::Ptr &ptr)
 | 
			
		||||
| 
						 | 
				
			
			@ -317,7 +327,7 @@ void RenderingManager::rebuildPtr(const MWWorld::Ptr &ptr)
 | 
			
		|||
        anim->rebuild();
 | 
			
		||||
        if(mCamera->getHandle() == ptr.getRefData().getHandle())
 | 
			
		||||
        {
 | 
			
		||||
            mCamera->attachTo(ptr);
 | 
			
		||||
            attachCameraTo(ptr);
 | 
			
		||||
            mCamera->setAnimation(anim);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -489,7 +499,7 @@ bool RenderingManager::toggleRenderMode(int mode)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RenderingManager::configureFog(MWWorld::CellStore &mCell)
 | 
			
		||||
void RenderingManager::configureFog(const MWWorld::CellStore &mCell)
 | 
			
		||||
{
 | 
			
		||||
    Ogre::ColourValue color;
 | 
			
		||||
    color.setAsABGR (mCell.getCell()->mAmbi.mFog);
 | 
			
		||||
| 
						 | 
				
			
			@ -500,7 +510,7 @@ void RenderingManager::configureFog(MWWorld::CellStore &mCell)
 | 
			
		|||
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
 | 
			
		||||
{
 | 
			
		||||
    mFogColour = colour;
 | 
			
		||||
    float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
 | 
			
		||||
    float max = Settings::Manager::getFloat("viewing distance", "Viewing distance");
 | 
			
		||||
 | 
			
		||||
    if (density == 0)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -732,7 +742,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
 | 
			
		|||
        {
 | 
			
		||||
            setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
 | 
			
		||||
        }
 | 
			
		||||
        else if (it->second == "max viewing distance" && it->first == "Viewing distance")
 | 
			
		||||
        else if (it->second == "viewing distance" && it->first == "Viewing distance")
 | 
			
		||||
        {
 | 
			
		||||
            if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior()
 | 
			
		||||
                && MWBase::Environment::get().getWorld()->getPlayerPtr().mCell)
 | 
			
		||||
| 
						 | 
				
			
			@ -859,7 +869,13 @@ void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned i
 | 
			
		|||
void RenderingManager::setupPlayer(const MWWorld::Ptr &ptr)
 | 
			
		||||
{
 | 
			
		||||
    ptr.getRefData().setBaseNode(mRendering.getScene()->getSceneNode("player"));
 | 
			
		||||
    mCamera->attachTo(ptr);
 | 
			
		||||
    attachCameraTo(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RenderingManager::attachCameraTo(const MWWorld::Ptr &ptr)
 | 
			
		||||
{
 | 
			
		||||
    Ogre::SceneNode* cameraNode = mCamera->attachTo(ptr);
 | 
			
		||||
    mSkyManager->attachToNode(cameraNode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,6 +123,7 @@ public:
 | 
			
		|||
 | 
			
		||||
    void setWaterHeight(const float height);
 | 
			
		||||
    bool toggleWater();
 | 
			
		||||
    bool toggleWorld();
 | 
			
		||||
 | 
			
		||||
    /// Updates object rendering after cell change
 | 
			
		||||
    /// \param old Object reference in previous cell
 | 
			
		||||
| 
						 | 
				
			
			@ -182,7 +183,7 @@ public:
 | 
			
		|||
    ///< request the local map for a cell
 | 
			
		||||
 | 
			
		||||
    /// configure fog according to cell
 | 
			
		||||
    void configureFog(MWWorld::CellStore &mCell);
 | 
			
		||||
    void configureFog(const MWWorld::CellStore &mCell);
 | 
			
		||||
 | 
			
		||||
    /// configure fog manually
 | 
			
		||||
    void configureFog(const float density, const Ogre::ColourValue& colour);
 | 
			
		||||
| 
						 | 
				
			
			@ -220,6 +221,8 @@ private:
 | 
			
		|||
    void setAmbientMode();
 | 
			
		||||
    void applyFog(bool underwater);
 | 
			
		||||
 | 
			
		||||
    void attachCameraTo(const MWWorld::Ptr& ptr);
 | 
			
		||||
 | 
			
		||||
    void setMenuTransparency(float val);
 | 
			
		||||
 | 
			
		||||
    bool mSunEnabled;
 | 
			
		||||
| 
						 | 
				
			
			@ -266,6 +269,8 @@ private:
 | 
			
		|||
    MWRender::LocalMap* mLocalMap;
 | 
			
		||||
 | 
			
		||||
    MWRender::Shadows* mShadows;
 | 
			
		||||
 | 
			
		||||
    bool mRenderWorld;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -382,9 +382,7 @@ void SkyManager::clearRain()
 | 
			
		|||
    for (std::map<Ogre::SceneNode*, NifOgre::ObjectScenePtr>::iterator it = mRainModels.begin(); it != mRainModels.end();)
 | 
			
		||||
    {
 | 
			
		||||
        it->second.setNull();
 | 
			
		||||
        Ogre::SceneNode* parent = it->first->getParentSceneNode();
 | 
			
		||||
        mSceneMgr->destroySceneNode(it->first);
 | 
			
		||||
        mSceneMgr->destroySceneNode(parent);
 | 
			
		||||
        mRainModels.erase(it++);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -402,9 +400,7 @@ void SkyManager::updateRain(float dt)
 | 
			
		|||
        if (pos.z < -minHeight)
 | 
			
		||||
        {
 | 
			
		||||
            it->second.setNull();
 | 
			
		||||
            Ogre::SceneNode* parent = it->first->getParentSceneNode();
 | 
			
		||||
            mSceneMgr->destroySceneNode(it->first);
 | 
			
		||||
            mSceneMgr->destroySceneNode(parent);
 | 
			
		||||
            mRainModels.erase(it++);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -420,17 +416,20 @@ void SkyManager::updateRain(float dt)
 | 
			
		|||
        {
 | 
			
		||||
            mRainTimer = 0;
 | 
			
		||||
 | 
			
		||||
            // TODO: handle rain settings from Morrowind.ini
 | 
			
		||||
            const float rangeRandom = 100;
 | 
			
		||||
            float xOffs = (std::rand()/(RAND_MAX+1.0)) * rangeRandom - (rangeRandom/2);
 | 
			
		||||
            float yOffs = (std::rand()/(RAND_MAX+1.0)) * rangeRandom - (rangeRandom/2);
 | 
			
		||||
            Ogre::SceneNode* sceneNode = mCamera->getParentSceneNode()->createChildSceneNode();
 | 
			
		||||
            sceneNode->setInheritOrientation(false);
 | 
			
		||||
 | 
			
		||||
            // Create a separate node to control the offset, since a node with setInheritOrientation(false) will still
 | 
			
		||||
            // consider the orientation of the parent node for its position, just not for its orientation
 | 
			
		||||
            float startHeight = 700;
 | 
			
		||||
            Ogre::SceneNode* offsetNode = sceneNode->createChildSceneNode(Ogre::Vector3(xOffs,yOffs,startHeight));
 | 
			
		||||
            Ogre::SceneNode* offsetNode = mParticleNode->createChildSceneNode(Ogre::Vector3(xOffs,yOffs,startHeight));
 | 
			
		||||
 | 
			
		||||
            // Spawn a new rain object for each instance.
 | 
			
		||||
            // TODO: this is inefficient. We could try to use an Ogre::ParticleSystem instead, but then we would need to make assumptions
 | 
			
		||||
            // about the rain meshes being Quads and their dimensions.
 | 
			
		||||
            // Or we could clone meshes into one vertex buffer manually.
 | 
			
		||||
            NifOgre::ObjectScenePtr objects = NifOgre::Loader::createObjects(offsetNode, mRainEffect);
 | 
			
		||||
            for (unsigned int i=0; i<objects->mEntities.size(); ++i)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -562,12 +561,6 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
 | 
			
		|||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (!mParticleNode)
 | 
			
		||||
            {
 | 
			
		||||
                mParticleNode = mCamera->getParentSceneNode()->createChildSceneNode();
 | 
			
		||||
                mParticleNode->setInheritOrientation(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            mParticle = NifOgre::Loader::createObjects(mParticleNode, mCurrentParticleEffect);
 | 
			
		||||
            for(size_t i = 0; i < mParticle->mParticles.size(); ++i)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -783,3 +776,16 @@ void SkyManager::setGlareEnabled (bool enabled)
 | 
			
		|||
        return;
 | 
			
		||||
    mSunGlare->setVisible (mSunEnabled && enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SkyManager::attachToNode(SceneNode *sceneNode)
 | 
			
		||||
{
 | 
			
		||||
    if (!mParticleNode)
 | 
			
		||||
    {
 | 
			
		||||
        mParticleNode = sceneNode->createChildSceneNode();
 | 
			
		||||
        mParticleNode->setInheritOrientation(false);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        sceneNode->addChild(mParticleNode);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -116,6 +116,9 @@ namespace MWRender
 | 
			
		|||
        SkyManager(Ogre::SceneNode* root, Ogre::Camera* pCamera);
 | 
			
		||||
        ~SkyManager();
 | 
			
		||||
 | 
			
		||||
        /// Attach weather particle effects to this scene node (should be the Camera's parent node)
 | 
			
		||||
        void attachToNode(Ogre::SceneNode* sceneNode);
 | 
			
		||||
 | 
			
		||||
        void update(float duration);
 | 
			
		||||
 | 
			
		||||
        void enable();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,7 +74,8 @@ CubeReflection::~CubeReflection ()
 | 
			
		|||
 | 
			
		||||
void CubeReflection::update ()
 | 
			
		||||
{
 | 
			
		||||
    mParentCamera->getParentSceneNode ()->needUpdate ();
 | 
			
		||||
    if (mParentCamera->isAttached())
 | 
			
		||||
        mParentCamera->getParentSceneNode ()->needUpdate ();
 | 
			
		||||
    mCamera->setPosition(mParentCamera->getDerivedPosition());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +134,8 @@ void PlaneReflection::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::St
 | 
			
		|||
 | 
			
		||||
void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
 | 
			
		||||
{
 | 
			
		||||
    mParentCamera->getParentSceneNode ()->needUpdate ();
 | 
			
		||||
    if (mParentCamera->isAttached())
 | 
			
		||||
        mParentCamera->getParentSceneNode ()->needUpdate ();
 | 
			
		||||
    mCamera->setOrientation(mParentCamera->getDerivedOrientation());
 | 
			
		||||
    mCamera->setPosition(mParentCamera->getDerivedPosition());
 | 
			
		||||
    mCamera->setNearClipDistance(mParentCamera->getNearClipDistance());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -432,5 +432,6 @@ op 0x20002ac-0x20002c3: SetMagicEffect, explicit
 | 
			
		|||
op 0x20002c4-0x20002db: ModMagicEffect
 | 
			
		||||
op 0x20002dc-0x20002f3: ModMagicEffect, explicit
 | 
			
		||||
op 0x20002f4: ResetActors
 | 
			
		||||
op 0x20002f5: ToggleWorld
 | 
			
		||||
 | 
			
		||||
opcodes 0x20002f5-0x3ffffff unused
 | 
			
		||||
opcodes 0x20002f6-0x3ffffff unused
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -290,6 +290,17 @@ namespace MWScript
 | 
			
		|||
                }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        class OpToggleWorld : public Interpreter::Opcode0
 | 
			
		||||
        {
 | 
			
		||||
            public:
 | 
			
		||||
 | 
			
		||||
                virtual void execute (Interpreter::Runtime& runtime)
 | 
			
		||||
                {
 | 
			
		||||
                    runtime.getContext().report(MWBase::Environment::get().getWorld()->toggleWorld() ? "World -> On"
 | 
			
		||||
                                                                                                     : "World -> Off");
 | 
			
		||||
                }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        class OpDontSaveObject : public Interpreter::Opcode0
 | 
			
		||||
        {
 | 
			
		||||
            public:
 | 
			
		||||
| 
						 | 
				
			
			@ -979,6 +990,7 @@ namespace MWScript
 | 
			
		|||
            interpreter.installSegment5 (Compiler::Misc::opcodeFadeTo, new OpFadeTo);
 | 
			
		||||
            interpreter.installSegment5 (Compiler::Misc::opcodeTogglePathgrid, new OpTogglePathgrid);
 | 
			
		||||
            interpreter.installSegment5 (Compiler::Misc::opcodeToggleWater, new OpToggleWater);
 | 
			
		||||
            interpreter.installSegment5 (Compiler::Misc::opcodeToggleWorld, new OpToggleWorld);
 | 
			
		||||
            interpreter.installSegment5 (Compiler::Misc::opcodeDontSaveObject, new OpDontSaveObject);
 | 
			
		||||
            interpreter.installSegment5 (Compiler::Misc::opcodeToggleVanityMode, new OpToggleVanityMode);
 | 
			
		||||
            interpreter.installSegment5 (Compiler::Misc::opcodeGetPcSleep, new OpGetPcSleep);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ using namespace Ogre;
 | 
			
		|||
namespace
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
void animateCollisionShapes (std::map<OEngine::Physic::RigidBody*, OEngine::Physic::AnimatedShapeInstance>& map)
 | 
			
		||||
void animateCollisionShapes (std::map<OEngine::Physic::RigidBody*, OEngine::Physic::AnimatedShapeInstance>& map, btDynamicsWorld* dynamicsWorld)
 | 
			
		||||
{
 | 
			
		||||
    for (std::map<OEngine::Physic::RigidBody*, OEngine::Physic::AnimatedShapeInstance>::iterator it = map.begin();
 | 
			
		||||
         it != map.end(); ++it)
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +79,9 @@ void animateCollisionShapes (std::map<OEngine::Physic::RigidBody*, OEngine::Phys
 | 
			
		|||
            compound->getChildShape(shapeIt->second)->setLocalScaling(BtOgre::Convert::toBullet(bone->_getDerivedScale()));
 | 
			
		||||
            compound->updateChildTransform(shapeIt->second, trans);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // needed because we used btDynamicsWorld::setForceUpdateAllAabbs(false)
 | 
			
		||||
        dynamicsWorld->updateSingleAabb(it->first);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -283,8 +286,9 @@ namespace MWWorld
 | 
			
		|||
             */
 | 
			
		||||
 | 
			
		||||
            OEngine::Physic::ActorTracer tracer;
 | 
			
		||||
            bool wasOnGround = false;
 | 
			
		||||
            bool isOnGround = false;
 | 
			
		||||
            bool isOnGround = physicActor->getOnGround();
 | 
			
		||||
            if (movement.z > 0.f)
 | 
			
		||||
                isOnGround = false;
 | 
			
		||||
            Ogre::Vector3 inertia(0.0f);
 | 
			
		||||
            Ogre::Vector3 velocity;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -317,23 +321,6 @@ namespace MWWorld
 | 
			
		|||
                        velocity = newVelocity;
 | 
			
		||||
                }
 | 
			
		||||
                inertia = velocity; // NOTE: velocity is for z axis only in this code block
 | 
			
		||||
 | 
			
		||||
                if(!(movement.z > 0.0f)) // falling or moving horizontally (or stationary?) check if we're on ground now
 | 
			
		||||
                {
 | 
			
		||||
                    wasOnGround = physicActor->getOnGround(); // store current state
 | 
			
		||||
                    tracer.doTrace(colobj, position, position - Ogre::Vector3(0,0,2), engine); // check if down 2 possible
 | 
			
		||||
                    if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
 | 
			
		||||
                    {
 | 
			
		||||
                        const btCollisionObject* standingOn = tracer.mHitObject;
 | 
			
		||||
                        if (const OEngine::Physic::RigidBody* body = dynamic_cast<const OEngine::Physic::RigidBody*>(standingOn))
 | 
			
		||||
                        {
 | 
			
		||||
                            standingCollisionTracker[ptr.getRefData().getHandle()] = body->mName;
 | 
			
		||||
                        }
 | 
			
		||||
                        isOnGround = true;
 | 
			
		||||
                        // if we're on the ground, don't try to fall any more
 | 
			
		||||
                        velocity.z = std::max(0.0f, velocity.z);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -385,7 +372,6 @@ namespace MWWorld
 | 
			
		|||
                    if(tracer.mFraction >= 1.0f)
 | 
			
		||||
                    {
 | 
			
		||||
                        newPosition = tracer.mEndPos; // ok to move, so set newPosition
 | 
			
		||||
                        remainingTime *= (1.0f-tracer.mFraction); // FIXME: remainingTime is no longer used so don't set it?
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
| 
						 | 
				
			
			@ -406,7 +392,6 @@ namespace MWWorld
 | 
			
		|||
                    // precision can be lost due to any math Bullet does internally). Since we
 | 
			
		||||
                    // aren't performing any collision detection, we want to reject the next
 | 
			
		||||
                    // position, so that we don't slowly move inside another object.
 | 
			
		||||
                    remainingTime *= (1.0f-tracer.mFraction); // FIXME: remainingTime is no longer used so don't set it?
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -438,12 +423,22 @@ namespace MWWorld
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(isOnGround || wasOnGround)
 | 
			
		||||
            if (!(inertia.z > 0.f) && !(newPosition.z < waterlevel || isFlying))
 | 
			
		||||
            {
 | 
			
		||||
                tracer.doTrace(colobj, newPosition, newPosition - Ogre::Vector3(0,0,sStepSize+2.0f), engine);
 | 
			
		||||
                Ogre::Vector3 from = newPosition;
 | 
			
		||||
                Ogre::Vector3 to = newPosition - (isOnGround ?
 | 
			
		||||
                             Ogre::Vector3(0,0,sStepSize+2.f) : Ogre::Vector3(0,0,2.f));
 | 
			
		||||
                tracer.doTrace(colobj, from, to, engine);
 | 
			
		||||
                if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
 | 
			
		||||
                {
 | 
			
		||||
                    const btCollisionObject* standingOn = tracer.mHitObject;
 | 
			
		||||
                    if (const OEngine::Physic::RigidBody* body = dynamic_cast<const OEngine::Physic::RigidBody*>(standingOn))
 | 
			
		||||
                    {
 | 
			
		||||
                        standingCollisionTracker[ptr.getRefData().getHandle()] = body->mName;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    newPosition.z = tracer.mEndPos.z + 1.0f;
 | 
			
		||||
 | 
			
		||||
                    isOnGround = true;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			@ -672,11 +667,18 @@ namespace MWWorld
 | 
			
		|||
        const Ogre::Vector3 &position = node->getPosition();
 | 
			
		||||
 | 
			
		||||
        if(OEngine::Physic::RigidBody *body = mEngine->getRigidBody(handle))
 | 
			
		||||
        {
 | 
			
		||||
            body->getWorldTransform().setOrigin(btVector3(position.x,position.y,position.z));
 | 
			
		||||
            mEngine->mDynamicsWorld->updateSingleAabb(body);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(OEngine::Physic::RigidBody *body = mEngine->getRigidBody(handle, true))
 | 
			
		||||
        {
 | 
			
		||||
            body->getWorldTransform().setOrigin(btVector3(position.x,position.y,position.z));
 | 
			
		||||
            mEngine->mDynamicsWorld->updateSingleAabb(body);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Actors update their AABBs every frame (DISABLE_DEACTIVATION), so no need to do it manually
 | 
			
		||||
        if(OEngine::Physic::PhysicActor *physact = mEngine->getCharacter(handle))
 | 
			
		||||
            physact->setPosition(position);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -698,6 +700,7 @@ namespace MWWorld
 | 
			
		|||
                body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
 | 
			
		||||
            else
 | 
			
		||||
                mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation);
 | 
			
		||||
            mEngine->mDynamicsWorld->updateSingleAabb(body);
 | 
			
		||||
        }
 | 
			
		||||
        if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle, true))
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -705,6 +708,7 @@ namespace MWWorld
 | 
			
		|||
                body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
 | 
			
		||||
            else
 | 
			
		||||
                mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation);
 | 
			
		||||
            mEngine->mDynamicsWorld->updateSingleAabb(body);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -866,8 +870,8 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
    void PhysicsSystem::stepSimulation(float dt)
 | 
			
		||||
    {
 | 
			
		||||
        animateCollisionShapes(mEngine->mAnimatedShapes);
 | 
			
		||||
        animateCollisionShapes(mEngine->mAnimatedRaycastingShapes);
 | 
			
		||||
        animateCollisionShapes(mEngine->mAnimatedShapes, mEngine->mDynamicsWorld);
 | 
			
		||||
        animateCollisionShapes(mEngine->mAnimatedRaycastingShapes, mEngine->mDynamicsWorld);
 | 
			
		||||
 | 
			
		||||
        mEngine->stepSimulation(dt);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@
 | 
			
		|||
#include <components/nif/niffile.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/environment.hpp"
 | 
			
		||||
#include "../mwbase/world.hpp" /// FIXME
 | 
			
		||||
#include "../mwbase/world.hpp"
 | 
			
		||||
#include "../mwbase/soundmanager.hpp"
 | 
			
		||||
#include "../mwbase/mechanicsmanager.hpp"
 | 
			
		||||
#include "../mwbase/windowmanager.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +117,28 @@ namespace MWWorld
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Scene::getGridCenter(int &cellX, int &cellY)
 | 
			
		||||
    {
 | 
			
		||||
        int maxX = std::numeric_limits<int>().min();
 | 
			
		||||
        int maxY = std::numeric_limits<int>().min();
 | 
			
		||||
        int minX = std::numeric_limits<int>().max();
 | 
			
		||||
        int minY = std::numeric_limits<int>().max();
 | 
			
		||||
        CellStoreCollection::iterator iter = mActiveCells.begin();
 | 
			
		||||
        while (iter!=mActiveCells.end())
 | 
			
		||||
        {
 | 
			
		||||
            assert ((*iter)->getCell()->isExterior());
 | 
			
		||||
            int x = (*iter)->getCell()->getGridX();
 | 
			
		||||
            int y = (*iter)->getCell()->getGridY();
 | 
			
		||||
            maxX = std::max(x, maxX);
 | 
			
		||||
            maxY = std::max(y, maxY);
 | 
			
		||||
            minX = std::min(x, minX);
 | 
			
		||||
            minY = std::min(y, minY);
 | 
			
		||||
            ++iter;
 | 
			
		||||
        }
 | 
			
		||||
        cellX = (minX + maxX) / 2;
 | 
			
		||||
        cellY = (minY + maxY) / 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Scene::update (float duration, bool paused)
 | 
			
		||||
    {
 | 
			
		||||
        if (mNeedMapUpdate)
 | 
			
		||||
| 
						 | 
				
			
			@ -126,6 +148,13 @@ namespace MWWorld
 | 
			
		|||
            for (CellStoreCollection::iterator active = mActiveCells.begin(); active!=mActiveCells.end(); ++active)
 | 
			
		||||
                mRendering.requestMap(*active);
 | 
			
		||||
            mNeedMapUpdate = false;
 | 
			
		||||
 | 
			
		||||
            if (mCurrentCell->isExterior())
 | 
			
		||||
            {
 | 
			
		||||
                int cellX, cellY;
 | 
			
		||||
                getGridCenter(cellX, cellY);
 | 
			
		||||
                MWBase::Environment::get().getWindowManager()->setActiveMap(cellX,cellY,false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mRendering.update (duration, paused);
 | 
			
		||||
| 
						 | 
				
			
			@ -213,41 +242,6 @@ namespace MWWorld
 | 
			
		|||
        MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Scene::playerCellChange(CellStore *cell, const ESM::Position& pos, bool adjustPlayerPos)
 | 
			
		||||
    {
 | 
			
		||||
        MWBase::World *world = MWBase::Environment::get().getWorld();
 | 
			
		||||
        MWWorld::Ptr old = world->getPlayerPtr();
 | 
			
		||||
        world->getPlayer().setCell(cell);
 | 
			
		||||
 | 
			
		||||
        MWWorld::Ptr player = world->getPlayerPtr();
 | 
			
		||||
        mRendering.updatePlayerPtr(player);
 | 
			
		||||
 | 
			
		||||
        if (adjustPlayerPos) {
 | 
			
		||||
            world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]);
 | 
			
		||||
 | 
			
		||||
            float x = Ogre::Radian(pos.rot[0]).valueDegrees();
 | 
			
		||||
            float y = Ogre::Radian(pos.rot[1]).valueDegrees();
 | 
			
		||||
            float z = Ogre::Radian(pos.rot[2]).valueDegrees();
 | 
			
		||||
            world->rotateObject(player, x, y, z);
 | 
			
		||||
 | 
			
		||||
            player.getClass().adjustPosition(player, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        MWBase::MechanicsManager *mechMgr =
 | 
			
		||||
            MWBase::Environment::get().getMechanicsManager();
 | 
			
		||||
 | 
			
		||||
        mechMgr->updateCell(old, player);
 | 
			
		||||
        mechMgr->watchActor(player);
 | 
			
		||||
 | 
			
		||||
        mRendering.updateTerrain();
 | 
			
		||||
 | 
			
		||||
        // Delay the map update until scripts have been given a chance to run.
 | 
			
		||||
        // If we don't do this, objects that should be disabled will still appear on the map.
 | 
			
		||||
        mNeedMapUpdate = true;
 | 
			
		||||
 | 
			
		||||
        MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Scene::changeToVoid()
 | 
			
		||||
    {
 | 
			
		||||
        CellStoreCollection::iterator active = mActiveCells.begin();
 | 
			
		||||
| 
						 | 
				
			
			@ -257,7 +251,28 @@ namespace MWWorld
 | 
			
		|||
        mCurrentCell = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos)
 | 
			
		||||
    void Scene::playerMoved(const Ogre::Vector3 &pos)
 | 
			
		||||
    {
 | 
			
		||||
        if (!mCurrentCell || !mCurrentCell->isExterior())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // figure out the center of the current cell grid (*not* necessarily mCurrentCell, which is the cell the player is in)
 | 
			
		||||
        int cellX, cellY;
 | 
			
		||||
        getGridCenter(cellX, cellY);
 | 
			
		||||
        float centerX, centerY;
 | 
			
		||||
        MWBase::Environment::get().getWorld()->indexToPosition(cellX, cellY, centerX, centerY, true);
 | 
			
		||||
        const float maxDistance = 8192/2 + 1024; // 1/2 cell size + threshold
 | 
			
		||||
        float distance = std::max(std::abs(centerX-pos.x), std::abs(centerY-pos.y));
 | 
			
		||||
        if (distance > maxDistance)
 | 
			
		||||
        {
 | 
			
		||||
            int newX, newY;
 | 
			
		||||
            MWBase::Environment::get().getWorld()->positionToIndex(pos.x, pos.y, newX, newY);
 | 
			
		||||
            changeCellGrid(newX, newY);
 | 
			
		||||
            mRendering.updateTerrain();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Scene::changeCellGrid (int X, int Y)
 | 
			
		||||
    {
 | 
			
		||||
        Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
 | 
			
		||||
        Loading::ScopedLoad load(loadingListener);
 | 
			
		||||
| 
						 | 
				
			
			@ -286,6 +301,7 @@ namespace MWWorld
 | 
			
		|||
        int refsToLoad = 0;
 | 
			
		||||
        // get the number of refs to load
 | 
			
		||||
        for (int x=X-1; x<=X+1; ++x)
 | 
			
		||||
        {
 | 
			
		||||
            for (int y=Y-1; y<=Y+1; ++y)
 | 
			
		||||
            {
 | 
			
		||||
                CellStoreCollection::iterator iter = mActiveCells.begin();
 | 
			
		||||
| 
						 | 
				
			
			@ -304,11 +320,13 @@ namespace MWWorld
 | 
			
		|||
                if (iter==mActiveCells.end())
 | 
			
		||||
                    refsToLoad += MWBase::Environment::get().getWorld()->getExterior(x, y)->count();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        loadingListener->setProgressRange(refsToLoad);
 | 
			
		||||
 | 
			
		||||
        // Load cells
 | 
			
		||||
        for (int x=X-1; x<=X+1; ++x)
 | 
			
		||||
        {
 | 
			
		||||
            for (int y=Y-1; y<=Y+1; ++y)
 | 
			
		||||
            {
 | 
			
		||||
                CellStoreCollection::iterator iter = mActiveCells.begin();
 | 
			
		||||
| 
						 | 
				
			
			@ -331,32 +349,47 @@ namespace MWWorld
 | 
			
		|||
                    loadCell (cell, loadingListener);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        // find current cell
 | 
			
		||||
        CellStoreCollection::iterator iter = mActiveCells.begin();
 | 
			
		||||
 | 
			
		||||
        while (iter!=mActiveCells.end())
 | 
			
		||||
        {
 | 
			
		||||
            assert ((*iter)->getCell()->isExterior());
 | 
			
		||||
 | 
			
		||||
            if (X==(*iter)->getCell()->getGridX() &&
 | 
			
		||||
                Y==(*iter)->getCell()->getGridY())
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            ++iter;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        assert (iter!=mActiveCells.end());
 | 
			
		||||
 | 
			
		||||
        mCurrentCell = *iter;
 | 
			
		||||
 | 
			
		||||
        // adjust player
 | 
			
		||||
        playerCellChange (mCurrentCell, position, adjustPlayerPos);
 | 
			
		||||
 | 
			
		||||
        // Sky system
 | 
			
		||||
        MWBase::Environment::get().getWorld()->adjustSky();
 | 
			
		||||
        CellStore* current = MWBase::Environment::get().getWorld()->getExterior(X,Y);
 | 
			
		||||
        MWBase::Environment::get().getWindowManager()->changeCell(current);
 | 
			
		||||
 | 
			
		||||
        mCellChanged = true;
 | 
			
		||||
 | 
			
		||||
        // Delay the map update until scripts have been given a chance to run.
 | 
			
		||||
        // If we don't do this, objects that should be disabled will still appear on the map.
 | 
			
		||||
        mNeedMapUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Scene::changePlayerCell(CellStore *cell, const ESM::Position &pos, bool adjustPlayerPos)
 | 
			
		||||
    {
 | 
			
		||||
        mCurrentCell = cell;
 | 
			
		||||
 | 
			
		||||
        MWBase::World *world = MWBase::Environment::get().getWorld();
 | 
			
		||||
        MWWorld::Ptr old = world->getPlayerPtr();
 | 
			
		||||
        world->getPlayer().setCell(cell);
 | 
			
		||||
 | 
			
		||||
        MWWorld::Ptr player = world->getPlayerPtr();
 | 
			
		||||
        mRendering.updatePlayerPtr(player);
 | 
			
		||||
 | 
			
		||||
        if (adjustPlayerPos) {
 | 
			
		||||
            world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]);
 | 
			
		||||
 | 
			
		||||
            float x = Ogre::Radian(pos.rot[0]).valueDegrees();
 | 
			
		||||
            float y = Ogre::Radian(pos.rot[1]).valueDegrees();
 | 
			
		||||
            float z = Ogre::Radian(pos.rot[2]).valueDegrees();
 | 
			
		||||
            world->rotateObject(player, x, y, z);
 | 
			
		||||
 | 
			
		||||
            player.getClass().adjustPosition(player, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        MWBase::MechanicsManager *mechMgr =
 | 
			
		||||
            MWBase::Environment::get().getMechanicsManager();
 | 
			
		||||
 | 
			
		||||
        mechMgr->updateCell(old, player);
 | 
			
		||||
        mechMgr->watchActor(player);
 | 
			
		||||
 | 
			
		||||
        MWBase::Environment::get().getWorld()->adjustSky();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //We need the ogre renderer and a scene node.
 | 
			
		||||
| 
						 | 
				
			
			@ -427,33 +460,39 @@ namespace MWWorld
 | 
			
		|||
        // Load cell.
 | 
			
		||||
        std::cout << "cellName: " << cell->getCell()->mName << std::endl;
 | 
			
		||||
 | 
			
		||||
        //Loading Interior loading text
 | 
			
		||||
 | 
			
		||||
        loadCell (cell, loadingListener);
 | 
			
		||||
 | 
			
		||||
        mCurrentCell = cell;
 | 
			
		||||
        changePlayerCell(cell, position, true);
 | 
			
		||||
 | 
			
		||||
        // adjust fog
 | 
			
		||||
        mRendering.configureFog(*mCurrentCell);
 | 
			
		||||
 | 
			
		||||
        // adjust player
 | 
			
		||||
        playerCellChange (mCurrentCell, position);
 | 
			
		||||
 | 
			
		||||
        // Sky system
 | 
			
		||||
        MWBase::Environment::get().getWorld()->adjustSky();
 | 
			
		||||
 | 
			
		||||
        mCellChanged = true;
 | 
			
		||||
        MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
 | 
			
		||||
 | 
			
		||||
        MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
 | 
			
		||||
 | 
			
		||||
        // Delay the map update until scripts have been given a chance to run.
 | 
			
		||||
        // If we don't do this, objects that should be disabled will still appear on the map.
 | 
			
		||||
        mNeedMapUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Scene::changeToExteriorCell (const ESM::Position& position)
 | 
			
		||||
    void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos)
 | 
			
		||||
    {
 | 
			
		||||
        int x = 0;
 | 
			
		||||
        int y = 0;
 | 
			
		||||
 | 
			
		||||
        MWBase::Environment::get().getWorld()->positionToIndex (position.pos[0], position.pos[1], x, y);
 | 
			
		||||
 | 
			
		||||
        changeCell (x, y, position, true);
 | 
			
		||||
        changeCellGrid(x, y);
 | 
			
		||||
 | 
			
		||||
        CellStore* current = MWBase::Environment::get().getWorld()->getExterior(x, y);
 | 
			
		||||
        changePlayerCell(current, position, adjustPlayerPos);
 | 
			
		||||
 | 
			
		||||
        mRendering.updateTerrain();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CellStore* Scene::getCurrentCell ()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,13 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
            bool mNeedMapUpdate;
 | 
			
		||||
 | 
			
		||||
            void playerCellChange (CellStore *cell, const ESM::Position& position,
 | 
			
		||||
                bool adjustPlayerPos = true);
 | 
			
		||||
 | 
			
		||||
            void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener);
 | 
			
		||||
 | 
			
		||||
            // Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
 | 
			
		||||
            void changeCellGrid (int X, int Y);
 | 
			
		||||
 | 
			
		||||
            void getGridCenter(int& cellX, int& cellY);
 | 
			
		||||
 | 
			
		||||
        public:
 | 
			
		||||
 | 
			
		||||
            Scene (MWRender::RenderingManager& rendering, PhysicsSystem *physics);
 | 
			
		||||
| 
						 | 
				
			
			@ -75,19 +77,21 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
            void loadCell (CellStore *cell, Loading::Listener* loadingListener);
 | 
			
		||||
 | 
			
		||||
            void changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos);
 | 
			
		||||
            void playerMoved (const Ogre::Vector3& pos);
 | 
			
		||||
 | 
			
		||||
            CellStore* getCurrentCell ();
 | 
			
		||||
            void changePlayerCell (CellStore* newCell, const ESM::Position& position, bool adjustPlayerPos);
 | 
			
		||||
 | 
			
		||||
            CellStore *getCurrentCell();
 | 
			
		||||
 | 
			
		||||
            const CellStoreCollection& getActiveCells () const;
 | 
			
		||||
 | 
			
		||||
            bool hasCellChanged() const;
 | 
			
		||||
            ///< Has the player moved to a different cell, since the last frame?
 | 
			
		||||
            ///< Has the set of active cells changed, since the last frame?
 | 
			
		||||
 | 
			
		||||
            void changeToInteriorCell (const std::string& cellName, const ESM::Position& position);
 | 
			
		||||
            ///< Move to interior cell.
 | 
			
		||||
 | 
			
		||||
            void changeToExteriorCell (const ESM::Position& position);
 | 
			
		||||
            void changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos);
 | 
			
		||||
            ///< Move to exterior cell.
 | 
			
		||||
 | 
			
		||||
            void changeToVoid();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -498,7 +498,8 @@ void WeatherManager::update(float duration)
 | 
			
		|||
                else if (sound == 1) soundName = &mThunderSoundID1;
 | 
			
		||||
                else if (sound == 2) soundName = &mThunderSoundID2;
 | 
			
		||||
                else if (sound == 3) soundName = &mThunderSoundID3;
 | 
			
		||||
                MWBase::Environment::get().getSoundManager()->playSound(*soundName, 1.0, 1.0);
 | 
			
		||||
                if (soundName)
 | 
			
		||||
                    MWBase::Environment::get().getSoundManager()->playSound(*soundName, 1.0, 1.0);
 | 
			
		||||
                mThunderSoundDelay = 1000;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -241,7 +241,7 @@ namespace MWWorld
 | 
			
		|||
                pos.rot[0] = 0;
 | 
			
		||||
                pos.rot[1] = 0;
 | 
			
		||||
                pos.rot[2] = 0;
 | 
			
		||||
                mWorldScene->changeToExteriorCell(pos);
 | 
			
		||||
                mWorldScene->changeToExteriorCell(pos, true);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -920,7 +920,7 @@ namespace MWWorld
 | 
			
		|||
            mRendering->notifyWorldSpaceChanged();
 | 
			
		||||
        }
 | 
			
		||||
        removeContainerScripts(getPlayerPtr());
 | 
			
		||||
        mWorldScene->changeToExteriorCell(position);
 | 
			
		||||
        mWorldScene->changeToExteriorCell(position, true);
 | 
			
		||||
        addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1045,7 +1045,7 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
        CellStore *currCell = ptr.isInCell() ? ptr.getCell() : NULL; // currCell == NULL should only happen for player, during initial startup
 | 
			
		||||
        bool isPlayer = ptr == mPlayer->getPlayer();
 | 
			
		||||
        bool haveToMove = isPlayer || mWorldScene->isCellActive(*currCell);
 | 
			
		||||
        bool haveToMove = isPlayer || (currCell && mWorldScene->isCellActive(*currCell));
 | 
			
		||||
 | 
			
		||||
        if (currCell != newCell)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -1057,9 +1057,10 @@ namespace MWWorld
 | 
			
		|||
                    changeToInteriorCell(Misc::StringUtils::lowerCase(newCell->getCell()->mName), pos);
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    int cellX = newCell->getCell()->getGridX();
 | 
			
		||||
                    int cellY = newCell->getCell()->getGridY();
 | 
			
		||||
                    mWorldScene->changeCell(cellX, cellY, pos, false);
 | 
			
		||||
                    if (mWorldScene->isCellActive(*newCell))
 | 
			
		||||
                        mWorldScene->changePlayerCell(newCell, pos, false);
 | 
			
		||||
                    else
 | 
			
		||||
                        mWorldScene->changeToExteriorCell(pos, false);
 | 
			
		||||
                }
 | 
			
		||||
                addContainerScripts (getPlayerPtr(), newCell);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1120,6 +1121,10 @@ namespace MWWorld
 | 
			
		|||
            mRendering->moveObject(ptr, vec);
 | 
			
		||||
            mPhysics->moveObject (ptr);
 | 
			
		||||
        }
 | 
			
		||||
        if (isPlayer)
 | 
			
		||||
        {
 | 
			
		||||
            mWorldScene->playerMoved (vec);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool World::moveObjectImp(const Ptr& ptr, float x, float y, float z)
 | 
			
		||||
| 
						 | 
				
			
			@ -1309,6 +1314,8 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
    void World::doPhysics(float duration)
 | 
			
		||||
    {
 | 
			
		||||
        mPhysics->stepSimulation(duration);
 | 
			
		||||
 | 
			
		||||
        processDoors(duration);
 | 
			
		||||
 | 
			
		||||
        mProjectileManager->update(duration);
 | 
			
		||||
| 
						 | 
				
			
			@ -1327,8 +1334,6 @@ namespace MWWorld
 | 
			
		|||
        }
 | 
			
		||||
        if(player != results.end())
 | 
			
		||||
            moveObjectImp(player->first, player->second.x, player->second.y, player->second.z);
 | 
			
		||||
 | 
			
		||||
        mPhysics->stepSimulation(duration);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2)
 | 
			
		||||
| 
						 | 
				
			
			@ -1565,7 +1570,7 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
    bool World::isCellExterior() const
 | 
			
		||||
    {
 | 
			
		||||
        CellStore *currentCell = mWorldScene->getCurrentCell();
 | 
			
		||||
        const CellStore *currentCell = mWorldScene->getCurrentCell();
 | 
			
		||||
        if (currentCell)
 | 
			
		||||
        {
 | 
			
		||||
            return currentCell->getCell()->isExterior();
 | 
			
		||||
| 
						 | 
				
			
			@ -1575,7 +1580,7 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
    bool World::isCellQuasiExterior() const
 | 
			
		||||
    {
 | 
			
		||||
        CellStore *currentCell = mWorldScene->getCurrentCell();
 | 
			
		||||
        const CellStore *currentCell = mWorldScene->getCurrentCell();
 | 
			
		||||
        if (currentCell)
 | 
			
		||||
        {
 | 
			
		||||
            if (!(currentCell->getCell()->mData.mFlags & ESM::Cell::QuasiEx))
 | 
			
		||||
| 
						 | 
				
			
			@ -1663,6 +1668,11 @@ namespace MWWorld
 | 
			
		|||
        return mRendering->toggleWater();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool World::toggleWorld()
 | 
			
		||||
    {
 | 
			
		||||
        return mRendering->toggleWorld();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void World::PCDropped (const Ptr& item)
 | 
			
		||||
    {
 | 
			
		||||
        std::string script = item.getClass().getScript(item);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -180,6 +180,7 @@ namespace MWWorld
 | 
			
		|||
            virtual void setWaterHeight(const float height);
 | 
			
		||||
 | 
			
		||||
            virtual bool toggleWater();
 | 
			
		||||
            virtual bool toggleWorld();
 | 
			
		||||
 | 
			
		||||
            virtual void adjustSky();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +198,7 @@ namespace MWWorld
 | 
			
		|||
            virtual LocalScripts& getLocalScripts();
 | 
			
		||||
 | 
			
		||||
            virtual bool hasCellChanged() const;
 | 
			
		||||
            ///< Has the player moved to a different cell, since the last frame?
 | 
			
		||||
            ///< Has the set of active cells changed, since the last frame?
 | 
			
		||||
 | 
			
		||||
            virtual bool isCellExterior() const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -256,6 +256,8 @@ namespace Compiler
 | 
			
		|||
            extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo);
 | 
			
		||||
            extensions.registerInstruction ("togglewater", "", opcodeToggleWater);
 | 
			
		||||
            extensions.registerInstruction ("twa", "", opcodeToggleWater);
 | 
			
		||||
            extensions.registerInstruction ("toggleworld", "", opcodeToggleWorld);
 | 
			
		||||
            extensions.registerInstruction ("tw", "", opcodeToggleWorld);
 | 
			
		||||
            extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid);
 | 
			
		||||
            extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid);
 | 
			
		||||
            extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,6 +212,7 @@ namespace Compiler
 | 
			
		|||
        const int opcodeFadeOut = 0x200013d;
 | 
			
		||||
        const int opcodeFadeTo = 0x200013e;
 | 
			
		||||
        const int opcodeToggleWater = 0x2000144;
 | 
			
		||||
        const int opcodeToggleWorld = 0x20002f5;
 | 
			
		||||
        const int opcodeTogglePathgrid = 0x2000146;
 | 
			
		||||
        const int opcodeDontSaveObject = 0x2000153;
 | 
			
		||||
        const int opcodeToggleVanityMode = 0x2000174;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,4 +20,12 @@ void SpellList::save(ESMWriter &esm) const
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SpellList::exists(const std::string &spell) const
 | 
			
		||||
{
 | 
			
		||||
    for (std::vector<std::string>::const_iterator it = mList.begin(); it != mList.end(); ++it)
 | 
			
		||||
        if (Misc::StringUtils::ciEqual(*it, spell))
 | 
			
		||||
            return true;
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,9 @@ namespace ESM
 | 
			
		|||
    {
 | 
			
		||||
        std::vector<std::string> mList;
 | 
			
		||||
 | 
			
		||||
        /// Is this spell ID in mList?
 | 
			
		||||
        bool exists(const std::string& spell) const;
 | 
			
		||||
 | 
			
		||||
        void load(ESMReader &esm);
 | 
			
		||||
        void save(ESMWriter &esm) const;
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,8 +147,8 @@ namespace ESMTerrain
 | 
			
		|||
        Ogre::Vector3 normal;
 | 
			
		||||
        Ogre::ColourValue color;
 | 
			
		||||
 | 
			
		||||
        float vertY;
 | 
			
		||||
        float vertX;
 | 
			
		||||
        float vertY = 0;
 | 
			
		||||
        float vertX = 0;
 | 
			
		||||
 | 
			
		||||
        float vertY_ = 0; // of current cell corner
 | 
			
		||||
        for (int cellY = startY; cellY < startY + std::ceil(size); ++cellY)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,38 +73,6 @@ namespace
 | 
			
		|||
            return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Ogre::AxisAlignedBox::distance is broken in 1.8.
 | 
			
		||||
    Ogre::Real distance(const Ogre::AxisAlignedBox& box, const Ogre::Vector3& v)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
      if (box.contains(v))
 | 
			
		||||
        return 0;
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
          Ogre::Vector3 maxDist(0,0,0);
 | 
			
		||||
        const Ogre::Vector3& minimum = box.getMinimum();
 | 
			
		||||
        const Ogre::Vector3& maximum = box.getMaximum();
 | 
			
		||||
 | 
			
		||||
        if (v.x < minimum.x)
 | 
			
		||||
          maxDist.x = minimum.x - v.x;
 | 
			
		||||
        else if (v.x > maximum.x)
 | 
			
		||||
          maxDist.x = v.x - maximum.x;
 | 
			
		||||
 | 
			
		||||
        if (v.y < minimum.y)
 | 
			
		||||
          maxDist.y = minimum.y - v.y;
 | 
			
		||||
        else if (v.y > maximum.y)
 | 
			
		||||
          maxDist.y = v.y - maximum.y;
 | 
			
		||||
 | 
			
		||||
        if (v.z < minimum.z)
 | 
			
		||||
          maxDist.z = minimum.z - v.z;
 | 
			
		||||
        else if (v.z > maximum.z)
 | 
			
		||||
          maxDist.z = v.z - maximum.z;
 | 
			
		||||
 | 
			
		||||
        return maxDist.length();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a 2D quad
 | 
			
		||||
    void makeQuad(Ogre::SceneManager* sceneMgr, float left, float top, float right, float bottom, Ogre::MaterialPtr material)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +238,7 @@ bool QuadTreeNode::update(const Ogre::Vector3 &cameraPos)
 | 
			
		|||
    if (mBounds.isNull())
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
    float dist = distance(mWorldBounds, cameraPos);
 | 
			
		||||
    float dist = mWorldBounds.distance(cameraPos);
 | 
			
		||||
 | 
			
		||||
    // Make sure our scene node is attached
 | 
			
		||||
    if (!mSceneNode->isInSceneGraph())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -197,8 +197,17 @@ namespace Gui
 | 
			
		|||
            MyGUI::IntCoord widgetCoord;
 | 
			
		||||
            widgetCoord.left = curX;
 | 
			
		||||
            widgetCoord.top = mPadding + (getSize().height-mPadding*2 - height) / 2;
 | 
			
		||||
            int width = sizes[i].second ? sizes[i].first.width + (getSize().width-mPadding*2 - total_width)/h_stretched_count
 | 
			
		||||
                                        : sizes[i].first.width;
 | 
			
		||||
 | 
			
		||||
            int width = 0;
 | 
			
		||||
            if (sizes[i].second)
 | 
			
		||||
            {
 | 
			
		||||
                if (h_stretched_count == 0)
 | 
			
		||||
                    throw std::logic_error("unexpected");
 | 
			
		||||
                width = sizes[i].first.width + (getSize().width-mPadding*2 - total_width)/h_stretched_count;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                width = sizes[i].first.width;
 | 
			
		||||
 | 
			
		||||
            widgetCoord.width = width;
 | 
			
		||||
            widgetCoord.height = height;
 | 
			
		||||
            w->setCoord(widgetCoord);
 | 
			
		||||
| 
						 | 
				
			
			@ -334,8 +343,17 @@ namespace Gui
 | 
			
		|||
            MyGUI::IntCoord widgetCoord;
 | 
			
		||||
            widgetCoord.top = curY;
 | 
			
		||||
            widgetCoord.left = mPadding + (getSize().width-mPadding*2 - width) / 2;
 | 
			
		||||
            int height = sizes[i].second ? sizes[i].first.height + (getSize().height-mPadding*2 - total_height)/v_stretched_count
 | 
			
		||||
                                        : sizes[i].first.height;
 | 
			
		||||
 | 
			
		||||
            int height = 0;
 | 
			
		||||
            if (sizes[i].second)
 | 
			
		||||
            {
 | 
			
		||||
                if (v_stretched_count == 0)
 | 
			
		||||
                    throw std::logic_error("unexpected");
 | 
			
		||||
                height = sizes[i].first.height + (getSize().height-mPadding*2 - total_height)/v_stretched_count;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                height = sizes[i].first.height;
 | 
			
		||||
 | 
			
		||||
            widgetCoord.height = height;
 | 
			
		||||
            widgetCoord.width = width;
 | 
			
		||||
            w->setCoord(widgetCoord);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								extern/oics/ICSInputControlSystem.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								extern/oics/ICSInputControlSystem.h
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -119,9 +119,11 @@ namespace ICS
 | 
			
		|||
        //bool sliderMoved(const OIS::JoyStickEvent &evt, int index);
 | 
			
		||||
 | 
			
		||||
        void addKeyBinding(Control* control, SDL_Scancode key, Control::ControlChangingDirection direction);
 | 
			
		||||
        bool isKeyBound(SDL_Scancode key) const;
 | 
			
		||||
		void addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction);
 | 
			
		||||
		void addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction);
 | 
			
		||||
		void addJoystickAxisBinding(Control* control, int deviceId, int axis, Control::ControlChangingDirection direction);
 | 
			
		||||
        bool isMouseButtonBound(unsigned int button) const;
 | 
			
		||||
        void addJoystickAxisBinding(Control* control, int deviceId, int axis, Control::ControlChangingDirection direction);
 | 
			
		||||
		void addJoystickButtonBinding(Control* control, int deviceId, unsigned int button, Control::ControlChangingDirection direction);
 | 
			
		||||
		void addJoystickPOVBinding(Control* control, int deviceId, int index, POVAxis axis, Control::ControlChangingDirection direction);
 | 
			
		||||
		void addJoystickSliderBinding(Control* control, int deviceId, int index, Control::ControlChangingDirection direction);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,6 +61,11 @@ namespace ICS
 | 
			
		|||
		mControlsKeyBinderMap[ key ] = controlKeyBinderItem;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    bool InputControlSystem::isKeyBound(SDL_Scancode key) const
 | 
			
		||||
    {
 | 
			
		||||
        return mControlsKeyBinderMap.find(key) != mControlsKeyBinderMap.end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputControlSystem::removeKeyBinding(SDL_Scancode key)
 | 
			
		||||
	{
 | 
			
		||||
		ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.find(key);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								extern/oics/ICSInputControlSystem_mouse.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								extern/oics/ICSInputControlSystem_mouse.cpp
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -139,6 +139,11 @@ namespace ICS
 | 
			
		|||
		mControlsMouseButtonBinderMap[ button ] = controlMouseButtonBinderItem;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool InputControlSystem::isMouseButtonBound(unsigned int button) const
 | 
			
		||||
	{
 | 
			
		||||
		return mControlsMouseButtonBinderMap.find(button) != mControlsMouseButtonBinderMap.end();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// get bindings
 | 
			
		||||
	InputControlSystem::NamedAxis InputControlSystem::getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,13 +12,13 @@
 | 
			
		|||
    {
 | 
			
		||||
        float4x4 viewFixed = view;
 | 
			
		||||
#if !SH_GLSL
 | 
			
		||||
        viewFixed[0][3] = 0;
 | 
			
		||||
        viewFixed[1][3] = 0;
 | 
			
		||||
        viewFixed[2][3] = 0;
 | 
			
		||||
        viewFixed[0][3] = 0.0;
 | 
			
		||||
        viewFixed[1][3] = 0.0;
 | 
			
		||||
        viewFixed[2][3] = 0.0;
 | 
			
		||||
#else
 | 
			
		||||
        viewFixed[3][0] = 0;
 | 
			
		||||
        viewFixed[3][1] = 0;
 | 
			
		||||
        viewFixed[3][2] = 0;
 | 
			
		||||
        viewFixed[3][0] = 0.0;
 | 
			
		||||
        viewFixed[3][1] = 0.0;
 | 
			
		||||
        viewFixed[3][2] = 0.0;
 | 
			
		||||
#endif
 | 
			
		||||
        shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shInputPosition));
 | 
			
		||||
            alphaFade = shInputPosition.z < 150.0 ? 0.0 : 1.0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,13 +14,13 @@
 | 
			
		|||
        float4x4 worldviewFixed = worldview;
 | 
			
		||||
 | 
			
		||||
#if !SH_GLSL
 | 
			
		||||
        worldviewFixed[0][3] = 0;
 | 
			
		||||
        worldviewFixed[1][3] = 0;
 | 
			
		||||
        worldviewFixed[2][3] = 0;
 | 
			
		||||
        worldviewFixed[0][3] = 0.0;
 | 
			
		||||
        worldviewFixed[1][3] = 0.0;
 | 
			
		||||
        worldviewFixed[2][3] = 0.0;
 | 
			
		||||
#else
 | 
			
		||||
        worldviewFixed[3][0] = 0;
 | 
			
		||||
        worldviewFixed[3][1] = 0;
 | 
			
		||||
        worldviewFixed[3][2] = 0;
 | 
			
		||||
        worldviewFixed[3][0] = 0.0;
 | 
			
		||||
        worldviewFixed[3][1] = 0.0;
 | 
			
		||||
        worldviewFixed[3][2] = 0.0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        shOutputPosition = shMatrixMult(proj, shMatrixMult(worldviewFixed, shInputPosition));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,13 +13,13 @@ shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix)
 | 
			
		|||
    {
 | 
			
		||||
        float4x4 viewFixed = view;
 | 
			
		||||
#if !SH_GLSL
 | 
			
		||||
        viewFixed[0][3] = 0;
 | 
			
		||||
        viewFixed[1][3] = 0;
 | 
			
		||||
        viewFixed[2][3] = 0;
 | 
			
		||||
        viewFixed[0][3] = 0.0;
 | 
			
		||||
        viewFixed[1][3] = 0.0;
 | 
			
		||||
        viewFixed[2][3] = 0.0;
 | 
			
		||||
#else
 | 
			
		||||
        viewFixed[3][0] = 0;
 | 
			
		||||
        viewFixed[3][1] = 0;
 | 
			
		||||
        viewFixed[3][2] = 0;
 | 
			
		||||
        viewFixed[3][0] = 0.0;
 | 
			
		||||
        viewFixed[3][1] = 0.0;
 | 
			
		||||
        viewFixed[3][2] = 0.0;
 | 
			
		||||
#endif
 | 
			
		||||
        shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shMatrixMult(world, shInputPosition)));
 | 
			
		||||
        UV = uv0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,13 +13,13 @@ shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix)
 | 
			
		|||
    {
 | 
			
		||||
        float4x4 viewFixed = view;
 | 
			
		||||
#if !SH_GLSL
 | 
			
		||||
        viewFixed[0][3] = 0;
 | 
			
		||||
        viewFixed[1][3] = 0;
 | 
			
		||||
        viewFixed[2][3] = 0;
 | 
			
		||||
        viewFixed[0][3] = 0.0;
 | 
			
		||||
        viewFixed[1][3] = 0.0;
 | 
			
		||||
        viewFixed[2][3] = 0.0;
 | 
			
		||||
#else
 | 
			
		||||
        viewFixed[3][0] = 0;
 | 
			
		||||
        viewFixed[3][1] = 0;
 | 
			
		||||
        viewFixed[3][2] = 0;
 | 
			
		||||
        viewFixed[3][0] = 0.0;
 | 
			
		||||
        viewFixed[3][1] = 0.0;
 | 
			
		||||
        viewFixed[3][2] = 0.0;
 | 
			
		||||
#endif
 | 
			
		||||
        shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shMatrixMult(world, shInputPosition)));
 | 
			
		||||
        UV = uv0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@
 | 
			
		|||
 | 
			
		||||
    SH_START_PROGRAM
 | 
			
		||||
    {
 | 
			
		||||
        shOutputColour(0).xyz = shSample(animatedTexture, UV * 15).xyz * float3(1.0, 1.0, 1.0);
 | 
			
		||||
        shOutputColour(0).xyz = shSample(animatedTexture, UV * float2(15.0, 15.0)).xyz * float3(1.0, 1.0, 1.0);
 | 
			
		||||
        shOutputColour(0).w = 0.7;
 | 
			
		||||
        
 | 
			
		||||
#if FOG
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@ set(MYGUI_FILES
 | 
			
		|||
    openmw_container_window.layout
 | 
			
		||||
    openmw_count_window.layout
 | 
			
		||||
    openmw_dialogue_window.layout
 | 
			
		||||
    openmw_dialogue_window_skin.xml
 | 
			
		||||
    openmw_dialogue_window.skin.xml
 | 
			
		||||
    openmw_edit.skin.xml
 | 
			
		||||
    openmw_font.xml
 | 
			
		||||
    openmw_hud_box.skin.xml
 | 
			
		||||
| 
						 | 
				
			
			@ -38,19 +38,19 @@ set(MYGUI_FILES
 | 
			
		|||
    openmw_interactive_messagebox.layout
 | 
			
		||||
    openmw_inventory_window.layout
 | 
			
		||||
    openmw_journal.layout
 | 
			
		||||
    openmw_journal_skin.xml
 | 
			
		||||
    openmw_journal.skin.xml
 | 
			
		||||
    openmw_layers.xml
 | 
			
		||||
    openmw_list.skin.xml
 | 
			
		||||
    openmw_mainmenu.layout
 | 
			
		||||
    openmw_mainmenu_skin.xml
 | 
			
		||||
    openmw_mainmenu.skin.xml
 | 
			
		||||
    openmw_map_window.layout
 | 
			
		||||
    openmw_map_window_skin.xml
 | 
			
		||||
    openmw_map_window.skin.xml
 | 
			
		||||
    openmw_messagebox.layout
 | 
			
		||||
    openmw_pointer.xml
 | 
			
		||||
    openmw_progress.skin.xml
 | 
			
		||||
    openmw_resources.xml
 | 
			
		||||
    openmw_scroll.layout
 | 
			
		||||
    openmw_scroll_skin.xml
 | 
			
		||||
    openmw_scroll.skin.xml
 | 
			
		||||
    openmw_settings_window.layout
 | 
			
		||||
    openmw_settings.xml
 | 
			
		||||
    openmw_spell_window.layout
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +83,8 @@ set(MYGUI_FILES
 | 
			
		|||
    openmw_recharge_dialog.layout
 | 
			
		||||
    openmw_screen_fader.layout
 | 
			
		||||
    openmw_edit_note.layout
 | 
			
		||||
    openmw_debug_window.layout
 | 
			
		||||
    openmw_debug_window.skin.xml
 | 
			
		||||
    DejaVuLGCSansMono.ttf
 | 
			
		||||
    ../launcher/images/openmw.png
 | 
			
		||||
    OpenMWResourcePlugin.xml
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,13 +15,14 @@
 | 
			
		|||
        <List file="openmw_progress.skin.xml" />
 | 
			
		||||
        <List file="openmw_hud_energybar.skin.xml" />
 | 
			
		||||
        <List file="openmw_hud_box.skin.xml" />
 | 
			
		||||
        <List file="openmw_mainmenu_skin.xml" />
 | 
			
		||||
        <List file="openmw_mainmenu.skin.xml" />
 | 
			
		||||
        <List file="openmw_console.skin.xml" />
 | 
			
		||||
        <List file="openmw_journal_skin.xml" />
 | 
			
		||||
        <List file="openmw_map_window_skin.xml" />
 | 
			
		||||
        <List file="openmw_dialogue_window_skin.xml" />
 | 
			
		||||
        <List file="openmw_scroll_skin.xml" />
 | 
			
		||||
        <List file="openmw_journal.skin.xml" />
 | 
			
		||||
        <List file="openmw_map_window.skin.xml" />
 | 
			
		||||
        <List file="openmw_dialogue_window.skin.xml" />
 | 
			
		||||
        <List file="openmw_scroll.skin.xml" />
 | 
			
		||||
        <List file="openmw_settings.xml" />
 | 
			
		||||
        <List file="openmw_debug_window.skin.xml" />
 | 
			
		||||
    </MyGUI>
 | 
			
		||||
</MyGUI>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,36 @@
 | 
			
		|||
        <Child type="Widget" skin="BTN_BottomLeft" offset="0 20 4 4" align="Bottom Left"/>
 | 
			
		||||
        <Child type="Widget" skin="BTN_BottomRight" offset="132 20 4 4" align="Bottom Right"/>
 | 
			
		||||
 | 
			
		||||
        <BasisSkin type="SimpleText" offset="4 4 128 16" align="Stretch">
 | 
			
		||||
            <State name="disabled" colour="#{fontcolour=disabled}" shift="0"/>
 | 
			
		||||
            <State name="normal" colour="#{fontcolour=normal}" shift="0"/>
 | 
			
		||||
            <State name="highlighted" colour="#{fontcolour=normal_over}" shift="0"/>
 | 
			
		||||
            <State name="pushed" colour="#{fontcolour=normal_pressed}" shift="0"/>
 | 
			
		||||
            <State name="disabled_checked" colour="#{fontcolour=disabled}" shift="0"/>
 | 
			
		||||
            <State name="normal_checked" colour="#{fontcolour=active}" shift="0"/>
 | 
			
		||||
            <State name="highlighted_checked" colour="#{fontcolour=active_over}" shift="0"/>
 | 
			
		||||
            <State name="pushed_checked" colour="#{fontcolour=active_pressed}" shift="0"/>
 | 
			
		||||
        </BasisSkin>
 | 
			
		||||
   </Resource>
 | 
			
		||||
 | 
			
		||||
    <!-- Button widget, 4 px padding on the right -->
 | 
			
		||||
    <Resource type="ResourceSkin" name="MW_Button_RightPadding" size="140 24" version="3.2.1">
 | 
			
		||||
        <Property key="FontName" value="Default"/>
 | 
			
		||||
        <Property key="TextAlign" value="Center"/>
 | 
			
		||||
 | 
			
		||||
        <!-- padding -->
 | 
			
		||||
        <Child type="Widget" skin="" offset="136 0 4 24" align="Right VStretch"/>
 | 
			
		||||
 | 
			
		||||
        <Child type="Widget" skin="BTN_Left" offset="0 4 4 16" align="VStretch Left"/>
 | 
			
		||||
        <Child type="Widget" skin="BTN_Right" offset="132 4 4 16" align="VStretch Right"/>
 | 
			
		||||
        <Child type="Widget" skin="BTN_Top" offset="4 0 128 4" align="HStretch Top"/>
 | 
			
		||||
        <Child type="Widget" skin="BTN_Bottom" offset="4 20 128 4" align="HStretch Bottom"/>
 | 
			
		||||
        <Child type="Widget" skin="BTN_TopLeft" offset="0 0 4 4" align="Top Left"/>
 | 
			
		||||
        <Child type="Widget" skin="BTN_TopRight" offset="132 0 4 4" align="Top Right"/>
 | 
			
		||||
        <Child type="Widget" skin="BTN_BottomLeft" offset="0 20 4 4" align="Bottom Left"/>
 | 
			
		||||
        <Child type="Widget" skin="BTN_BottomRight" offset="132 20 4 4" align="Bottom Right"/>
 | 
			
		||||
        <Child type="Widget" skin="BTN_BottomRight" offset="132 20 4 4" align="Bottom Right"/>
 | 
			
		||||
 | 
			
		||||
        <BasisSkin type="SimpleText" offset="4 4 128 16" align="Stretch">
 | 
			
		||||
            <State name="disabled" colour="#{fontcolour=disabled}" shift="0"/>
 | 
			
		||||
            <State name="normal" colour="#{fontcolour=normal}" shift="0"/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue