mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-01 20:45:33 +00:00
Merge branch 'master' of https://github.com/zinnschlag/openmw.git into AICombat
Conflicts: apps/openmw/mwmechanics/actors.cpp apps/openmw/mwscript/docs/vmformat.txt
This commit is contained in:
commit
d587f3c946
188 changed files with 2615 additions and 836 deletions
51
.gitignore
vendored
51
.gitignore
vendored
|
@ -1,24 +1,53 @@
|
|||
build
|
||||
*~
|
||||
Doxygen
|
||||
prebuilt
|
||||
apps/openmw/config.hpp
|
||||
Docs/mainpage.hpp
|
||||
## make
|
||||
CMakeFiles
|
||||
*/CMakeFiles
|
||||
CMakeCache.txt
|
||||
moc_*.cxx
|
||||
cmake_install.cmake
|
||||
*.[ao]
|
||||
CMakeLists.txt.user
|
||||
Makefile
|
||||
makefile
|
||||
data
|
||||
build
|
||||
prebuilt
|
||||
|
||||
## doxygen
|
||||
Doxygen
|
||||
|
||||
## ides/editors
|
||||
*~
|
||||
*.kdev4
|
||||
CMakeLists.txt.user
|
||||
*.swp
|
||||
*.swo
|
||||
*.kate-swp
|
||||
.cproject
|
||||
.project
|
||||
.settings/
|
||||
.settings
|
||||
.directory
|
||||
|
||||
## resources
|
||||
data
|
||||
resources
|
||||
/*.cfg
|
||||
/*.desktop
|
||||
/*.install
|
||||
|
||||
## binaries
|
||||
/esmtool
|
||||
/mwiniimport
|
||||
/omwlauncher
|
||||
/openmw
|
||||
/opencs
|
||||
|
||||
## generated objects
|
||||
apps/openmw/config.hpp
|
||||
Docs/mainpage.hpp
|
||||
moc_*.cxx
|
||||
*.cxx_parameters
|
||||
*qrc_launcher.cxx
|
||||
*qrc_resources.cxx
|
||||
*__*
|
||||
*ui_datafilespage.h
|
||||
*ui_graphicspage.h
|
||||
*ui_mainwindow.h
|
||||
*ui_playpage.h
|
||||
*.[ao]
|
||||
*.so
|
||||
|
|
|
@ -79,7 +79,6 @@ set(OENGINE_OGRE
|
|||
${LIBDIR}/openengine/ogre/renderer.cpp
|
||||
${LIBDIR}/openengine/ogre/fader.cpp
|
||||
${LIBDIR}/openengine/ogre/lights.cpp
|
||||
${LIBDIR}/openengine/ogre/particles.cpp
|
||||
${LIBDIR}/openengine/ogre/selectionbuffer.cpp
|
||||
${LIBDIR}/openengine/ogre/imagerotate.cpp
|
||||
)
|
||||
|
@ -161,6 +160,20 @@ if (NOT FFMPEG_FOUND)
|
|||
message(WARNING "--------------------")
|
||||
endif (NOT FFMPEG_FOUND)
|
||||
|
||||
# TinyXML
|
||||
option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF)
|
||||
if(USE_SYSTEM_TINYXML)
|
||||
find_library(TINYXML_LIBRARIES tinyxml)
|
||||
find_path(TINYXML_INCLUDE_DIR tinyxml.h)
|
||||
message(STATUS "Found TinyXML: ${TINYXML_LIBRARIES} ${TINYXML_INCLUDE_DIR}")
|
||||
add_definitions (-DTIXML_USE_STL)
|
||||
if(TINYXML_LIBRARIES AND TINYXML_INCLUDE_DIR)
|
||||
include_directories(${TINYXML_INCLUDE_DIR})
|
||||
message(STATUS "Using system TinyXML library.")
|
||||
else()
|
||||
message(FATAL_ERROR "Detection of system TinyXML incomplete.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Platform specific
|
||||
if (WIN32)
|
||||
|
|
|
@ -10,12 +10,9 @@
|
|||
#endif
|
||||
#include <SDL.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <boost/math/common_factor.hpp>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/files/ogreplugin.hpp>
|
||||
|
||||
#include <components/fileorderlist/utils/naturalsort.hpp>
|
||||
|
||||
|
@ -54,13 +51,9 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g
|
|||
|
||||
bool GraphicsPage::setupOgre()
|
||||
{
|
||||
// Create a log manager so we can surpress debug text to stdout/stderr
|
||||
Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager;
|
||||
logMgr->createLog((mCfgMgr.getLogPath().string() + "/launcherOgre.log"), true, false, false);
|
||||
|
||||
try
|
||||
{
|
||||
mOgre = new Ogre::Root("", "", "./launcherOgre.log");
|
||||
mOgre = mOgreInit.init(mCfgMgr.getLogPath().string() + "/launcherOgre.log");
|
||||
}
|
||||
catch(Ogre::Exception &ex)
|
||||
{
|
||||
|
@ -78,40 +71,6 @@ bool GraphicsPage::setupOgre()
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::string pluginDir;
|
||||
const char* pluginEnv = getenv("OPENMW_OGRE_PLUGIN_DIR");
|
||||
if (pluginEnv)
|
||||
pluginDir = pluginEnv;
|
||||
else
|
||||
{
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||
pluginDir = ".\\";
|
||||
#endif
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
pluginDir = OGRE_PLUGIN_DIR;
|
||||
#endif
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
||||
pluginDir = OGRE_PLUGIN_DIR_REL;
|
||||
#endif
|
||||
}
|
||||
|
||||
QDir dir(QString::fromStdString(pluginDir));
|
||||
pluginDir = dir.absolutePath().toStdString();
|
||||
|
||||
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mOgre);
|
||||
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mOgre);
|
||||
Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mOgre);
|
||||
|
||||
#ifdef ENABLE_PLUGIN_GL
|
||||
mGLPlugin = new Ogre::GLPlugin();
|
||||
mOgre->installPlugin(mGLPlugin);
|
||||
#endif
|
||||
#ifdef ENABLE_PLUGIN_Direct3D9
|
||||
mD3D9Plugin = new Ogre::D3D9Plugin();
|
||||
mOgre->installPlugin(mD3D9Plugin);
|
||||
#endif
|
||||
|
||||
// Get the available renderers and put them in the combobox
|
||||
const Ogre::RenderSystemList &renderers = mOgre->getAvailableRenderers();
|
||||
|
||||
|
@ -133,7 +92,7 @@ bool GraphicsPage::setupOgre()
|
|||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not select a valid render system</b><br><br> \
|
||||
Please make sure the plugins.cfg file exists and contains a valid rendering plugin.<br>"));
|
||||
Please make sure Ogre plugins were installed correctly.<br>"));
|
||||
msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -5,16 +5,9 @@
|
|||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderSystem.h>
|
||||
//#include <OgreConfigFile.h>
|
||||
//#include <OgreConfigDialog.h>
|
||||
|
||||
// Static plugin headers
|
||||
#ifdef ENABLE_PLUGIN_GL
|
||||
# include "OgreGLPlugin.h"
|
||||
#endif
|
||||
#ifdef ENABLE_PLUGIN_Direct3D9
|
||||
# include "OgreD3D9Plugin.h"
|
||||
#endif
|
||||
#include <components/ogreinit/ogreinit.hpp>
|
||||
|
||||
|
||||
#include "ui_graphicspage.h"
|
||||
|
||||
|
@ -41,16 +34,13 @@ private slots:
|
|||
void slotStandardToggled(bool checked);
|
||||
|
||||
private:
|
||||
OgreInit::OgreInit mOgreInit;
|
||||
|
||||
Ogre::Root *mOgre;
|
||||
Ogre::RenderSystem *mSelectedRenderSystem;
|
||||
Ogre::RenderSystem *mOpenGLRenderSystem;
|
||||
Ogre::RenderSystem *mDirect3DRenderSystem;
|
||||
#ifdef ENABLE_PLUGIN_GL
|
||||
Ogre::GLPlugin* mGLPlugin;
|
||||
#endif
|
||||
#ifdef ENABLE_PLUGIN_Direct3D9
|
||||
Ogre::D3D9Plugin* mD3D9Plugin;
|
||||
#endif
|
||||
|
||||
|
||||
Files::ConfigurationManager &mCfgMgr;
|
||||
GraphicsSettings &mGraphicsSettings;
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include <SDL.h>
|
||||
|
||||
#include "maindialog.hpp"
|
||||
// SDL workaround
|
||||
#include "graphicspage.hpp"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
|
|
@ -77,6 +77,8 @@ namespace
|
|||
ini.insert(loc, setting + "=" + val + "\r\n");
|
||||
}
|
||||
|
||||
#define FIX(setting) add_setting(category, setting, get_setting(category, setting, inx), ini)
|
||||
|
||||
void bloodmoon_fix_ini(std::string& ini, const bfs::path inxPath)
|
||||
{
|
||||
std::string inx = read_to_string(inxPath);
|
||||
|
@ -88,95 +90,94 @@ namespace
|
|||
ini.erase(start, end-start);
|
||||
|
||||
std::string category;
|
||||
std::string setting;
|
||||
|
||||
category = "General";
|
||||
{
|
||||
setting = "Werewolf FOV"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Werewolf FOV");
|
||||
}
|
||||
category = "Moons";
|
||||
{
|
||||
setting = "Script Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Script Color");
|
||||
}
|
||||
category = "Weather";
|
||||
{
|
||||
setting = "Snow Ripples"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Ripple Radius"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Ripples Per Flake"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Ripple Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Ripple Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Gravity Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow High Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Low Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Snow Ripples");
|
||||
FIX("Snow Ripple Radius");
|
||||
FIX("Snow Ripples Per Flake");
|
||||
FIX("Snow Ripple Scale");
|
||||
FIX("Snow Ripple Speed");
|
||||
FIX("Snow Gravity Scale");
|
||||
FIX("Snow High Kill");
|
||||
FIX("Snow Low Kill");
|
||||
}
|
||||
category = "Weather Blight";
|
||||
{
|
||||
setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Ambient Loop Sound ID");
|
||||
}
|
||||
category = "Weather Snow";
|
||||
{
|
||||
setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Diameter"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Height Min"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Height Max"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Snow Entrance Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Max Snowflakes"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Sky Sunrise Color");
|
||||
FIX("Sky Day Color");
|
||||
FIX("Sky Sunset Color");
|
||||
FIX("Sky Night Color");
|
||||
FIX("Fog Sunrise Color");
|
||||
FIX("Fog Day Color");
|
||||
FIX("Fog Sunset Color");
|
||||
FIX("Fog Night Color");
|
||||
FIX("Ambient Sunrise Color");
|
||||
FIX("Ambient Day Color");
|
||||
FIX("Ambient Sunset Color");
|
||||
FIX("Ambient Night Color");
|
||||
FIX("Sun Sunrise Color");
|
||||
FIX("Sun Day Color");
|
||||
FIX("Sun Sunset Color");
|
||||
FIX("Sun Night Color");
|
||||
FIX("Sun Disc Sunset Color");
|
||||
FIX("Transition Delta");
|
||||
FIX("Land Fog Day Depth");
|
||||
FIX("Land Fog Night Depth");
|
||||
FIX("Clouds Maximum Percent");
|
||||
FIX("Wind Speed");
|
||||
FIX("Cloud Speed");
|
||||
FIX("Glare View");
|
||||
FIX("Cloud Texture");
|
||||
FIX("Ambient Loop Sound ID");
|
||||
FIX("Snow Threshold");
|
||||
FIX("Snow Diameter");
|
||||
FIX("Snow Height Min");
|
||||
FIX("Snow Height Max");
|
||||
FIX("Snow Entrance Speed");
|
||||
FIX("Max Snowflakes");
|
||||
}
|
||||
category = "Weather Blizzard";
|
||||
{
|
||||
setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
setting = "Storm Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini);
|
||||
FIX("Sky Sunrise Color");
|
||||
FIX("Sky Day Color");
|
||||
FIX("Sky Sunset Color");
|
||||
FIX("Sky Night Color");
|
||||
FIX("Fog Sunrise Color");
|
||||
FIX("Fog Day Color");
|
||||
FIX("Fog Sunset Color");
|
||||
FIX("Fog Night Color");
|
||||
FIX("Ambient Sunrise Color");
|
||||
FIX("Ambient Day Color");
|
||||
FIX("Ambient Sunset Color");
|
||||
FIX("Ambient Night Color");
|
||||
FIX("Sun Sunrise Color");
|
||||
FIX("Sun Day Color");
|
||||
FIX("Sun Sunset Color");
|
||||
FIX("Sun Night Color");
|
||||
FIX("Sun Disc Sunset Color");
|
||||
FIX("Transition Delta");
|
||||
FIX("Land Fog Day Depth");
|
||||
FIX("Land Fog Night Depth");
|
||||
FIX("Clouds Maximum Percent");
|
||||
FIX("Wind Speed");
|
||||
FIX("Cloud Speed");
|
||||
FIX("Glare View");
|
||||
FIX("Cloud Texture");
|
||||
FIX("Ambient Loop Sound ID");
|
||||
FIX("Storm Threshold");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,6 +269,27 @@ namespace
|
|||
strptime(time, "%d %B %Y", &tms);
|
||||
return mktime(&tms);
|
||||
}
|
||||
|
||||
// Some cds have cab files which have the Data Files subfolders outside the Data Files folder
|
||||
void install_dfiles_outside(const bfs::path& from, const bfs::path& dFiles)
|
||||
{
|
||||
bfs::path fonts = findFile(from, "fonts", false);
|
||||
if(fonts.string() != "")
|
||||
installToPath(fonts, dFiles / "Fonts");
|
||||
|
||||
bfs::path music = findFile(from, "music", false);
|
||||
if(music.string() != "")
|
||||
installToPath(music, dFiles / "Music");
|
||||
|
||||
bfs::path sound = findFile(from, "sound", false);
|
||||
if(sound.string() != "")
|
||||
installToPath(sound, dFiles / "Sound");
|
||||
|
||||
bfs::path splash = findFile(from, "splash", false);
|
||||
if(splash.string() != "")
|
||||
installToPath(splash, dFiles / "Splash");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool UnshieldThread::SetMorrowindPath(const std::string& path)
|
||||
|
@ -365,6 +387,8 @@ bool UnshieldThread::extract()
|
|||
|
||||
installToPath(dFilesDir, outputDataFilesDir);
|
||||
|
||||
install_dfiles_outside(mwExtractPath, outputDataFilesDir);
|
||||
|
||||
// Videos are often kept uncompressed on the cd
|
||||
bfs::path videosPath = findFile(mMorrowindPath.parent_path(), "video", false);
|
||||
if(videosPath.string() != "")
|
||||
|
@ -399,6 +423,8 @@ bool UnshieldThread::extract()
|
|||
|
||||
installToPath(dFilesDir, outputDataFilesDir);
|
||||
|
||||
install_dfiles_outside(tbExtractPath, outputDataFilesDir);
|
||||
|
||||
// Mt GOTY CD has Sounds in a seperate folder from the rest of the data files
|
||||
bfs::path soundsPath = findFile(tbExtractPath, "sounds", false);
|
||||
if(soundsPath.string() != "")
|
||||
|
@ -426,6 +452,8 @@ bool UnshieldThread::extract()
|
|||
bfs::path dFilesDir = findFile(bmExtractPath, "bloodmoon.esm").parent_path();
|
||||
|
||||
installToPath(dFilesDir, outputDataFilesDir);
|
||||
|
||||
install_dfiles_outside(bmExtractPath, outputDataFilesDir);
|
||||
|
||||
// My GOTY CD contains a folder within cab files called Tribunal patch,
|
||||
// which contains Tribunal.esm
|
||||
|
|
|
@ -18,12 +18,12 @@ opencs_hdrs_noqt (model/doc
|
|||
|
||||
|
||||
opencs_units (model/world
|
||||
idtable idtableproxymodel regionmap
|
||||
idtable idtableproxymodel regionmap data
|
||||
)
|
||||
|
||||
|
||||
opencs_units_noqt (model/world
|
||||
universalid data record commands columnbase scriptcontext cell refidcollection
|
||||
universalid record commands columnbase scriptcontext cell refidcollection
|
||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns
|
||||
)
|
||||
|
||||
|
@ -43,7 +43,8 @@ opencs_units_noqt (model/tools
|
|||
|
||||
|
||||
opencs_units (view/doc
|
||||
viewmanager view operations operation subview startup filedialog
|
||||
viewmanager view operations operation subview startup filedialog newgame filewidget
|
||||
adjusterwidget
|
||||
)
|
||||
|
||||
|
||||
|
@ -58,12 +59,13 @@ opencs_hdrs_noqt (view/doc
|
|||
|
||||
opencs_units (view/world
|
||||
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
|
||||
cellcreator referenceablecreator referencecreator
|
||||
cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool
|
||||
scenetoolmode
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/world
|
||||
dialoguesubview subviews
|
||||
enumdelegate vartypedelegate recordstatusdelegate refidtypedelegate datadisplaydelegate
|
||||
enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||
scripthighlighter idvalidator
|
||||
)
|
||||
|
||||
|
|
|
@ -4,27 +4,35 @@
|
|||
#include <QApplication>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "model/doc/document.hpp"
|
||||
#include "model/world/data.hpp"
|
||||
|
||||
|
||||
CS::Editor::Editor() : mViewManager (mDocumentManager)
|
||||
{
|
||||
mIpcServerName = "org.openmw.OpenCS";
|
||||
|
||||
connect (&mViewManager, SIGNAL (newDocumentRequest ()), this, SLOT (createDocument ()));
|
||||
setupDataFiles();
|
||||
|
||||
mNewGame.setLocalData (mLocal);
|
||||
|
||||
connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ()));
|
||||
connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ()));
|
||||
connect (&mViewManager, SIGNAL (loadDocumentRequest ()), this, SLOT (loadDocument ()));
|
||||
connect (&mViewManager, SIGNAL (editSettingsRequest()), this, SLOT (showSettings ()));
|
||||
|
||||
connect (&mStartup, SIGNAL (createGame()), this, SLOT (createDocument ())); /// \todo split
|
||||
connect (&mStartup, SIGNAL (createAddon()), this, SLOT (createDocument ()));
|
||||
connect (&mStartup, SIGNAL (createGame()), this, SLOT (createGame ()));
|
||||
connect (&mStartup, SIGNAL (createAddon()), this, SLOT (createAddon ()));
|
||||
connect (&mStartup, SIGNAL (loadDocument()), this, SLOT (loadDocument ()));
|
||||
connect (&mStartup, SIGNAL (editConfig()), this, SLOT (showSettings ()));
|
||||
|
||||
connect (&mFileDialog, SIGNAL(openFiles()), this, SLOT(openFiles()));
|
||||
connect (&mFileDialog, SIGNAL(createNewFile()), this, SLOT(createNewFile()));
|
||||
|
||||
setupDataFiles();
|
||||
connect (&mNewGame, SIGNAL (createRequest (const boost::filesystem::path&)),
|
||||
this, SLOT (createNewGame (const boost::filesystem::path&)));
|
||||
}
|
||||
|
||||
void CS::Editor::setupDataFiles()
|
||||
|
@ -42,26 +50,39 @@ void CS::Editor::setupDataFiles()
|
|||
|
||||
mCfgMgr.readConfiguration(variables, desc);
|
||||
|
||||
Files::PathContainer mDataDirs, mDataLocal;
|
||||
Files::PathContainer dataDirs, dataLocal;
|
||||
if (!variables["data"].empty()) {
|
||||
mDataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||
dataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||
}
|
||||
|
||||
std::string local = variables["data-local"].as<std::string>();
|
||||
if (!local.empty()) {
|
||||
mDataLocal.push_back(Files::PathContainer::value_type(local));
|
||||
dataLocal.push_back(Files::PathContainer::value_type(local));
|
||||
}
|
||||
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
mCfgMgr.processPaths(mDataLocal);
|
||||
mCfgMgr.processPaths (dataDirs);
|
||||
mCfgMgr.processPaths (dataLocal, true);
|
||||
|
||||
if (!dataLocal.empty())
|
||||
mLocal = dataLocal[0];
|
||||
else
|
||||
{
|
||||
QMessageBox messageBox;
|
||||
messageBox.setWindowTitle (tr ("No local data path available"));
|
||||
messageBox.setIcon (QMessageBox::Critical);
|
||||
messageBox.setStandardButtons (QMessageBox::Ok);
|
||||
messageBox.setText(tr("<br><b>OpenCS is unable to access the local data directory. This may indicate a faulty configuration or a broken install.</b>"));
|
||||
messageBox.exec();
|
||||
|
||||
QApplication::exit (1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the charset for reading the esm/esp files
|
||||
QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
||||
mFileDialog.setEncoding(encoding);
|
||||
|
||||
Files::PathContainer dataDirs;
|
||||
dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end());
|
||||
dataDirs.insert(dataDirs.end(), mDataLocal.begin(), mDataLocal.end());
|
||||
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
||||
|
||||
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
|
||||
{
|
||||
|
@ -72,10 +93,20 @@ void CS::Editor::setupDataFiles()
|
|||
//load the settings into the userSettings instance.
|
||||
const QString settingFileName = "opencs.cfg";
|
||||
CSMSettings::UserSettings::instance().loadSettings(settingFileName);
|
||||
|
||||
}
|
||||
|
||||
void CS::Editor::createDocument()
|
||||
void CS::Editor::createGame()
|
||||
{
|
||||
mStartup.hide();
|
||||
|
||||
if (mNewGame.isHidden())
|
||||
mNewGame.show();
|
||||
|
||||
mNewGame.raise();
|
||||
mNewGame.activateWindow();
|
||||
}
|
||||
|
||||
void CS::Editor::createAddon()
|
||||
{
|
||||
mStartup.hide();
|
||||
|
||||
|
@ -98,7 +129,9 @@ void CS::Editor::openFiles()
|
|||
files.push_back(path.toStdString());
|
||||
}
|
||||
|
||||
CSMDoc::Document *document = mDocumentManager.addDocument(files, false);
|
||||
/// \todo Get the save path from the file dialogue
|
||||
|
||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), false);
|
||||
|
||||
mViewManager.addView (document);
|
||||
mFileDialog.hide();
|
||||
|
@ -115,12 +148,27 @@ void CS::Editor::createNewFile()
|
|||
|
||||
files.push_back(mFileDialog.fileName().toStdString());
|
||||
|
||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, true);
|
||||
/// \todo Get the save path from the file dialogue.
|
||||
|
||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), true);
|
||||
|
||||
mViewManager.addView (document);
|
||||
mFileDialog.hide();
|
||||
}
|
||||
|
||||
void CS::Editor::createNewGame (const boost::filesystem::path& file)
|
||||
{
|
||||
std::vector<boost::filesystem::path> files;
|
||||
|
||||
files.push_back (file);
|
||||
|
||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, file, true);
|
||||
|
||||
mViewManager.addView (document);
|
||||
|
||||
mNewGame.hide();
|
||||
}
|
||||
|
||||
void CS::Editor::showStartup()
|
||||
{
|
||||
if(mStartup.isHidden())
|
||||
|
@ -161,6 +209,9 @@ void CS::Editor::connectToIPCServer()
|
|||
|
||||
int CS::Editor::run()
|
||||
{
|
||||
if (mLocal.empty())
|
||||
return 1;
|
||||
|
||||
mStartup.show();
|
||||
|
||||
QApplication::setQuitOnLastWindowClosed (true);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "view/doc/viewmanager.hpp"
|
||||
#include "view/doc/startup.hpp"
|
||||
#include "view/doc/filedialog.hpp"
|
||||
#include "view/doc/newgame.hpp"
|
||||
|
||||
#include "view/settings/usersettingsdialog.hpp"
|
||||
|
||||
|
@ -29,10 +30,13 @@ namespace CS
|
|||
CSMDoc::DocumentManager mDocumentManager;
|
||||
CSVDoc::ViewManager mViewManager;
|
||||
CSVDoc::StartupDialogue mStartup;
|
||||
CSVDoc::NewGameDialogue mNewGame;
|
||||
CSVSettings::UserSettingsDialog mSettings;
|
||||
FileDialog mFileDialog;
|
||||
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
boost::filesystem::path mLocal;
|
||||
|
||||
void setupDataFiles();
|
||||
|
||||
// not implemented
|
||||
|
@ -51,11 +55,13 @@ namespace CS
|
|||
|
||||
private slots:
|
||||
|
||||
void createDocument();
|
||||
void createGame();
|
||||
void createAddon();
|
||||
|
||||
void loadDocument();
|
||||
void openFiles();
|
||||
void createNewFile();
|
||||
void createNewGame (const boost::filesystem::path& file);
|
||||
|
||||
void showStartup();
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
if(!editor.makeIPCServer())
|
||||
{
|
||||
editor.connectToIPCServer();
|
||||
return 0;
|
||||
editor.connectToIPCServer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return editor.run();
|
||||
|
|
|
@ -2139,18 +2139,13 @@ void CSMDoc::Document::createBase()
|
|||
}
|
||||
}
|
||||
|
||||
CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files, bool new_)
|
||||
: mTools (mData)
|
||||
CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files,
|
||||
const boost::filesystem::path& savePath, bool new_)
|
||||
: mSavePath (savePath), mTools (mData)
|
||||
{
|
||||
if (files.empty())
|
||||
throw std::runtime_error ("Empty content file sequence");
|
||||
|
||||
/// \todo adjust last file name:
|
||||
/// \li make sure it is located in the data-local directory (adjust path if necessary)
|
||||
/// \li make sure the extension matches the new scheme (change it if necesarry)
|
||||
|
||||
mName = files.back().filename().string();
|
||||
|
||||
if (new_ && files.size()==1)
|
||||
createBase();
|
||||
else
|
||||
|
@ -2201,9 +2196,9 @@ int CSMDoc::Document::getState() const
|
|||
return state;
|
||||
}
|
||||
|
||||
const std::string& CSMDoc::Document::getName() const
|
||||
const boost::filesystem::path& CSMDoc::Document::getSavePath() const
|
||||
{
|
||||
return mName;
|
||||
return mSavePath;
|
||||
}
|
||||
|
||||
void CSMDoc::Document::save()
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace CSMDoc
|
|||
|
||||
private:
|
||||
|
||||
std::string mName; ///< \todo replace name with ESX list
|
||||
boost::filesystem::path mSavePath;
|
||||
CSMWorld::Data mData;
|
||||
CSMTools::Tools mTools;
|
||||
|
||||
|
@ -64,15 +64,16 @@ namespace CSMDoc
|
|||
|
||||
public:
|
||||
|
||||
Document (const std::vector<boost::filesystem::path>& files, bool new_);
|
||||
Document (const std::vector<boost::filesystem::path>& files,
|
||||
const boost::filesystem::path& savePath, bool new_);
|
||||
|
||||
~Document();
|
||||
|
||||
QUndoStack& getUndoStack();
|
||||
|
||||
int getState() const;
|
||||
|
||||
const std::string& getName() const;
|
||||
///< \todo replace with ESX list
|
||||
const boost::filesystem::path& getSavePath() const;
|
||||
|
||||
void save();
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@ CSMDoc::DocumentManager::~DocumentManager()
|
|||
delete *iter;
|
||||
}
|
||||
|
||||
CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files,
|
||||
CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
|
||||
bool new_)
|
||||
{
|
||||
Document *document = new Document (files, new_);
|
||||
Document *document = new Document (files, savePath, new_);
|
||||
|
||||
mDocuments.push_back (document);
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ namespace CSMDoc
|
|||
|
||||
~DocumentManager();
|
||||
|
||||
Document *addDocument (const std::vector<boost::filesystem::path>& files, bool new_);
|
||||
Document *addDocument (const std::vector<boost::filesystem::path>& files,
|
||||
const boost::filesystem::path& savePath, bool new_);
|
||||
///< The ownership of the returned document is not transferred to the caller.
|
||||
///
|
||||
/// \param new_ Do not load the last content file in \a files and instead create in an
|
||||
|
|
|
@ -34,7 +34,7 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row,
|
|||
{
|
||||
string = data.toString();
|
||||
}
|
||||
else if (data.type()==QVariant::Int || data.type()==QVariant::UInt ||
|
||||
else if ((data.type()==QVariant::Int || data.type()==QVariant::UInt) &&
|
||||
CSMWorld::Columns::hasEnums (static_cast<CSMWorld::Columns::ColumnId> (mColumnId)))
|
||||
{
|
||||
int value = data.toInt();
|
||||
|
@ -47,8 +47,10 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row,
|
|||
}
|
||||
else if (data.type()==QVariant::Bool)
|
||||
{
|
||||
string = data.toBool() ? "true" : " false";
|
||||
string = data.toBool() ? "true" : "false";
|
||||
}
|
||||
else if (mText.empty() && !data.isValid())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row,
|
|||
const std::map<int, int>::const_iterator iter = columns.find (mColumnId);
|
||||
|
||||
if (iter==columns.end())
|
||||
throw std::logic_error ("invalid column in test value test");
|
||||
throw std::logic_error ("invalid column in value node test");
|
||||
|
||||
if (iter->second==-1)
|
||||
return true;
|
||||
|
@ -27,7 +27,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row,
|
|||
QVariant data = table.data (index);
|
||||
|
||||
if (data.type()!=QVariant::Double && data.type()!=QVariant::Bool && data.type()!=QVariant::Int &&
|
||||
data.type()!=QVariant::UInt)
|
||||
data.type()!=QVariant::UInt && data.type()!=static_cast<QVariant::Type> (QMetaType::Float))
|
||||
return false;
|
||||
|
||||
double value = data.toDouble();
|
||||
|
@ -68,7 +68,7 @@ std::string CSMFilter::ValueNode::toString (bool numericColumns) const
|
|||
<< CSMWorld::Columns::getName (static_cast<CSMWorld::Columns::ColumnId> (mColumnId))
|
||||
<< "\"";
|
||||
|
||||
stream << ", \"";
|
||||
stream << ", ";
|
||||
|
||||
if (mLower==mUpper && mLowerType!=Type_Infinite && mUpperType!=Type_Infinite)
|
||||
stream << mLower;
|
||||
|
|
|
@ -19,7 +19,12 @@ int CSMTools::BirthsignCheckStage::setup()
|
|||
|
||||
void CSMTools::BirthsignCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::BirthSign& birthsign = mBirthsigns.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::BirthSign>& record = mBirthsigns.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::BirthSign& birthsign = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Birthsign, birthsign.mId);
|
||||
|
||||
|
|
|
@ -20,7 +20,12 @@ int CSMTools::ClassCheckStage::setup()
|
|||
|
||||
void CSMTools::ClassCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Class& class_= mClasses.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Class>& record = mClasses.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Class& class_ = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Class, class_.mId);
|
||||
|
||||
|
|
|
@ -20,7 +20,12 @@ int CSMTools::FactionCheckStage::setup()
|
|||
|
||||
void CSMTools::FactionCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Faction& faction = mFactions.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Faction>& record = mFactions.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Faction& faction = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Faction, faction.mId);
|
||||
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
|
||||
void CSMTools::RaceCheckStage::performPerRecord (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Race& race = mRaces.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Race>& record = mRaces.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Race& race = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Race, race.mId);
|
||||
|
||||
|
|
|
@ -19,7 +19,12 @@ int CSMTools::RegionCheckStage::setup()
|
|||
|
||||
void CSMTools::RegionCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Region& region = mRegions.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Region>& record = mRegions.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Region& region = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Region, region.mId);
|
||||
|
||||
|
|
|
@ -18,7 +18,12 @@ int CSMTools::SkillCheckStage::setup()
|
|||
|
||||
void CSMTools::SkillCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Skill& skill = mSkills.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Skill>& record = mSkills.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Skill& skill = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Skill, skill.mId);
|
||||
|
||||
|
|
|
@ -18,7 +18,12 @@ int CSMTools::SoundCheckStage::setup()
|
|||
|
||||
void CSMTools::SoundCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Sound& sound = mSounds.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Sound>& record = mSounds.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Sound& sound = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId);
|
||||
|
||||
|
|
|
@ -19,7 +19,12 @@ int CSMTools::SpellCheckStage::setup()
|
|||
|
||||
void CSMTools::SpellCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Spell& spell = mSpells.getRecord (stage).get();
|
||||
const CSMWorld::Record<ESM::Spell>& record = mSpells.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
const ESM::Spell& spell = record.get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Spell, spell.mId);
|
||||
|
||||
|
|
|
@ -107,6 +107,11 @@ namespace CSMWorld
|
|||
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual std::vector<std::string> getIds (bool listDeleted = true) const;
|
||||
///< Return a sorted collection of all IDs
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
|
||||
void addColumn (Column<ESXRecordT> *column);
|
||||
|
||||
void setRecord (int index, const Record<ESXRecordT>& record);
|
||||
|
@ -293,6 +298,21 @@ namespace CSMWorld
|
|||
return static_cast<int> (mRecords.size());
|
||||
}
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
std::vector<std::string> Collection<ESXRecordT, IdAccessorT>::getIds (bool listDeleted) const
|
||||
{
|
||||
std::vector<std::string> ids;
|
||||
|
||||
for (typename std::map<std::string, int>::const_iterator iter = mIndex.begin();
|
||||
iter!=mIndex.end(); ++iter)
|
||||
{
|
||||
if (listDeleted || !mRecords[iter->second].isDeleted())
|
||||
ids.push_back (IdAccessorT().getId (mRecords[iter->second].get()));
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
const Record<ESXRecordT>& Collection<ESXRecordT, IdAccessorT>::getRecord (const std::string& id) const
|
||||
{
|
||||
|
|
|
@ -78,8 +78,12 @@ namespace CSMWorld
|
|||
|
||||
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const = 0;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
};
|
||||
|
||||
virtual std::vector<std::string> getIds (bool listDeleted = true) const = 0;
|
||||
///< Return a sorted collection of all IDs
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1216,6 +1216,74 @@ namespace CSMWorld
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct PosColumn : public Column<ESXRecordT>
|
||||
{
|
||||
ESM::Position ESXRecordT::* mPosition;
|
||||
int mIndex;
|
||||
|
||||
PosColumn (ESM::Position ESXRecordT::* position, int index, bool door)
|
||||
: Column<ESXRecordT> (
|
||||
(door ? Columns::ColumnId_DoorPositionXPos : Columns::ColumnId_PositionXPos)+index,
|
||||
ColumnBase::Display_Float), mPosition (position), mIndex (index) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
const ESM::Position& position = record.get().*mPosition;
|
||||
return position.pos[mIndex];
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
ESM::Position& position = record.get().*mPosition;
|
||||
|
||||
position.pos[mIndex] = data.toFloat();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct RotColumn : public Column<ESXRecordT>
|
||||
{
|
||||
ESM::Position ESXRecordT::* mPosition;
|
||||
int mIndex;
|
||||
|
||||
RotColumn (ESM::Position ESXRecordT::* position, int index, bool door)
|
||||
: Column<ESXRecordT> (
|
||||
(door ? Columns::ColumnId_DoorPositionXRot : Columns::ColumnId_PositionXRot)+index,
|
||||
ColumnBase::Display_Float), mPosition (position), mIndex (index) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
const ESM::Position& position = record.get().*mPosition;
|
||||
return position.rot[mIndex];
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
ESM::Position& position = record.get().*mPosition;
|
||||
|
||||
position.rot[mIndex] = data.toFloat();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace CSMWorld
|
|||
{ ColumnId_FactionIndex, "Faction Index" },
|
||||
{ ColumnId_Charges, "Charges" },
|
||||
{ ColumnId_Enchantment, "Enchantment" },
|
||||
{ ColumnId_Value, "Coin Value" },
|
||||
{ ColumnId_CoinValue, "Coin Value" },
|
||||
{ ColumnId_Teleport, "Teleport" },
|
||||
{ ColumnId_TeleportCell, "Teleport Cell" },
|
||||
{ ColumnId_LockLevel, "Lock Level" },
|
||||
|
@ -147,6 +147,18 @@ namespace CSMWorld
|
|||
{ ColumnId_Magical, "Magical" },
|
||||
{ ColumnId_Silver, "Silver" },
|
||||
{ ColumnId_Filter, "Filter" },
|
||||
{ ColumnId_PositionXPos, "Pos X" },
|
||||
{ ColumnId_PositionYPos, "Pos Y" },
|
||||
{ ColumnId_PositionZPos, "Pos Z" },
|
||||
{ ColumnId_PositionXRot, "Rot X" },
|
||||
{ ColumnId_PositionYRot, "Rot Y" },
|
||||
{ ColumnId_PositionZRot, "Rot Z" },
|
||||
{ ColumnId_DoorPositionXPos, "Teleport Pos X" },
|
||||
{ ColumnId_DoorPositionYPos, "Teleport Pos Y" },
|
||||
{ ColumnId_DoorPositionZPos, "Teleport Pos Z" },
|
||||
{ ColumnId_DoorPositionXRot, "Teleport Rot X" },
|
||||
{ ColumnId_DoorPositionYRot, "Teleport Rot Y" },
|
||||
{ ColumnId_DoorPositionZRot, "Teleport Rot Z" },
|
||||
|
||||
{ ColumnId_UseValue1, "Use value 1" },
|
||||
{ ColumnId_UseValue2, "Use value 2" },
|
||||
|
|
|
@ -45,101 +45,113 @@ namespace CSMWorld
|
|||
ColumnId_Charges = 32,
|
||||
ColumnId_Enchantment = 33,
|
||||
ColumnId_CoinValue = 34,
|
||||
ColumnId_Teleport = 25,
|
||||
ColumnId_TeleportCell = 26,
|
||||
ColumnId_LockLevel = 27,
|
||||
ColumnId_Key = 28,
|
||||
ColumnId_Trap = 29,
|
||||
ColumnId_BeastRace = 30,
|
||||
ColumnId_AutoCalc = 31,
|
||||
ColumnId_StarterSpell = 32,
|
||||
ColumnId_AlwaysSucceeds = 33,
|
||||
ColumnId_SleepForbidden = 34,
|
||||
ColumnId_InteriorWater = 35,
|
||||
ColumnId_InteriorSky = 36,
|
||||
ColumnId_Model = 37,
|
||||
ColumnId_Script = 38,
|
||||
ColumnId_Icon = 39,
|
||||
ColumnId_Weight = 40,
|
||||
ColumnId_EnchantmentPoints = 31,
|
||||
ColumnId_Quality = 32,
|
||||
ColumnId_Ai = 33,
|
||||
ColumnId_AiHello = 34,
|
||||
ColumnId_AiFlee = 35,
|
||||
ColumnId_AiFight = 36,
|
||||
ColumnId_AiAlarm = 37,
|
||||
ColumnId_BuysWeapons = 38,
|
||||
ColumnId_BuysArmor = 39,
|
||||
ColumnId_BuysClothing = 40,
|
||||
ColumnId_BuysBooks = 41,
|
||||
ColumnId_BuysIngredients = 42,
|
||||
ColumnId_BuysLockpicks = 43,
|
||||
ColumnId_BuysProbes = 44,
|
||||
ColumnId_BuysLights = 45,
|
||||
ColumnId_BuysApparati = 46,
|
||||
ColumnId_BuysRepairItems = 47,
|
||||
ColumnId_BuysMiscItems = 48,
|
||||
ColumnId_BuysPotions = 49,
|
||||
ColumnId_BuysMagicItems = 50,
|
||||
ColumnId_SellsSpells = 51,
|
||||
ColumnId_Trainer = 52,
|
||||
ColumnId_Spellmaking = 53,
|
||||
ColumnId_EnchantingService = 54,
|
||||
ColumnId_RepairService = 55,
|
||||
ColumnId_ApparatusType = 56,
|
||||
ColumnId_ArmorType = 57,
|
||||
ColumnId_Health = 58,
|
||||
ColumnId_ArmorValue = 59,
|
||||
ColumnId_Scroll = 60,
|
||||
ColumnId_ClothingType = 61,
|
||||
ColumnId_WeightCapacity = 62,
|
||||
ColumnId_OrganicContainer = 63,
|
||||
ColumnId_Respawn = 64,
|
||||
ColumnId_CreatureType = 65,
|
||||
ColumnId_SoulPoints = 66,
|
||||
ColumnId_OriginalCreature = 67,
|
||||
ColumnId_Biped = 68,
|
||||
ColumnId_HasWeapon = 69,
|
||||
ColumnId_NoMovement = 70,
|
||||
ColumnId_Swims = 71,
|
||||
ColumnId_Flies = 72,
|
||||
ColumnId_Walks = 73,
|
||||
ColumnId_Essential = 74,
|
||||
ColumnId_SkeletonBlood = 75,
|
||||
ColumnId_MetalBlood = 76,
|
||||
ColumnId_OpenSound = 77,
|
||||
ColumnId_CloseSound = 78,
|
||||
ColumnId_Duration = 79,
|
||||
ColumnId_Radius = 80,
|
||||
ColumnId_Colour = 81,
|
||||
ColumnId_Sound = 82,
|
||||
ColumnId_Dynamic = 83,
|
||||
ColumnId_Portable = 84,
|
||||
ColumnId_NegativeLight = 85,
|
||||
ColumnId_Flickering = 86,
|
||||
ColumnId_SlowFlickering = 87,
|
||||
ColumnId_Pulsing = 88,
|
||||
ColumnId_SlowPulsing = 89,
|
||||
ColumnId_Fire = 90,
|
||||
ColumnId_OffByDefault = 91,
|
||||
ColumnId_IsKey = 92,
|
||||
ColumnId_Race = 93,
|
||||
ColumnId_Class = 94,
|
||||
Columnid_Hair = 95,
|
||||
ColumnId_Head = 96,
|
||||
ColumnId_Female = 97,
|
||||
ColumnId_WeaponType = 98,
|
||||
ColumnId_WeaponSpeed = 99,
|
||||
ColumnId_WeaponReach = 100,
|
||||
ColumnId_MinChop = 101,
|
||||
ColumnId_MaxChip = 102,
|
||||
Columnid_MinSlash = 103,
|
||||
ColumnId_MaxSlash = 104,
|
||||
ColumnId_MinThrust = 105,
|
||||
ColumnId_MaxThrust = 106,
|
||||
ColumnId_Magical = 107,
|
||||
ColumnId_Silver = 108,
|
||||
ColumnId_Filter = 109,
|
||||
ColumnId_Teleport = 35,
|
||||
ColumnId_TeleportCell = 36,
|
||||
ColumnId_LockLevel = 37,
|
||||
ColumnId_Key = 38,
|
||||
ColumnId_Trap = 39,
|
||||
ColumnId_BeastRace = 40,
|
||||
ColumnId_AutoCalc = 41,
|
||||
ColumnId_StarterSpell = 42,
|
||||
ColumnId_AlwaysSucceeds = 43,
|
||||
ColumnId_SleepForbidden = 44,
|
||||
ColumnId_InteriorWater = 45,
|
||||
ColumnId_InteriorSky = 46,
|
||||
ColumnId_Model = 47,
|
||||
ColumnId_Script = 48,
|
||||
ColumnId_Icon = 49,
|
||||
ColumnId_Weight = 50,
|
||||
ColumnId_EnchantmentPoints = 51,
|
||||
ColumnId_Quality = 52,
|
||||
ColumnId_Ai = 53,
|
||||
ColumnId_AiHello = 54,
|
||||
ColumnId_AiFlee = 55,
|
||||
ColumnId_AiFight = 56,
|
||||
ColumnId_AiAlarm = 57,
|
||||
ColumnId_BuysWeapons = 58,
|
||||
ColumnId_BuysArmor = 59,
|
||||
ColumnId_BuysClothing = 60,
|
||||
ColumnId_BuysBooks = 61,
|
||||
ColumnId_BuysIngredients = 62,
|
||||
ColumnId_BuysLockpicks = 63,
|
||||
ColumnId_BuysProbes = 64,
|
||||
ColumnId_BuysLights = 65,
|
||||
ColumnId_BuysApparati = 66,
|
||||
ColumnId_BuysRepairItems = 67,
|
||||
ColumnId_BuysMiscItems = 68,
|
||||
ColumnId_BuysPotions = 69,
|
||||
ColumnId_BuysMagicItems = 70,
|
||||
ColumnId_SellsSpells = 71,
|
||||
ColumnId_Trainer = 72,
|
||||
ColumnId_Spellmaking = 73,
|
||||
ColumnId_EnchantingService = 74,
|
||||
ColumnId_RepairService = 75,
|
||||
ColumnId_ApparatusType = 76,
|
||||
ColumnId_ArmorType = 77,
|
||||
ColumnId_Health = 78,
|
||||
ColumnId_ArmorValue = 79,
|
||||
ColumnId_Scroll = 80,
|
||||
ColumnId_ClothingType = 81,
|
||||
ColumnId_WeightCapacity = 82,
|
||||
ColumnId_OrganicContainer = 83,
|
||||
ColumnId_Respawn = 84,
|
||||
ColumnId_CreatureType = 85,
|
||||
ColumnId_SoulPoints = 86,
|
||||
ColumnId_OriginalCreature = 87,
|
||||
ColumnId_Biped = 88,
|
||||
ColumnId_HasWeapon = 89,
|
||||
ColumnId_NoMovement = 90,
|
||||
ColumnId_Swims = 91,
|
||||
ColumnId_Flies = 92,
|
||||
ColumnId_Walks = 93,
|
||||
ColumnId_Essential = 94,
|
||||
ColumnId_SkeletonBlood = 95,
|
||||
ColumnId_MetalBlood = 96,
|
||||
ColumnId_OpenSound = 97,
|
||||
ColumnId_CloseSound = 98,
|
||||
ColumnId_Duration = 99,
|
||||
ColumnId_Radius = 100,
|
||||
ColumnId_Colour = 101,
|
||||
ColumnId_Sound = 102,
|
||||
ColumnId_Dynamic = 103,
|
||||
ColumnId_Portable = 104,
|
||||
ColumnId_NegativeLight = 105,
|
||||
ColumnId_Flickering = 106,
|
||||
ColumnId_SlowFlickering = 107,
|
||||
ColumnId_Pulsing = 108,
|
||||
ColumnId_SlowPulsing = 109,
|
||||
ColumnId_Fire = 110,
|
||||
ColumnId_OffByDefault = 111,
|
||||
ColumnId_IsKey = 112,
|
||||
ColumnId_Race = 113,
|
||||
ColumnId_Class = 114,
|
||||
Columnid_Hair = 115,
|
||||
ColumnId_Head = 116,
|
||||
ColumnId_Female = 117,
|
||||
ColumnId_WeaponType = 118,
|
||||
ColumnId_WeaponSpeed = 119,
|
||||
ColumnId_WeaponReach = 120,
|
||||
ColumnId_MinChop = 121,
|
||||
ColumnId_MaxChip = 122,
|
||||
Columnid_MinSlash = 123,
|
||||
ColumnId_MaxSlash = 124,
|
||||
ColumnId_MinThrust = 125,
|
||||
ColumnId_MaxThrust = 126,
|
||||
ColumnId_Magical = 127,
|
||||
ColumnId_Silver = 128,
|
||||
ColumnId_Filter = 129,
|
||||
ColumnId_PositionXPos = 130,
|
||||
ColumnId_PositionYPos = 131,
|
||||
ColumnId_PositionZPos = 132,
|
||||
ColumnId_PositionXRot = 133,
|
||||
ColumnId_PositionYRot = 134,
|
||||
ColumnId_PositionZRot = 135,
|
||||
ColumnId_DoorPositionXPos = 136,
|
||||
ColumnId_DoorPositionYPos = 137,
|
||||
ColumnId_DoorPositionZPos = 138,
|
||||
ColumnId_DoorPositionXRot = 139,
|
||||
ColumnId_DoorPositionYRot = 140,
|
||||
ColumnId_DoorPositionZRot = 141,
|
||||
|
||||
// Allocated to a separate value range, so we don't get a collision should we ever need
|
||||
// to extend the number of use values.
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#include "data.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/loadglob.hpp>
|
||||
#include <components/esm/cellref.hpp>
|
||||
|
||||
#include "idtable.hpp"
|
||||
#include "columnimp.hpp"
|
||||
|
@ -15,13 +17,31 @@
|
|||
#include "columns.hpp"
|
||||
|
||||
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2)
|
||||
UniversalId::Type type2, bool update)
|
||||
{
|
||||
mModels.push_back (model);
|
||||
mModelIndex.insert (std::make_pair (type1, model));
|
||||
|
||||
if (type2!=UniversalId::Type_None)
|
||||
mModelIndex.insert (std::make_pair (type2, model));
|
||||
|
||||
if (update)
|
||||
{
|
||||
connect (model, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT (dataChanged (const QModelIndex&, const QModelIndex&)));
|
||||
connect (model, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
|
||||
connect (model, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
|
||||
}
|
||||
}
|
||||
|
||||
void CSMWorld::Data::appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
||||
bool listDeleted)
|
||||
{
|
||||
std::vector<std::string> ids2 = collection.getIds (listDeleted);
|
||||
|
||||
ids.insert (ids.end(), ids2.begin(), ids2.end());
|
||||
}
|
||||
|
||||
CSMWorld::Data::Data() : mRefs (mCells)
|
||||
|
@ -134,6 +154,12 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||
mRefs.addColumn (new RecordStateColumn<CellRef>);
|
||||
mRefs.addColumn (new CellColumn<CellRef>);
|
||||
mRefs.addColumn (new IdColumn<CellRef>);
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mPos, 0, false));
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mPos, 1, false));
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mPos, 2, false));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mPos, 0, false));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mPos, 1, false));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mPos, 2, false));
|
||||
mRefs.addColumn (new ScaleColumn<CellRef>);
|
||||
mRefs.addColumn (new OwnerColumn<CellRef>);
|
||||
mRefs.addColumn (new SoulColumn<CellRef>);
|
||||
|
@ -144,6 +170,12 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||
mRefs.addColumn (new GoldValueColumn<CellRef>);
|
||||
mRefs.addColumn (new TeleportColumn<CellRef>);
|
||||
mRefs.addColumn (new TeleportCellColumn<CellRef>);
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mDoorDest, 0, true));
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mDoorDest, 1, true));
|
||||
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mDoorDest, 2, true));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mDoorDest, 0, true));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mDoorDest, 1, true));
|
||||
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mDoorDest, 2, true));
|
||||
mRefs.addColumn (new LockLevelColumn<CellRef>);
|
||||
mRefs.addColumn (new KeyColumn<CellRef>);
|
||||
mRefs.addColumn (new TrapColumn<CellRef>);
|
||||
|
@ -155,7 +187,7 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill, false);
|
||||
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
|
||||
addModel (new IdTable (&mFactions), UniversalId::Type_Factions, UniversalId::Type_Faction);
|
||||
addModel (new IdTable (&mRaces), UniversalId::Type_Races, UniversalId::Type_Race);
|
||||
|
@ -167,8 +199,8 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||
addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
||||
addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables,
|
||||
UniversalId::Type_Referenceable);
|
||||
addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference);
|
||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter);
|
||||
addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false);
|
||||
}
|
||||
|
||||
CSMWorld::Data::~Data()
|
||||
|
@ -341,7 +373,7 @@ QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
|||
{
|
||||
RegionMap *table = 0;
|
||||
addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap,
|
||||
UniversalId::Type_None);
|
||||
UniversalId::Type_None, false);
|
||||
return table;
|
||||
}
|
||||
throw std::logic_error ("No table model available for " + id.toString());
|
||||
|
@ -440,3 +472,36 @@ bool CSMWorld::Data::hasId (const std::string& id) const
|
|||
getCells().searchId (id)!=-1 ||
|
||||
getReferenceables().searchId (id)!=-1;
|
||||
}
|
||||
|
||||
std::vector<std::string> CSMWorld::Data::getIds (bool listDeleted) const
|
||||
{
|
||||
std::vector<std::string> ids;
|
||||
|
||||
appendIds (ids, mGlobals, listDeleted);
|
||||
appendIds (ids, mGmsts, listDeleted);
|
||||
appendIds (ids, mClasses, listDeleted);
|
||||
appendIds (ids, mFactions, listDeleted);
|
||||
appendIds (ids, mRaces, listDeleted);
|
||||
appendIds (ids, mSounds, listDeleted);
|
||||
appendIds (ids, mScripts, listDeleted);
|
||||
appendIds (ids, mRegions, listDeleted);
|
||||
appendIds (ids, mBirthsigns, listDeleted);
|
||||
appendIds (ids, mSpells, listDeleted);
|
||||
appendIds (ids, mCells, listDeleted);
|
||||
appendIds (ids, mReferenceables, listDeleted);
|
||||
|
||||
std::sort (ids.begin(), ids.end());
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
||||
{
|
||||
if (topLeft.column()<=0)
|
||||
emit idListChanged();
|
||||
}
|
||||
|
||||
void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end)
|
||||
{
|
||||
emit idListChanged();
|
||||
}
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <QObject>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include <components/esm/loadglob.hpp>
|
||||
#include <components/esm/loadgmst.hpp>
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
@ -30,8 +33,10 @@ class QAbstractItemModel;
|
|||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data
|
||||
class Data : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
IdCollection<ESM::Global> mGlobals;
|
||||
IdCollection<ESM::GameSetting> mGmsts;
|
||||
IdCollection<ESM::Skill> mSkills;
|
||||
|
@ -55,13 +60,17 @@ namespace CSMWorld
|
|||
Data& operator= (const Data&);
|
||||
|
||||
void addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2 = UniversalId::Type_None);
|
||||
UniversalId::Type type2 = UniversalId::Type_None, bool update = true);
|
||||
|
||||
static void appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
||||
bool listDeleted);
|
||||
///< Append all IDs from collection to \a ids.
|
||||
|
||||
public:
|
||||
|
||||
Data();
|
||||
|
||||
~Data();
|
||||
virtual ~Data();
|
||||
|
||||
const IdCollection<ESM::Global>& getGlobals() const;
|
||||
|
||||
|
@ -136,6 +145,21 @@ namespace CSMWorld
|
|||
///< Merging content of a file into base or modified.
|
||||
|
||||
bool hasId (const std::string& id) const;
|
||||
|
||||
std::vector<std::string> getIds (bool listDeleted = true) const;
|
||||
///< Return a sorted collection of all IDs that are not internal to the editor.
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
|
||||
signals:
|
||||
|
||||
void idListChanged();
|
||||
|
||||
private slots:
|
||||
|
||||
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||
|
||||
void rowsChanged (const QModelIndex& parent, int start, int end);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -534,3 +534,8 @@ int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const
|
|||
{
|
||||
return mData.getAppendIndex (type);
|
||||
}
|
||||
|
||||
std::vector<std::string> CSMWorld::RefIdCollection::getIds (bool listDeleted) const
|
||||
{
|
||||
return mData.getIds (listDeleted);
|
||||
}
|
||||
|
|
|
@ -89,6 +89,11 @@ namespace CSMWorld
|
|||
|
||||
virtual int getAppendIndex (UniversalId::Type type) const;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual std::vector<std::string> getIds (bool listDeleted) const;
|
||||
///< Return a sorted collection of all IDs
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -196,3 +196,25 @@ int CSMWorld::RefIdData::getSize() const
|
|||
{
|
||||
return mIndex.size();
|
||||
}
|
||||
|
||||
std::vector<std::string> CSMWorld::RefIdData::getIds (bool listDeleted) const
|
||||
{
|
||||
std::vector<std::string> ids;
|
||||
|
||||
for (std::map<std::string, LocalIndex>::const_iterator iter (mIndex.begin()); iter!=mIndex.end();
|
||||
++iter)
|
||||
{
|
||||
if (listDeleted || !getRecord (iter->second).isDeleted())
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator container =
|
||||
mRecordContainers.find (iter->second.second);
|
||||
|
||||
if (container==mRecordContainers.end())
|
||||
throw std::logic_error ("Invalid referenceable ID type");
|
||||
|
||||
ids.push_back (container->second->getId (iter->second.first));
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
|
|
@ -182,6 +182,11 @@ namespace CSMWorld
|
|||
void load (const LocalIndex& index, ESM::ESMReader& reader, bool base);
|
||||
|
||||
int getSize() const;
|
||||
|
||||
std::vector<std::string> getIds (bool listDeleted = true) const;
|
||||
///< Return a sorted collection of all IDs
|
||||
///
|
||||
/// \param listDeleted include deleted record in the list
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
|
||||
#include "scriptcontext.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "data.hpp"
|
||||
|
||||
CSMWorld::ScriptContext::ScriptContext (const Data& data) : mData (data), mIdsUpdated (false) {}
|
||||
|
||||
bool CSMWorld::ScriptContext::canDeclareLocals() const
|
||||
{
|
||||
return false;
|
||||
|
@ -18,5 +26,19 @@ char CSMWorld::ScriptContext::getMemberType (const std::string& name, const std:
|
|||
|
||||
bool CSMWorld::ScriptContext::isId (const std::string& name) const
|
||||
{
|
||||
return false;
|
||||
if (!mIdsUpdated)
|
||||
{
|
||||
mIds = mData.getIds();
|
||||
|
||||
std::for_each (mIds.begin(), mIds.end(), &Misc::StringUtils::lowerCase);
|
||||
|
||||
mIdsUpdated = true;
|
||||
}
|
||||
|
||||
return std::binary_search (mIds.begin(), mIds.end(), Misc::StringUtils::lowerCase (name));
|
||||
}
|
||||
|
||||
void CSMWorld::ScriptContext::invalidateIds()
|
||||
{
|
||||
mIdsUpdated = false;
|
||||
}
|
|
@ -1,14 +1,25 @@
|
|||
#ifndef CSM_WORLD_SCRIPTCONTEXT_H
|
||||
#define CSM_WORLD_SCRIPTCONTEXT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <components/compiler/context.hpp>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data;
|
||||
|
||||
class ScriptContext : public Compiler::Context
|
||||
{
|
||||
const Data& mData;
|
||||
mutable std::vector<std::string> mIds;
|
||||
mutable bool mIdsUpdated;
|
||||
|
||||
public:
|
||||
|
||||
ScriptContext (const Data& data);
|
||||
|
||||
virtual bool canDeclareLocals() const;
|
||||
///< Is the compiler allowed to declare local variables?
|
||||
|
||||
|
@ -20,6 +31,8 @@ namespace CSMWorld
|
|||
|
||||
virtual bool isId (const std::string& name) const;
|
||||
///< Does \a name match an ID, that can be referenced?
|
||||
|
||||
void invalidateIds();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -43,18 +43,18 @@ namespace
|
|||
|
||||
static const TypeData sIdArg[] =
|
||||
{
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", ":./globvar.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", ":./GMST.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", ":./skill.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class", ":./class.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction", ":./faction.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race", ":./race.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound", ":./sound.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script", ":./script.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", ":./land.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", ":./birthsign.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 },
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" },
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Potion, "Potion", ":./potion.png" },
|
||||
|
@ -80,13 +80,14 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Static, "Static", ":./static.png" },
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", 0 },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
||||
static const TypeData sIndexArg[] =
|
||||
{
|
||||
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
|
|
@ -86,10 +86,11 @@ namespace CSMWorld
|
|||
Type_Reference,
|
||||
Type_RegionMap,
|
||||
Type_Filter,
|
||||
Type_Filters
|
||||
Type_Filters,
|
||||
Type_Scene
|
||||
};
|
||||
|
||||
enum { NumberOfTypes = Type_Filters+1 };
|
||||
enum { NumberOfTypes = Type_Scene+1 };
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#include "ocspropertywidget.hpp"
|
||||
|
||||
OcsPropertyWidget::OcsPropertyWidget(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef OCSPROPERTYWIDGET_HPP
|
||||
#define OCSPROPERTYWIDGET_HPP
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class OcsPropertyWidget : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OcsPropertyWidget(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // OCSPROPERTYWIDGET_HPP
|
91
apps/opencs/view/doc/adjusterwidget.cpp
Normal file
91
apps/opencs/view/doc/adjusterwidget.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
|
||||
#include "adjusterwidget.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QStyle>
|
||||
|
||||
CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent)
|
||||
: QWidget (parent), mValid (false)
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout (this);
|
||||
|
||||
mIcon = new QLabel (this);
|
||||
|
||||
layout->addWidget (mIcon, 0);
|
||||
|
||||
mMessage = new QLabel (this);
|
||||
mMessage->setWordWrap (true);
|
||||
mMessage->setSizePolicy (QSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum));
|
||||
|
||||
layout->addWidget (mMessage, 1);
|
||||
|
||||
setName ("", false);
|
||||
|
||||
setLayout (layout);
|
||||
}
|
||||
|
||||
void CSVDoc::AdjusterWidget::setLocalData (const boost::filesystem::path& localData)
|
||||
{
|
||||
mLocalData = localData;
|
||||
}
|
||||
|
||||
boost::filesystem::path CSVDoc::AdjusterWidget::getPath() const
|
||||
{
|
||||
if (!mValid)
|
||||
throw std::logic_error ("invalid content file path");
|
||||
|
||||
return mResultPath;
|
||||
}
|
||||
|
||||
void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
|
||||
{
|
||||
QString message;
|
||||
|
||||
if (name.isEmpty())
|
||||
{
|
||||
mValid = false;
|
||||
message = "No name.";
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::filesystem::path path (name.toUtf8().data());
|
||||
|
||||
path.replace_extension (addon ? ".omwaddon" : ".omwgame");
|
||||
|
||||
if (path.parent_path().string()==mLocalData.string())
|
||||
{
|
||||
// path already points to the local data directory
|
||||
message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str());
|
||||
mResultPath = path;
|
||||
mValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// path points somewhere else or is a leaf name.
|
||||
path = mLocalData / path.filename();
|
||||
|
||||
message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str());
|
||||
mResultPath = path;
|
||||
mValid = true;
|
||||
|
||||
if (boost::filesystem::exists (path))
|
||||
{
|
||||
/// \todo add an user setting to make this an error.
|
||||
message += "<p>But a file with the same name already exists. If you continue, it will be overwritten.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mMessage->setText (message);
|
||||
mIcon->setPixmap (style()->standardIcon (
|
||||
mValid ? QStyle::SP_MessageBoxInformation : QStyle::SP_MessageBoxWarning).
|
||||
pixmap (QSize (16, 16)));
|
||||
|
||||
emit stateChanged (mValid);
|
||||
}
|
41
apps/opencs/view/doc/adjusterwidget.hpp
Normal file
41
apps/opencs/view/doc/adjusterwidget.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef CSV_DOC_ADJUSTERWIDGET_H
|
||||
#define CSV_DOC_ADJUSTERWIDGET_H
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
|
||||
namespace CSVDoc
|
||||
{
|
||||
class AdjusterWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
boost::filesystem::path mLocalData;
|
||||
QLabel *mMessage;
|
||||
QLabel *mIcon;
|
||||
bool mValid;
|
||||
boost::filesystem::path mResultPath;
|
||||
|
||||
public:
|
||||
|
||||
AdjusterWidget (QWidget *parent = 0);
|
||||
|
||||
void setLocalData (const boost::filesystem::path& localData);
|
||||
|
||||
boost::filesystem::path getPath() const;
|
||||
///< This function must not be called if there is no valid path.
|
||||
|
||||
public slots:
|
||||
|
||||
void setName (const QString& name, bool addon);
|
||||
|
||||
signals:
|
||||
|
||||
void stateChanged (bool valid);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
53
apps/opencs/view/doc/filewidget.cpp
Normal file
53
apps/opencs/view/doc/filewidget.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
|
||||
#include "filewidget.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QRegExpValidator>
|
||||
#include <QRegExp>
|
||||
|
||||
QString CSVDoc::FileWidget::getExtension() const
|
||||
{
|
||||
return mAddon ? ".omwaddon" : ".omwgame";
|
||||
}
|
||||
|
||||
CSVDoc::FileWidget::FileWidget (QWidget *parent) : QWidget (parent), mAddon (false)
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout (this);
|
||||
|
||||
mInput = new QLineEdit (this);
|
||||
mInput->setValidator (new QRegExpValidator(QRegExp("^[a-zA-Z0-9\\s]*$")));
|
||||
|
||||
layout->addWidget (mInput, 1);
|
||||
|
||||
mType = new QLabel (this);
|
||||
|
||||
layout ->addWidget (mType);
|
||||
|
||||
connect (mInput, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&)));
|
||||
|
||||
setLayout (layout);
|
||||
}
|
||||
|
||||
void CSVDoc::FileWidget::setType (bool addon)
|
||||
{
|
||||
mAddon = addon;
|
||||
|
||||
mType->setText (getExtension());
|
||||
}
|
||||
|
||||
QString CSVDoc::FileWidget::getName() const
|
||||
{
|
||||
QString text = mInput->text();
|
||||
|
||||
if (text.isEmpty())
|
||||
return "";
|
||||
|
||||
return text + getExtension();
|
||||
}
|
||||
|
||||
void CSVDoc::FileWidget::textChanged (const QString& text)
|
||||
{
|
||||
emit nameChanged (getName(), mAddon);
|
||||
}
|
40
apps/opencs/view/doc/filewidget.hpp
Normal file
40
apps/opencs/view/doc/filewidget.hpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef CSV_DOC_FILEWIDGET_H
|
||||
#define CSV_DOC_FILEWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
class QString;
|
||||
class QLineEdit;
|
||||
|
||||
namespace CSVDoc
|
||||
{
|
||||
class FileWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
bool mAddon;
|
||||
QLineEdit *mInput;
|
||||
QLabel *mType;
|
||||
|
||||
QString getExtension() const;
|
||||
|
||||
public:
|
||||
|
||||
FileWidget (QWidget *parent = 0);
|
||||
|
||||
void setType (bool addon);
|
||||
|
||||
QString getName() const;
|
||||
|
||||
private slots:
|
||||
|
||||
void textChanged (const QString& text);
|
||||
|
||||
signals:
|
||||
|
||||
void nameChanged (const QString& file, bool addon);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
68
apps/opencs/view/doc/newgame.cpp
Normal file
68
apps/opencs/view/doc/newgame.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
|
||||
#include "newgame.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "filewidget.hpp"
|
||||
#include "adjusterwidget.hpp"
|
||||
|
||||
CSVDoc::NewGameDialogue::NewGameDialogue()
|
||||
{
|
||||
setWindowTitle ("Create New Game");
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout (this);
|
||||
|
||||
mFileWidget = new FileWidget (this);
|
||||
mFileWidget->setType (false);
|
||||
|
||||
layout->addWidget (mFileWidget, 1);
|
||||
|
||||
mAdjusterWidget = new AdjusterWidget (this);
|
||||
|
||||
layout->addWidget (mAdjusterWidget, 1);
|
||||
|
||||
QDialogButtonBox *buttons = new QDialogButtonBox (this);
|
||||
|
||||
mCreate = new QPushButton ("Create", this);
|
||||
mCreate->setDefault (true);
|
||||
mCreate->setEnabled (false);
|
||||
|
||||
buttons->addButton (mCreate, QDialogButtonBox::AcceptRole);
|
||||
|
||||
QPushButton *cancel = new QPushButton ("Cancel", this);
|
||||
|
||||
buttons->addButton (cancel, QDialogButtonBox::RejectRole);
|
||||
|
||||
layout->addWidget (buttons);
|
||||
|
||||
setLayout (layout);
|
||||
|
||||
connect (mAdjusterWidget, SIGNAL (stateChanged (bool)), this, SLOT (stateChanged (bool)));
|
||||
connect (mCreate, SIGNAL (clicked()), this, SLOT (create()));
|
||||
connect (cancel, SIGNAL (clicked()), this, SLOT (reject()));
|
||||
connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)),
|
||||
mAdjusterWidget, SLOT (setName (const QString&, bool)));
|
||||
|
||||
QRect scr = QApplication::desktop()->screenGeometry();
|
||||
QRect rect = geometry();
|
||||
move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y());
|
||||
}
|
||||
|
||||
void CSVDoc::NewGameDialogue::setLocalData (const boost::filesystem::path& localData)
|
||||
{
|
||||
mAdjusterWidget->setLocalData (localData);
|
||||
}
|
||||
|
||||
void CSVDoc::NewGameDialogue::stateChanged (bool valid)
|
||||
{
|
||||
mCreate->setEnabled (valid);
|
||||
}
|
||||
|
||||
void CSVDoc::NewGameDialogue::create()
|
||||
{
|
||||
emit createRequest (mAdjusterWidget->getPath());
|
||||
}
|
44
apps/opencs/view/doc/newgame.hpp
Normal file
44
apps/opencs/view/doc/newgame.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef CSV_DOC_NEWGAME_H
|
||||
#define CSV_DOC_NEWGAME_H
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMetaType>
|
||||
|
||||
Q_DECLARE_METATYPE (boost::filesystem::path)
|
||||
|
||||
class QPushButton;
|
||||
|
||||
namespace CSVDoc
|
||||
{
|
||||
class FileWidget;
|
||||
class AdjusterWidget;
|
||||
|
||||
class NewGameDialogue : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QPushButton *mCreate;
|
||||
FileWidget *mFileWidget;
|
||||
AdjusterWidget *mAdjusterWidget;
|
||||
|
||||
public:
|
||||
|
||||
NewGameDialogue();
|
||||
|
||||
void setLocalData (const boost::filesystem::path& localData);
|
||||
|
||||
signals:
|
||||
|
||||
void createRequest (const boost::filesystem::path& file);
|
||||
|
||||
private slots:
|
||||
|
||||
void stateChanged (bool valid);
|
||||
|
||||
void create();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -27,9 +27,13 @@ void CSVDoc::View::setupFileMenu()
|
|||
{
|
||||
QMenu *file = menuBar()->addMenu (tr ("&File"));
|
||||
|
||||
QAction *new_ = new QAction (tr ("New"), this);
|
||||
connect (new_, SIGNAL (triggered()), this, SIGNAL (newDocumentRequest()));
|
||||
file->addAction (new_);
|
||||
QAction *newGame = new QAction (tr ("New Game"), this);
|
||||
connect (newGame, SIGNAL (triggered()), this, SIGNAL (newGameRequest()));
|
||||
file->addAction (newGame);
|
||||
|
||||
QAction *newAddon = new QAction (tr ("New Addon"), this);
|
||||
connect (newAddon, SIGNAL (triggered()), this, SIGNAL (newAddonRequest()));
|
||||
file->addAction (newAddon);
|
||||
|
||||
QAction *open = new QAction (tr ("&Open"), this);
|
||||
connect (open, SIGNAL (triggered()), this, SIGNAL (loadDocumentRequest()));
|
||||
|
@ -111,6 +115,10 @@ void CSVDoc::View::setupWorldMenu()
|
|||
|
||||
world->addSeparator(); // items that don't represent single record lists follow here
|
||||
|
||||
QAction *scene = new QAction (tr ("Scene"), this);
|
||||
connect (scene, SIGNAL (triggered()), this, SLOT (addSceneSubView()));
|
||||
world->addAction (scene);
|
||||
|
||||
QAction *regionMap = new QAction (tr ("Region Map"), this);
|
||||
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView()));
|
||||
world->addAction (regionMap);
|
||||
|
@ -180,7 +188,7 @@ void CSVDoc::View::updateTitle()
|
|||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << mDocument->getName();
|
||||
stream << mDocument->getSavePath().filename().string();
|
||||
|
||||
if (mDocument->getState() & CSMDoc::State_Modified)
|
||||
stream << " *";
|
||||
|
@ -399,6 +407,11 @@ void CSVDoc::View::addFiltersSubView()
|
|||
addSubView (CSMWorld::UniversalId::Type_Filters);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addSceneSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Scene);
|
||||
}
|
||||
|
||||
void CSVDoc::View::abortOperation (int type)
|
||||
{
|
||||
mDocument->abortOperation (type);
|
||||
|
|
|
@ -106,7 +106,9 @@ namespace CSVDoc
|
|||
|
||||
signals:
|
||||
|
||||
void newDocumentRequest();
|
||||
void newGameRequest();
|
||||
|
||||
void newAddonRequest();
|
||||
|
||||
void loadDocumentRequest();
|
||||
|
||||
|
@ -162,6 +164,8 @@ namespace CSVDoc
|
|||
|
||||
void addFiltersSubView();
|
||||
|
||||
void addSceneSubView();
|
||||
|
||||
void toggleShowStatusBar (bool show);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "../world/enumdelegate.hpp"
|
||||
#include "../world/vartypedelegate.hpp"
|
||||
#include "../world/recordstatusdelegate.hpp"
|
||||
#include "../world/refidtypedelegate.hpp"
|
||||
#include "../world/idtypedelegate.hpp"
|
||||
#include "../settings/usersettingsdialog.hpp"
|
||||
|
||||
#include "view.hpp"
|
||||
|
@ -56,7 +56,7 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
|||
new CSVWorld::RecordStatusDelegateFactory());
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType,
|
||||
new CSVWorld::RefIdTypeDelegateFactory());
|
||||
new CSVWorld::IdTypeDelegateFactory());
|
||||
|
||||
struct Mapping
|
||||
{
|
||||
|
@ -107,12 +107,12 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
|
|||
|
||||
View *view = new View (*this, document, countViews (document)+1);
|
||||
|
||||
|
||||
mViews.push_back (view);
|
||||
|
||||
view->show();
|
||||
|
||||
connect (view, SIGNAL (newDocumentRequest ()), this, SIGNAL (newDocumentRequest()));
|
||||
connect (view, SIGNAL (newGameRequest ()), this, SIGNAL (newGameRequest()));
|
||||
connect (view, SIGNAL (newAddonRequest ()), this, SIGNAL (newAddonRequest()));
|
||||
connect (view, SIGNAL (loadDocumentRequest ()), this, SIGNAL (loadDocumentRequest()));
|
||||
connect (view, SIGNAL (editSettingsRequest()), this, SIGNAL (editSettingsRequest()));
|
||||
|
||||
|
|
|
@ -55,7 +55,9 @@ namespace CSVDoc
|
|||
|
||||
signals:
|
||||
|
||||
void newDocumentRequest();
|
||||
void newGameRequest();
|
||||
|
||||
void newAddonRequest();
|
||||
|
||||
void loadDocumentRequest();
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "../../model/tools/reportmodel.hpp"
|
||||
|
||||
#include "../../view/world/idtypedelegate.hpp"
|
||||
|
||||
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||
: CSVDoc::SubView (id), mModel (document.getReport (id))
|
||||
{
|
||||
|
@ -18,6 +20,11 @@ CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc:
|
|||
mTable->setSelectionBehavior (QAbstractItemView::SelectRows);
|
||||
mTable->setSelectionMode (QAbstractItemView::ExtendedSelection);
|
||||
|
||||
mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (
|
||||
document.getUndoStack(), this);
|
||||
|
||||
mTable->setItemDelegateForColumn (0, mIdTypeDelegate);
|
||||
|
||||
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (show (const QModelIndex&)));
|
||||
}
|
||||
|
||||
|
@ -26,6 +33,11 @@ void CSVTools::ReportSubView::setEditLock (bool locked)
|
|||
// ignored. We don't change document state anyway.
|
||||
}
|
||||
|
||||
void CSVTools::ReportSubView::updateEditorSetting (const QString& key, const QString& value)
|
||||
{
|
||||
mIdTypeDelegate->updateEditorSetting (key, value);
|
||||
}
|
||||
|
||||
void CSVTools::ReportSubView::show (const QModelIndex& index)
|
||||
{
|
||||
focusId (mModel->getUniversalId (index.row()));
|
||||
|
|
|
@ -16,6 +16,11 @@ namespace CSMTools
|
|||
class ReportModel;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class CommandDelegate;
|
||||
}
|
||||
|
||||
namespace CSVTools
|
||||
{
|
||||
class Table;
|
||||
|
@ -26,6 +31,7 @@ namespace CSVTools
|
|||
|
||||
CSMTools::ReportModel *mModel;
|
||||
QTableView *mTable;
|
||||
CSVWorld::CommandDelegate *mIdTypeDelegate;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -33,6 +39,8 @@ namespace CSVTools
|
|||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
virtual void updateEditorSetting (const QString&, const QString&);
|
||||
|
||||
private slots:
|
||||
|
||||
void show (const QModelIndex& index);
|
||||
|
|
46
apps/opencs/view/world/idtypedelegate.cpp
Executable file
46
apps/opencs/view/world/idtypedelegate.cpp
Executable file
|
@ -0,0 +1,46 @@
|
|||
#include "idtypedelegate.hpp"
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
CSVWorld::IdTypeDelegate::IdTypeDelegate
|
||||
(const ValueList &values, const IconList &icons, QUndoStack& undoStack, QObject *parent)
|
||||
: DataDisplayDelegate (values, icons, undoStack, parent)
|
||||
{}
|
||||
|
||||
bool CSVWorld::IdTypeDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
/// \todo make the setting key a member variable, that is initialised from a constructor argument
|
||||
if (settingName == "Referenceable ID Type Display")
|
||||
{
|
||||
if (settingValue == "Icon and Text")
|
||||
mDisplayMode = Mode_IconAndText;
|
||||
|
||||
else if (settingValue == "Icon Only")
|
||||
mDisplayMode = Mode_IconOnly;
|
||||
|
||||
else if (settingValue == "Text Only")
|
||||
mDisplayMode = Mode_TextOnly;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CSVWorld::IdTypeDelegateFactory::IdTypeDelegateFactory()
|
||||
{
|
||||
for (int i=0; i<CSMWorld::UniversalId::NumberOfTypes; ++i)
|
||||
{
|
||||
CSMWorld::UniversalId id (static_cast<CSMWorld::UniversalId::Type> (i));
|
||||
|
||||
DataDisplayDelegateFactory::add (id.getType(), QString::fromUtf8 (id.getTypeName().c_str()),
|
||||
QString::fromUtf8 (id.getIcon().c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
CSVWorld::CommandDelegate *CSVWorld::IdTypeDelegateFactory::makeDelegate (QUndoStack& undoStack,
|
||||
QObject *parent) const
|
||||
{
|
||||
return new IdTypeDelegate (mValues, mIcons, undoStack, parent);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef REFIDTYPEDELEGATE_HPP
|
||||
#define REFIDTYPEDELEGATE_HPP
|
||||
#ifndef IDTYPEDELEGATE_HPP
|
||||
#define IDTYPEDELEGATE_HPP
|
||||
|
||||
#include "enumdelegate.hpp"
|
||||
#include "util.hpp"
|
||||
|
@ -8,29 +8,23 @@
|
|||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class RefIdTypeDelegate : public DataDisplayDelegate
|
||||
class IdTypeDelegate : public DataDisplayDelegate
|
||||
{
|
||||
public:
|
||||
RefIdTypeDelegate (const ValueList &mValues, const IconList &icons, QUndoStack& undoStack, QObject *parent);
|
||||
IdTypeDelegate (const ValueList &mValues, const IconList &icons, QUndoStack& undoStack, QObject *parent);
|
||||
|
||||
virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
};
|
||||
|
||||
class RefIdTypeDelegateFactory : public DataDisplayDelegateFactory
|
||||
class IdTypeDelegateFactory : public DataDisplayDelegateFactory
|
||||
{
|
||||
|
||||
typedef std::vector < std::pair <CSMWorld::UniversalId::Type, QString> > UidTypeList;
|
||||
|
||||
public:
|
||||
RefIdTypeDelegateFactory();
|
||||
|
||||
IdTypeDelegateFactory();
|
||||
|
||||
virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const;
|
||||
///< The ownership of the returned CommandDelegate is transferred to the caller.
|
||||
|
||||
private:
|
||||
UidTypeList buildUidTypeList () const;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#include "refidtypedelegate.hpp"
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
CSVWorld::RefIdTypeDelegate::RefIdTypeDelegate
|
||||
(const ValueList &values, const IconList &icons, QUndoStack& undoStack, QObject *parent)
|
||||
: DataDisplayDelegate (values, icons, undoStack, parent)
|
||||
{}
|
||||
|
||||
bool CSVWorld::RefIdTypeDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
if (settingName == "Referenceable ID Type Display")
|
||||
{
|
||||
if (settingValue == "Icon and Text")
|
||||
mDisplayMode = Mode_IconAndText;
|
||||
|
||||
else if (settingValue == "Icon Only")
|
||||
mDisplayMode = Mode_IconOnly;
|
||||
|
||||
else if (settingValue == "Text Only")
|
||||
mDisplayMode = Mode_TextOnly;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CSVWorld::RefIdTypeDelegateFactory::RefIdTypeDelegateFactory()
|
||||
{
|
||||
UidTypeList uIdList = buildUidTypeList();
|
||||
|
||||
for (UidTypeList::const_iterator it = uIdList.begin(); it != uIdList.end(); it++)
|
||||
{
|
||||
int i = it->first;
|
||||
DataDisplayDelegateFactory::add (i, QString::fromStdString(CSMWorld::UniversalId(it->first, "").getTypeName()), it->second);
|
||||
}
|
||||
}
|
||||
|
||||
CSVWorld::CommandDelegate *CSVWorld::RefIdTypeDelegateFactory::makeDelegate (QUndoStack& undoStack,
|
||||
QObject *parent) const
|
||||
{
|
||||
return new RefIdTypeDelegate (mValues, mIcons, undoStack, parent);
|
||||
}
|
||||
|
||||
CSVWorld::RefIdTypeDelegateFactory::UidTypeList CSVWorld::RefIdTypeDelegateFactory::buildUidTypeList() const
|
||||
{
|
||||
UidTypeList list;
|
||||
|
||||
std::vector<CSMWorld::UniversalId::Type> types = CSMWorld::UniversalId::listReferenceableTypes();
|
||||
|
||||
for (std::vector<CSMWorld::UniversalId::Type>::const_iterator iter (types.begin());
|
||||
iter!=types.end(); ++iter)
|
||||
{
|
||||
CSMWorld::UniversalId id (*iter, "");
|
||||
|
||||
list.push_back (std::make_pair (id.getType(), id.getIcon().c_str()));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
82
apps/opencs/view/world/scenesubview.cpp
Normal file
82
apps/opencs/view/world/scenesubview.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
|
||||
#include "scenesubview.hpp"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../filter/filterbox.hpp"
|
||||
|
||||
#include "tablebottombox.hpp"
|
||||
#include "creator.hpp"
|
||||
#include "scenetoolbar.hpp"
|
||||
#include "scenetoolmode.hpp"
|
||||
|
||||
CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||
: SubView (id)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
|
||||
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
layout->addWidget (mBottom =
|
||||
new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id,
|
||||
this), 0);
|
||||
|
||||
QHBoxLayout *layout2 = new QHBoxLayout;
|
||||
|
||||
layout2->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||
// test
|
||||
SceneToolMode *tool = new SceneToolMode (toolbar);
|
||||
tool->addButton (":door.png", "a");
|
||||
tool->addButton (":GMST.png", "b");
|
||||
tool->addButton (":Info.png", "c");
|
||||
toolbar->addTool (tool);
|
||||
toolbar->addTool (new SceneToolMode (toolbar));
|
||||
toolbar->addTool (new SceneToolMode (toolbar));
|
||||
toolbar->addTool (new SceneToolMode (toolbar));
|
||||
layout2->addWidget (toolbar, 0);
|
||||
|
||||
/// \todo replace with rendering widget
|
||||
QPalette palette2 (palette());
|
||||
palette2.setColor (QPalette::Background, Qt::white);
|
||||
QLabel *placeholder = new QLabel ("Here goes the 3D scene", this);
|
||||
placeholder->setAutoFillBackground (true);
|
||||
placeholder->setPalette (palette2);
|
||||
placeholder->setAlignment (Qt::AlignHCenter);
|
||||
|
||||
layout2->addWidget (placeholder, 1);
|
||||
|
||||
layout->insertLayout (0, layout2, 1);
|
||||
|
||||
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
|
||||
|
||||
layout->insertWidget (0, filterBox);
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
|
||||
widget->setLayout (layout);
|
||||
|
||||
setWidget (widget);
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::setEditLock (bool locked)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::updateEditorSetting(const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::setStatusBar (bool show)
|
||||
{
|
||||
mBottom->setStatusBar (show);
|
||||
}
|
37
apps/opencs/view/world/scenesubview.hpp
Normal file
37
apps/opencs/view/world/scenesubview.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef CSV_WORLD_SCENESUBVIEW_H
|
||||
#define CSV_WORLD_SCENESUBVIEW_H
|
||||
|
||||
#include "../doc/subview.hpp"
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class Table;
|
||||
class TableBottomBox;
|
||||
class CreatorFactoryBase;
|
||||
|
||||
class SceneSubView : public CSVDoc::SubView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
TableBottomBox *mBottom;
|
||||
|
||||
public:
|
||||
|
||||
SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
||||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
virtual void updateEditorSetting (const QString& key, const QString& value);
|
||||
|
||||
virtual void setStatusBar (bool show);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
17
apps/opencs/view/world/scenetool.cpp
Normal file
17
apps/opencs/view/world/scenetool.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
#include "scenetool.hpp"
|
||||
|
||||
#include "scenetoolbar.hpp"
|
||||
|
||||
CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent)
|
||||
{
|
||||
setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
setFixedSize (parent->getButtonSize(), parent->getButtonSize());
|
||||
|
||||
connect (this, SIGNAL (clicked()), this, SLOT (openRequest()));
|
||||
}
|
||||
|
||||
void CSVWorld::SceneTool::openRequest()
|
||||
{
|
||||
showPanel (parentWidget()->mapToGlobal (pos()));
|
||||
}
|
27
apps/opencs/view/world/scenetool.hpp
Normal file
27
apps/opencs/view/world/scenetool.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef CSV_WORLD_SCENETOOL_H
|
||||
#define CSV_WORLD_SCENETOOL_H
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class SceneToolbar;
|
||||
|
||||
///< \brief Tool base class
|
||||
class SceneTool : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
SceneTool (SceneToolbar *parent);
|
||||
|
||||
virtual void showPanel (const QPoint& position) = 0;
|
||||
|
||||
private slots:
|
||||
|
||||
void openRequest();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
29
apps/opencs/view/world/scenetoolbar.cpp
Normal file
29
apps/opencs/view/world/scenetoolbar.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
#include "scenetoolbar.hpp"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "scenetool.hpp"
|
||||
|
||||
CSVWorld::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent)
|
||||
: QWidget (parent), mButtonSize (buttonSize)
|
||||
{
|
||||
setFixedWidth (mButtonSize);
|
||||
|
||||
mLayout = new QVBoxLayout (this);
|
||||
mLayout->setAlignment (Qt::AlignTop);
|
||||
|
||||
mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
setLayout (mLayout);
|
||||
}
|
||||
|
||||
void CSVWorld::SceneToolbar::addTool (SceneTool *tool)
|
||||
{
|
||||
mLayout->addWidget (tool, 0, Qt::AlignTop);
|
||||
}
|
||||
|
||||
int CSVWorld::SceneToolbar::getButtonSize() const
|
||||
{
|
||||
return mButtonSize;
|
||||
}
|
29
apps/opencs/view/world/scenetoolbar.hpp
Normal file
29
apps/opencs/view/world/scenetoolbar.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSV_WORLD_SCENETOOLBAR_H
|
||||
#define CSV_WORLD_SCENETOOLBAR_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QVBoxLayout;
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class SceneTool;
|
||||
|
||||
class SceneToolbar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QVBoxLayout *mLayout;
|
||||
int mButtonSize;
|
||||
|
||||
public:
|
||||
|
||||
SceneToolbar (int buttonSize, QWidget *parent = 0);
|
||||
|
||||
void addTool (SceneTool *tool);
|
||||
|
||||
int getButtonSize() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
56
apps/opencs/view/world/scenetoolmode.cpp
Normal file
56
apps/opencs/view/world/scenetoolmode.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
|
||||
#include "scenetoolmode.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QFrame>
|
||||
#include <QSignalMapper>
|
||||
|
||||
#include "scenetoolbar.hpp"
|
||||
|
||||
CSVWorld::SceneToolMode::SceneToolMode (SceneToolbar *parent)
|
||||
: SceneTool (parent), mButtonSize (parent->getButtonSize())
|
||||
{
|
||||
mPanel = new QFrame (this, Qt::Popup);
|
||||
|
||||
mLayout = new QHBoxLayout (mPanel);
|
||||
|
||||
mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
mPanel->setLayout (mLayout);
|
||||
}
|
||||
|
||||
void CSVWorld::SceneToolMode::showPanel (const QPoint& position)
|
||||
{
|
||||
mPanel->move (position);
|
||||
mPanel->show();
|
||||
}
|
||||
|
||||
void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::string& id)
|
||||
{
|
||||
QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel);
|
||||
button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
button->setFixedSize (mButtonSize, mButtonSize);
|
||||
|
||||
mLayout->addWidget (button);
|
||||
|
||||
mButtons.insert (std::make_pair (button, id));
|
||||
|
||||
connect (button, SIGNAL (clicked()), this, SLOT (selected()));
|
||||
|
||||
if (mButtons.size()==1)
|
||||
setIcon (button->icon());
|
||||
}
|
||||
|
||||
void CSVWorld::SceneToolMode::selected()
|
||||
{
|
||||
std::map<QPushButton *, std::string>::const_iterator iter =
|
||||
mButtons.find (dynamic_cast<QPushButton *> (sender()));
|
||||
|
||||
if (iter!=mButtons.end())
|
||||
{
|
||||
mPanel->hide();
|
||||
|
||||
setIcon (iter->first->icon());
|
||||
emit modeChanged (iter->second);
|
||||
}
|
||||
}
|
42
apps/opencs/view/world/scenetoolmode.hpp
Normal file
42
apps/opencs/view/world/scenetoolmode.hpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef CSV_WORLD_SCENETOOL_MODE_H
|
||||
#define CSV_WORLD_SCENETOOL_MODE_H
|
||||
|
||||
#include "scenetool.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
class QHBoxLayout;
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class SceneToolbar;
|
||||
|
||||
///< \brief Mode selector tool
|
||||
class SceneToolMode : public SceneTool
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QWidget *mPanel;
|
||||
QHBoxLayout *mLayout;
|
||||
std::map<QPushButton *, std::string> mButtons; // widget, id
|
||||
int mButtonSize;
|
||||
|
||||
public:
|
||||
|
||||
SceneToolMode (SceneToolbar *parent);
|
||||
|
||||
virtual void showPanel (const QPoint& position);
|
||||
|
||||
void addButton (const std::string& icon, const std::string& id);
|
||||
|
||||
signals:
|
||||
|
||||
void modeChanged (const std::string& id);
|
||||
|
||||
private slots:
|
||||
|
||||
void selected();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -4,6 +4,7 @@
|
|||
#include <sstream>
|
||||
|
||||
#include <components/compiler/scanner.hpp>
|
||||
#include <components/compiler/extensions0.hpp>
|
||||
|
||||
bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc,
|
||||
Compiler::Scanner& scanner)
|
||||
|
@ -22,7 +23,7 @@ bool CSVWorld::ScriptHighlighter::parseFloat (float value, const Compiler::Token
|
|||
bool CSVWorld::ScriptHighlighter::parseName (const std::string& name, const Compiler::TokenLoc& loc,
|
||||
Compiler::Scanner& scanner)
|
||||
{
|
||||
highlight (loc, Type_Name);
|
||||
highlight (loc, mContext.isId (name) ? Type_Id : Type_Name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -62,10 +63,10 @@ void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type
|
|||
setFormat (index, length, mScheme[type]);
|
||||
}
|
||||
|
||||
CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent)
|
||||
: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext)
|
||||
CSVWorld::ScriptHighlighter::ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent)
|
||||
: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext), mContext (data)
|
||||
{
|
||||
/// \ŧodo replace this with user settings
|
||||
/// \todo replace this with user settings
|
||||
{
|
||||
QTextCharFormat format;
|
||||
format.setForeground (Qt::darkMagenta);
|
||||
|
@ -101,6 +102,16 @@ CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent)
|
|||
format.setForeground (Qt::green);
|
||||
mScheme.insert (std::make_pair (Type_Comment, format));
|
||||
}
|
||||
|
||||
{
|
||||
QTextCharFormat format;
|
||||
format.setForeground (Qt::blue);
|
||||
mScheme.insert (std::make_pair (Type_Id, format));
|
||||
}
|
||||
|
||||
// configure compiler
|
||||
Compiler::registerExtensions (mExtensions);
|
||||
mContext.setExtensions (&mExtensions);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text)
|
||||
|
@ -114,5 +125,9 @@ void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text)
|
|||
scanner.scan (*this);
|
||||
}
|
||||
catch (...) {} // ignore syntax errors
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptHighlighter::invalidateIds()
|
||||
{
|
||||
mContext.invalidateIds();
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <components/compiler/nullerrorhandler.hpp>
|
||||
#include <components/compiler/parser.hpp>
|
||||
#include <components/compiler/extensions.hpp>
|
||||
|
||||
#include "../../model/world/scriptcontext.hpp"
|
||||
|
||||
|
@ -23,12 +24,14 @@ namespace CSVWorld
|
|||
Type_Name,
|
||||
Type_Keyword,
|
||||
Type_Special,
|
||||
Type_Comment
|
||||
Type_Comment,
|
||||
Type_Id
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Compiler::NullErrorHandler mErrorHandler;
|
||||
Compiler::Extensions mExtensions;
|
||||
CSMWorld::ScriptContext mContext;
|
||||
std::map<Type, QTextCharFormat> mScheme;
|
||||
|
||||
|
@ -71,9 +74,11 @@ namespace CSVWorld
|
|||
|
||||
public:
|
||||
|
||||
ScriptHighlighter (QTextDocument *parent);
|
||||
ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent);
|
||||
|
||||
virtual void highlightBlock (const QString& text);
|
||||
|
||||
void invalidateIds();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,13 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc:
|
|||
connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||
|
||||
new ScriptHighlighter (mEditor->document());
|
||||
connect (&document.getData(), SIGNAL (idListChanged()), this, SLOT (idListChanged()));
|
||||
|
||||
mHighlighter = new ScriptHighlighter (document.getData(), mEditor->document());
|
||||
|
||||
connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting()));
|
||||
|
||||
mUpdateTimer.setSingleShot (true);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::setEditLock (bool locked)
|
||||
|
@ -66,8 +72,19 @@ void CSVWorld::ScriptSubView::setEditLock (bool locked)
|
|||
mEditor->setReadOnly (locked);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::idListChanged()
|
||||
{
|
||||
mHighlighter->invalidateIds();
|
||||
|
||||
if (!mUpdateTimer.isActive())
|
||||
mUpdateTimer.start (0);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::textChanged()
|
||||
{
|
||||
if (mChangeLocked)
|
||||
return;
|
||||
|
||||
ChangeLock lock (*this);
|
||||
|
||||
mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel,
|
||||
|
@ -79,6 +96,8 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo
|
|||
if (mChangeLocked)
|
||||
return;
|
||||
|
||||
ChangeLock lock (*this);
|
||||
|
||||
QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn);
|
||||
|
||||
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row() &&
|
||||
|
@ -96,4 +115,14 @@ void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, i
|
|||
|
||||
if (!parent.isValid() && index.row()>=start && index.row()<=end)
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::updateHighlighting()
|
||||
{
|
||||
if (mChangeLocked)
|
||||
return;
|
||||
|
||||
ChangeLock lock (*this);
|
||||
|
||||
mHighlighter->rehighlight();
|
||||
}
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "../doc/subview.hpp"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
class QTextEdit;
|
||||
class QModelIndex;
|
||||
|
||||
|
@ -18,6 +20,8 @@ namespace CSMWorld
|
|||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class ScriptHighlighter;
|
||||
|
||||
class ScriptSubView : public CSVDoc::SubView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -27,6 +31,8 @@ namespace CSVWorld
|
|||
CSMWorld::IdTable *mModel;
|
||||
int mColumn;
|
||||
int mChangeLocked;
|
||||
ScriptHighlighter *mHighlighter;
|
||||
QTimer mUpdateTimer;
|
||||
|
||||
class ChangeLock
|
||||
{
|
||||
|
@ -49,13 +55,19 @@ namespace CSVWorld
|
|||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
private slots:
|
||||
public slots:
|
||||
|
||||
void idListChanged();
|
||||
|
||||
void textChanged();
|
||||
|
||||
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||
|
||||
void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||
|
||||
private slots:
|
||||
|
||||
void updateHighlighting();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "cellcreator.hpp"
|
||||
#include "referenceablecreator.hpp"
|
||||
#include "referencecreator.hpp"
|
||||
#include "scenesubview.hpp"
|
||||
|
||||
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||
{
|
||||
|
@ -62,4 +63,5 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
new CSVDoc::SubViewFactoryWithCreator<TableSubView,
|
||||
CreatorFactory<CSVFilter::FilterCreator> >);
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory<SceneSubView>);
|
||||
}
|
|
@ -12,8 +12,8 @@
|
|||
#include "../../model/world/idtableproxymodel.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/record.hpp"
|
||||
|
||||
#include "recordstatusdelegate.hpp"
|
||||
#include "refidtypedelegate.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||
|
|
|
@ -119,6 +119,10 @@ target_link_libraries(openmw
|
|||
components
|
||||
)
|
||||
|
||||
if (USE_SYSTEM_TINYXML)
|
||||
target_link_libraries(openmw ${TINYXML_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (NOT UNIX)
|
||||
target_link_libraries(openmw ${SDL2MAIN_LIBRARY})
|
||||
endif()
|
||||
|
|
|
@ -357,8 +357,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
mOgre->configure(
|
||||
mCfgMgr.getLogPath().string(),
|
||||
renderSystem,
|
||||
Settings::Manager::getString("opengl rtt mode", "Video"),
|
||||
false);
|
||||
Settings::Manager::getString("opengl rtt mode", "Video"));
|
||||
|
||||
// This has to be added BEFORE MyGUI is initialized, as it needs
|
||||
// to find core.xml here.
|
||||
|
@ -399,8 +398,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding);
|
||||
mEnvironment.setWindowManager (window);
|
||||
if (mNewGame)
|
||||
mEnvironment.getWindowManager()->setNewGame(true);
|
||||
|
||||
// Create the world
|
||||
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins,
|
||||
|
@ -410,6 +407,10 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
input->setPlayer(&mEnvironment.getWorld()->getPlayer());
|
||||
|
||||
window->initUI();
|
||||
if (mNewGame)
|
||||
// still redundant work here: recreate CharacterCreation(),
|
||||
// double update visibility etc.
|
||||
window->setNewGame(true);
|
||||
window->renderWorldMap();
|
||||
|
||||
//Load translation data
|
||||
|
@ -501,7 +502,8 @@ void OMW::Engine::go()
|
|||
MWBase::Environment::get().getWindowManager()->executeInConsole (mStartupScript);
|
||||
|
||||
// Start the main rendering loop
|
||||
mOgre->start();
|
||||
while (!mEnvironment.getRequestExit())
|
||||
Ogre::Root::getSingleton().renderOneFrame();
|
||||
|
||||
// Save user settings
|
||||
settings.saveUser(settingspath);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "windowmanager.hpp"
|
||||
|
||||
MWBase::Environment *MWBase::Environment::sThis = 0;
|
||||
bool MWBase::Environment::sExit = false;
|
||||
|
||||
MWBase::Environment::Environment()
|
||||
: mWorld (0), mSoundManager (0), mScriptManager (0), mWindowManager (0),
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace MWBase
|
|||
InputManager *mInputManager;
|
||||
float mFrameDuration;
|
||||
|
||||
static bool sExit;
|
||||
|
||||
Environment (const Environment&);
|
||||
///< not implemented
|
||||
|
||||
|
@ -44,6 +46,9 @@ namespace MWBase
|
|||
|
||||
~Environment();
|
||||
|
||||
static void setRequestExit () { sExit = true; }
|
||||
static bool getRequestExit () { return sExit; }
|
||||
|
||||
void setWorld (World *world);
|
||||
|
||||
void setSoundManager (SoundManager *soundManager);
|
||||
|
|
|
@ -324,6 +324,7 @@ namespace MWBase
|
|||
virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0;
|
||||
|
||||
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
|
||||
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
|
||||
virtual bool isSwimming(const MWWorld::Ptr &object) const = 0;
|
||||
///Is the head of the creature underwater?
|
||||
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
|
||||
|
@ -392,12 +393,22 @@ namespace MWBase
|
|||
/// Returns true if teleport spell effects are allowed.
|
||||
virtual bool isTeleportingEnabled() const = 0;
|
||||
|
||||
/// Enables or disables use of levitation spell effect.
|
||||
virtual void enableLevitation(bool enable) = 0;
|
||||
|
||||
/// Returns true if levitation spell effect is allowed.
|
||||
virtual bool isLevitationEnabled() const = 0;
|
||||
|
||||
/// Turn actor into werewolf or normal form.
|
||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0;
|
||||
|
||||
/// Sets the NPC's Acrobatics skill to match the fWerewolfAcrobatics GMST.
|
||||
/// It only applies to the current form the NPC is in.
|
||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0;
|
||||
|
||||
virtual bool getGodModeState() = 0;
|
||||
|
||||
virtual bool toggleGodMode() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -16,12 +16,34 @@
|
|||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/customdata.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
#include "../mwrender/renderinginterface.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
{
|
||||
float mTime;
|
||||
///< Time remaining
|
||||
|
||||
CustomData(MWWorld::Ptr ptr)
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
|
||||
mTime = ref->mBase->mData.mTime;
|
||||
}
|
||||
///< Constructs this CustomData from the base values for Ptr.
|
||||
|
||||
virtual MWWorld::CustomData *clone() const
|
||||
{
|
||||
return new CustomData (*this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||
|
@ -182,6 +204,21 @@ namespace MWClass
|
|||
return action;
|
||||
}
|
||||
|
||||
void Light::setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const
|
||||
{
|
||||
ensureCustomData(ptr);
|
||||
|
||||
float &timeRemaining = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||
timeRemaining = duration;
|
||||
}
|
||||
|
||||
float Light::getRemainingUsageTime (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ensureCustomData(ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||
}
|
||||
|
||||
MWWorld::Ptr
|
||||
Light::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
|
||||
{
|
||||
|
@ -191,6 +228,12 @@ namespace MWClass
|
|||
return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
void Light::ensureCustomData (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getCustomData())
|
||||
ptr.getRefData().setCustomData(new CustomData(ptr));
|
||||
}
|
||||
|
||||
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
{
|
||||
return npcServices & ESM::NPC::Lights;
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace MWClass
|
|||
virtual MWWorld::Ptr
|
||||
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
|
||||
|
||||
void ensureCustomData (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
public:
|
||||
|
||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||
|
@ -56,6 +58,12 @@ namespace MWClass
|
|||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual void setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const;
|
||||
///< Sets the remaining duration of the object.
|
||||
|
||||
virtual float getRemainingUsageTime (const MWWorld::Ptr& ptr) const;
|
||||
///< Returns the remaining duration of the object.
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
@ -396,9 +397,10 @@ namespace MWClass
|
|||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
|
||||
}
|
||||
weapon.getCellRef().mCharge -= std::min(std::max(1,
|
||||
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())),
|
||||
weapon.getCellRef().mCharge);
|
||||
|
||||
if (!MWBase::Environment::get().getWorld()->getGodModeState())
|
||||
weapon.getCellRef().mCharge -= std::min(std::max(1,
|
||||
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge);
|
||||
}
|
||||
healthdmg = true;
|
||||
}
|
||||
|
@ -769,6 +771,37 @@ namespace MWClass
|
|||
return x;
|
||||
}
|
||||
|
||||
float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const
|
||||
{
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||
|
||||
const float fallDistanceMin = gmst.find("fFallDamageDistanceMin")->getFloat();
|
||||
|
||||
if (fallHeight >= fallDistanceMin)
|
||||
{
|
||||
const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
|
||||
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
|
||||
const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Jump)).mMagnitude;
|
||||
const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat();
|
||||
const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat();
|
||||
const float fallDistanceBase = gmst.find("fFallDistanceBase")->getFloat();
|
||||
const float fallDistanceMult = gmst.find("fFallDistanceMult")->getFloat();
|
||||
|
||||
float x = fallHeight - fallDistanceMin;
|
||||
x -= (1.5 * acrobaticsSkill) + jumpSpellBonus;
|
||||
x = std::max(0.0f, x);
|
||||
|
||||
float a = fallAcroBase + fallAcroMult * (100 - acrobaticsSkill);
|
||||
x = fallDistanceBase + fallDistanceMult * x;
|
||||
x *= a;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ensureCustomData (ptr);
|
||||
|
|
|
@ -97,6 +97,9 @@ namespace MWClass
|
|||
virtual float getJump(const MWWorld::Ptr &ptr) const;
|
||||
///< Return jump velocity (not accounting for movement)
|
||||
|
||||
virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const;
|
||||
///< Return amount of health points lost when falling
|
||||
|
||||
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
||||
///< Return desired movement.
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <MyGUI_XmlDocument.h>
|
||||
#include <MyGUI_FactoryManager.h>
|
||||
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
namespace
|
||||
|
@ -62,6 +63,58 @@ namespace
|
|||
|
||||
return unicode;
|
||||
}
|
||||
|
||||
std::string getUtf8 (unsigned char c, ToUTF8::Utf8Encoder& encoder, ToUTF8::FromType encoding)
|
||||
{
|
||||
if (encoding == ToUTF8::WINDOWS_1250)
|
||||
{
|
||||
unsigned char win1250;
|
||||
std::map<unsigned char, unsigned char> conv;
|
||||
conv[0x80] = 0xc6;
|
||||
conv[0x81] = 0x9c;
|
||||
conv[0x82] = 0xe6;
|
||||
conv[0x83] = 0xb3;
|
||||
conv[0x84] = 0xf1;
|
||||
conv[0x85] = 0xb9;
|
||||
conv[0x86] = 0xbf;
|
||||
conv[0x87] = 0x9f;
|
||||
conv[0x88] = 0xea;
|
||||
conv[0x89] = 0xea;
|
||||
conv[0x8a] = 0x0; // not contained in win1250
|
||||
conv[0x8b] = 0x0; // not contained in win1250
|
||||
conv[0x8c] = 0x8f;
|
||||
conv[0x8d] = 0xaf;
|
||||
conv[0x8e] = 0xa5;
|
||||
conv[0x8f] = 0x8c;
|
||||
conv[0x90] = 0xca;
|
||||
conv[0x93] = 0xa3;
|
||||
conv[0x94] = 0xf6;
|
||||
conv[0x95] = 0xf3;
|
||||
conv[0x96] = 0xaf;
|
||||
conv[0x97] = 0x8f;
|
||||
conv[0x99] = 0xd3;
|
||||
conv[0x9a] = 0xd1;
|
||||
conv[0x9c] = 0x0; // not contained in win1250
|
||||
conv[0xa0] = 0xb9;
|
||||
conv[0xa1] = 0xaf;
|
||||
conv[0xa2] = 0xf3;
|
||||
conv[0xa3] = 0xbf;
|
||||
conv[0xa4] = 0x0; // not contained in win1250
|
||||
conv[0xe1] = 0x8c;
|
||||
conv[0xe1] = 0x8c;
|
||||
conv[0xe3] = 0x0; // not contained in win1250
|
||||
conv[0xf5] = 0x0; // not contained in win1250
|
||||
|
||||
if (conv.find(c) != conv.end())
|
||||
win1250 = conv[c];
|
||||
else
|
||||
win1250 = c;
|
||||
return encoder.getUtf8(std::string(1, win1250));
|
||||
}
|
||||
else
|
||||
return encoder.getUtf8(std::string(1, c));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
|
@ -184,7 +237,7 @@ namespace MWGui
|
|||
int h = data[i].bottom_left.y*height - y1;
|
||||
|
||||
ToUTF8::Utf8Encoder encoder(mEncoding);
|
||||
unsigned long unicodeVal = utf8ToUnicode(encoder.getUtf8(std::string(1, (unsigned char)(i))));
|
||||
unsigned long unicodeVal = utf8ToUnicode(getUtf8(i, encoder, mEncoding));
|
||||
|
||||
MyGUI::xml::ElementPtr code = codes->createChild("Code");
|
||||
code->addAttribute("index", unicodeVal);
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace MWGui
|
|||
, mStamina(NULL)
|
||||
, mDrowning(NULL)
|
||||
, mDrowningFrame(NULL)
|
||||
, mDrowningFlash(NULL)
|
||||
, mWeapImage(NULL)
|
||||
, mSpellImage(NULL)
|
||||
, mWeapStatus(NULL)
|
||||
|
@ -53,6 +54,7 @@ namespace MWGui
|
|||
, mSpellVisible(true)
|
||||
, mWorldMouseOver(false)
|
||||
, mEnemyHealthTimer(0)
|
||||
, mIsDrowning(false)
|
||||
{
|
||||
setCoord(0,0, width, height);
|
||||
|
||||
|
@ -75,6 +77,7 @@ namespace MWGui
|
|||
//Drowning bar
|
||||
getWidget(mDrowningFrame, "DrowningFrame");
|
||||
getWidget(mDrowning, "Drowning");
|
||||
getWidget(mDrowningFlash, "Flash");
|
||||
mDrowning->setProgressRange(200);
|
||||
|
||||
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
@ -207,7 +210,15 @@ namespace MWGui
|
|||
|
||||
void HUD::setDrowningTimeLeft(float time)
|
||||
{
|
||||
mDrowning->setProgressPosition(time/20.0*200.0);
|
||||
size_t progress = time/20.0*200.0;
|
||||
mDrowning->setProgressPosition(progress);
|
||||
|
||||
bool isDrowning = (progress == 0);
|
||||
if (isDrowning && !mIsDrowning) // Just started drowning
|
||||
mDrowningFlashTheta = 0.0f; // Start out on bright red every time.
|
||||
|
||||
mDrowningFlash->setVisible(isDrowning);
|
||||
mIsDrowning = isDrowning;
|
||||
}
|
||||
|
||||
void HUD::setDrowningBarVisible(bool visible)
|
||||
|
@ -250,6 +261,7 @@ namespace MWGui
|
|||
// remove object from the container it was coming from
|
||||
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
|
||||
mDragAndDrop->finish();
|
||||
mDragAndDrop->mSourceModel->update();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -366,6 +378,9 @@ namespace MWGui
|
|||
mEnemyHealth->setVisible(false);
|
||||
mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() + MyGUI::IntPoint(0,20));
|
||||
}
|
||||
|
||||
if (mIsDrowning)
|
||||
mDrowningFlashTheta += dt * Ogre::Math::TWO_PI;
|
||||
}
|
||||
|
||||
void HUD::onResChange(int width, int height)
|
||||
|
@ -608,6 +623,12 @@ namespace MWGui
|
|||
mEnemyHealth->setProgressRange(100);
|
||||
mEnemyHealth->setProgressPosition(stats.getHealth().getCurrent() / stats.getHealth().getModified() * 100);
|
||||
}
|
||||
|
||||
if (mIsDrowning)
|
||||
{
|
||||
float intensity = (cos(mDrowningFlashTheta) + 1.0f) / 2.0f;
|
||||
mDrowningFlash->setColour(MyGUI::Colour(intensity, intensity, intensity));
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setEnemy(const MWWorld::Ptr &enemy)
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace MWGui
|
|||
MyGUI::ImageBox* mCrosshair;
|
||||
MyGUI::TextBox* mCellNameBox;
|
||||
MyGUI::TextBox* mWeaponSpellBox;
|
||||
MyGUI::Widget* mDrowningFrame;
|
||||
MyGUI::Widget *mDrowningFrame, *mDrowningFlash;
|
||||
|
||||
MyGUI::Widget* mDummy;
|
||||
|
||||
|
@ -101,6 +101,9 @@ namespace MWGui
|
|||
MWWorld::Ptr mEnemy;
|
||||
float mEnemyHealthTimer;
|
||||
|
||||
bool mIsDrowning;
|
||||
float mDrowningFlashTheta;
|
||||
|
||||
void onWorldClicked(MyGUI::Widget* _sender);
|
||||
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
|
||||
void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new);
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace MWGui
|
|||
, mLastWallpaperChangeTime(0.f)
|
||||
, mFirstLoad(true)
|
||||
, mProgress(0)
|
||||
, mVSyncWasEnabled(false)
|
||||
{
|
||||
getWidget(mLoadingText, "LoadingText");
|
||||
getWidget(mProgressBar, "ProgressBar");
|
||||
|
@ -67,6 +68,14 @@ namespace MWGui
|
|||
|
||||
void LoadingScreen::loadingOn()
|
||||
{
|
||||
// Temporarily turn off VSync, we want to do actual loading rather than waiting for the screen to sync.
|
||||
// Threaded loading would be even better, of course - especially because some drivers force VSync to on and we can't change it.
|
||||
// In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/
|
||||
mVSyncWasEnabled = mWindow->isVSyncEnabled();
|
||||
#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0)
|
||||
mWindow->setVSyncEnabled(false);
|
||||
#endif
|
||||
|
||||
setVisible(true);
|
||||
|
||||
if (mFirstLoad)
|
||||
|
@ -83,6 +92,12 @@ namespace MWGui
|
|||
|
||||
void LoadingScreen::loadingOff()
|
||||
{
|
||||
// Re-enable vsync now.
|
||||
// In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/
|
||||
#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0)
|
||||
mWindow->setVSyncEnabled(mVSyncWasEnabled);
|
||||
#endif
|
||||
|
||||
setVisible(false);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading);
|
||||
|
@ -212,7 +227,8 @@ namespace MWGui
|
|||
// caused a sync / flush and would be expensive).
|
||||
// We're doing this so we can do some actual loading while the GPU is busy with the render.
|
||||
// This means the render is lagging a frame behind, but this is hardly noticable.
|
||||
mWindow->swapBuffers(false); // never Vsync, makes no sense here
|
||||
mWindow->swapBuffers();
|
||||
|
||||
mWindow->update(false);
|
||||
|
||||
if (!hasCompositor)
|
||||
|
|
|
@ -57,6 +57,8 @@ namespace MWGui
|
|||
|
||||
Ogre::StringVector mResources;
|
||||
|
||||
bool mVSyncWasEnabled;
|
||||
|
||||
void changeWallpaper();
|
||||
|
||||
void draw();
|
||||
|
|
|
@ -70,11 +70,14 @@ namespace MWGui
|
|||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
||||
if (sender == mButtons["return"])
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager ()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
|
||||
MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu);
|
||||
}
|
||||
else if (sender == mButtons["options"])
|
||||
MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings);
|
||||
else if (sender == mButtons["exitgame"])
|
||||
Ogre::Root::getSingleton ().queueEndRendering ();
|
||||
MWBase::Environment::get().setRequestExit();
|
||||
else if (sender == mButtons["newgame"])
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->startNewGame();
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace MWGui
|
|||
mMessageBoxSpeed = 0.1;
|
||||
mInterMessageBoxe = NULL;
|
||||
mStaticMessageBox = NULL;
|
||||
mLastButtonPressed = -1;
|
||||
}
|
||||
|
||||
void MessageBoxManager::onFrame (float frameDuration)
|
||||
|
@ -62,6 +63,7 @@ namespace MWGui
|
|||
}
|
||||
|
||||
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
|
||||
mLastButtonPressed = mInterMessageBoxe->readPressedButton();
|
||||
delete mInterMessageBoxe;
|
||||
mInterMessageBoxe = NULL;
|
||||
MWBase::Environment::get().getInputManager()->changeInputMode(
|
||||
|
@ -107,6 +109,7 @@ namespace MWGui
|
|||
}
|
||||
|
||||
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
|
||||
mLastButtonPressed = -1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -154,11 +157,9 @@ namespace MWGui
|
|||
|
||||
int MessageBoxManager::readPressedButton ()
|
||||
{
|
||||
if(mInterMessageBoxe != NULL)
|
||||
{
|
||||
return mInterMessageBoxe->readPressedButton();
|
||||
}
|
||||
return -1;
|
||||
int pressed = mLastButtonPressed;
|
||||
mLastButtonPressed = -1;
|
||||
return pressed;
|
||||
}
|
||||
|
||||
|
||||
|
@ -421,9 +422,7 @@ namespace MWGui
|
|||
|
||||
int InteractiveMessageBox::readPressedButton ()
|
||||
{
|
||||
int pressed = mButtonPressed;
|
||||
mButtonPressed = -1;
|
||||
return pressed;
|
||||
return mButtonPressed;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace MWGui
|
|||
MessageBox* mStaticMessageBox;
|
||||
std::vector<MessageBoxManagerTimer> mTimers;
|
||||
float mMessageBoxSpeed;
|
||||
int mLastButtonPressed;
|
||||
};
|
||||
|
||||
class MessageBox : public OEngine::GUI::Layout
|
||||
|
|
|
@ -363,8 +363,12 @@ namespace MWGui
|
|||
else if (_sender == mVSyncButton)
|
||||
{
|
||||
Settings::Manager::setBool("vsync", "Video", newState);
|
||||
// Ogre::Window::setVSyncEnabled is bugged in 1.8
|
||||
#if OGRE_VERSION < (1 << 16 | 9 << 8 | 0)
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("VSync will be applied after a restart", std::vector<std::string>());
|
||||
#endif
|
||||
apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
@ -169,13 +172,34 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->getGameSettingString(
|
||||
ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")";
|
||||
|
||||
if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
||||
ESM::MagicEffect::MagnitudeDisplayType displayType = effect->getMagnitudeDisplayType();
|
||||
if (displayType == ESM::MagicEffect::MDT_TimesInt)
|
||||
{
|
||||
std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", "");
|
||||
std::stringstream formatter;
|
||||
formatter << std::fixed << std::setprecision(1) << " " << (effectIt->mMagnitude / 10.0f) << timesInt;
|
||||
sourcesDescription += formatter.str();
|
||||
}
|
||||
else if ( displayType != ESM::MagicEffect::MDT_None )
|
||||
{
|
||||
std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "");
|
||||
std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "");
|
||||
|
||||
sourcesDescription += ": " + boost::lexical_cast<std::string>(effectIt->mMagnitude);
|
||||
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt);
|
||||
|
||||
if ( displayType == ESM::MagicEffect::MDT_Percentage )
|
||||
sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", "");
|
||||
else if ( displayType == ESM::MagicEffect::MDT_Feet )
|
||||
sourcesDescription += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", "");
|
||||
else if ( displayType == ESM::MagicEffect::MDT_Level )
|
||||
{
|
||||
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ?
|
||||
MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", "") :
|
||||
MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", "") );
|
||||
}
|
||||
else // ESM::MagicEffect::MDT_Points
|
||||
{
|
||||
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ?
|
||||
MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "") :
|
||||
MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "") );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <MyGUI_ProgressBar.h>
|
||||
#include <MyGUI_ImageBox.h>
|
||||
#include <MyGUI_ControllerManager.h>
|
||||
|
@ -405,6 +408,10 @@ namespace MWGui
|
|||
|
||||
std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "");
|
||||
std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "");
|
||||
std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", "");
|
||||
std::string ft = MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", "");
|
||||
std::string lvl = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", "");
|
||||
std::string lvls = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", "");
|
||||
std::string to = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "") + " ";
|
||||
std::string sec = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("ssecond", "");
|
||||
std::string secs = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sseconds", "");
|
||||
|
@ -421,13 +428,32 @@ namespace MWGui
|
|||
spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], "");
|
||||
}
|
||||
|
||||
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
||||
{
|
||||
if (mEffectParams.mMagnMin == mEffectParams.mMagnMax)
|
||||
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts);
|
||||
else
|
||||
{
|
||||
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax) + " " + pts;
|
||||
if (mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) {
|
||||
ESM::MagicEffect::MagnitudeDisplayType displayType = magicEffect->getMagnitudeDisplayType();
|
||||
if ( displayType == ESM::MagicEffect::MDT_TimesInt ) {
|
||||
std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", "");
|
||||
std::stringstream formatter;
|
||||
|
||||
formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f);
|
||||
if (mEffectParams.mMagnMin != mEffectParams.mMagnMax)
|
||||
formatter << to << (mEffectParams.mMagnMax / 10.0f);
|
||||
formatter << timesInt;
|
||||
|
||||
spellLine += formatter.str();
|
||||
}
|
||||
else if ( displayType != ESM::MagicEffect::MDT_None ) {
|
||||
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin);
|
||||
if (mEffectParams.mMagnMin != mEffectParams.mMagnMax)
|
||||
spellLine += to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax);
|
||||
|
||||
if ( displayType == ESM::MagicEffect::MDT_Percentage )
|
||||
spellLine += pct;
|
||||
else if ( displayType == ESM::MagicEffect::MDT_Feet )
|
||||
spellLine += " " + ft;
|
||||
else if ( displayType == ESM::MagicEffect::MDT_Level )
|
||||
spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? lvl : lvls );
|
||||
else // ESM::MagicEffect::MDT_Points
|
||||
spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,20 +61,23 @@ namespace MWGui
|
|||
const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *ogre,
|
||||
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
|
||||
Translation::Storage& translationDataStorage, ToUTF8::FromType encoding)
|
||||
: mGuiManager(NULL)
|
||||
, mConsoleOnlyScripts(consoleOnlyScripts)
|
||||
: mConsoleOnlyScripts(consoleOnlyScripts)
|
||||
, mGuiManager(NULL)
|
||||
, mRendering(ogre)
|
||||
, mHud(NULL)
|
||||
, mMap(NULL)
|
||||
, mMenu(NULL)
|
||||
, mStatsWindow(NULL)
|
||||
, mToolTips(NULL)
|
||||
, mStatsWindow(NULL)
|
||||
, mMessageBoxManager(NULL)
|
||||
, mConsole(NULL)
|
||||
, mJournal(NULL)
|
||||
, mDialogueWindow(NULL)
|
||||
, mBookWindow(NULL)
|
||||
, mContainerWindow(NULL)
|
||||
, mDragAndDrop(NULL)
|
||||
, mInventoryWindow(NULL)
|
||||
, mScrollWindow(NULL)
|
||||
, mBookWindow(NULL)
|
||||
, mCountDialog(NULL)
|
||||
, mTradeWindow(NULL)
|
||||
, mSpellBuyingWindow(NULL)
|
||||
|
@ -83,27 +86,37 @@ namespace MWGui
|
|||
, mConfirmationDialog(NULL)
|
||||
, mAlchemyWindow(NULL)
|
||||
, mSpellWindow(NULL)
|
||||
, mQuickKeysMenu(NULL)
|
||||
, mLoadingScreen(NULL)
|
||||
, mCharGen(NULL)
|
||||
, mLevelupDialog(NULL)
|
||||
, mWaitDialog(NULL)
|
||||
, mSpellCreationDialog(NULL)
|
||||
, mEnchantingDialog(NULL)
|
||||
, mTrainingWindow(NULL)
|
||||
, mMerchantRepair(NULL)
|
||||
, mRepair(NULL)
|
||||
, mSoulgemDialog(NULL)
|
||||
, mRepair(NULL)
|
||||
, mCompanionWindow(NULL)
|
||||
, mTranslationDataStorage (translationDataStorage)
|
||||
, mSoftwareCursor(NULL)
|
||||
, mCharGen(NULL)
|
||||
, mInputBlocker(NULL)
|
||||
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
|
||||
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
|
||||
, mHudEnabled(true)
|
||||
, mCursorVisible(true)
|
||||
, mPlayerName()
|
||||
, mPlayerRaceId()
|
||||
, mPlayerAttributes()
|
||||
, mPlayerMajorSkills()
|
||||
, mPlayerMinorSkills()
|
||||
, mPlayerMajorSkills()
|
||||
, mPlayerSkillValues()
|
||||
, mPlayerHealth()
|
||||
, mPlayerMagicka()
|
||||
, mPlayerFatigue()
|
||||
, mGui(NULL)
|
||||
, mGuiModes()
|
||||
, mCursorManager(NULL)
|
||||
, mGarbageDialogs()
|
||||
, mShown(GW_ALL)
|
||||
, mForceHidden(GW_None)
|
||||
|
@ -113,13 +126,7 @@ namespace MWGui
|
|||
, mFPS(0.0f)
|
||||
, mTriangleCount(0)
|
||||
, mBatchCount(0)
|
||||
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
|
||||
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
|
||||
, mHudEnabled(true)
|
||||
, mTranslationDataStorage (translationDataStorage)
|
||||
, mCursorManager(NULL)
|
||||
, mUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI"))
|
||||
, mCursorVisible(true)
|
||||
{
|
||||
// Set up the GUI system
|
||||
mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath);
|
||||
|
|
|
@ -182,9 +182,6 @@ namespace MWInput
|
|||
case A_GameMenu:
|
||||
toggleMainMenu ();
|
||||
break;
|
||||
case A_Quit:
|
||||
exitNow();
|
||||
break;
|
||||
case A_Screenshot:
|
||||
screenshot();
|
||||
break;
|
||||
|
@ -468,6 +465,41 @@ namespace MWInput
|
|||
|
||||
bool InputManager::keyPressed( const SDL_KeyboardEvent &arg )
|
||||
{
|
||||
// Cut, copy & paste
|
||||
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
|
||||
if (focus)
|
||||
{
|
||||
MyGUI::EditBox* edit = focus->castType<MyGUI::EditBox>(false);
|
||||
if (edit && !edit->getEditReadOnly())
|
||||
{
|
||||
if (arg.keysym.sym == SDLK_v && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
|
||||
{
|
||||
char* text = SDL_GetClipboardText();
|
||||
|
||||
if (text)
|
||||
{
|
||||
edit->addText(MyGUI::UString(text));
|
||||
SDL_free(text);
|
||||
}
|
||||
}
|
||||
if (arg.keysym.sym == SDLK_x && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
|
||||
{
|
||||
std::string text = edit->getTextSelection();
|
||||
if (text.length())
|
||||
{
|
||||
SDL_SetClipboardText(text.c_str());
|
||||
edit->deleteTextSelection();
|
||||
}
|
||||
}
|
||||
if (arg.keysym.sym == SDLK_c && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
|
||||
{
|
||||
std::string text = edit->getTextSelection();
|
||||
if (text.length())
|
||||
SDL_SetClipboardText(text.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mInputBinder->keyPressed (arg);
|
||||
|
||||
if(arg.keysym.sym == SDLK_RETURN
|
||||
|
@ -577,15 +609,15 @@ namespace MWInput
|
|||
rot[0] = -y;
|
||||
rot[1] = 0.0f;
|
||||
rot[2] = x;
|
||||
|
||||
// Only actually turn player when we're not in vanity mode
|
||||
|
||||
// Only actually turn player when we're not in vanity mode
|
||||
if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot))
|
||||
{
|
||||
mPlayer->yaw(x/scale);
|
||||
mPlayer->pitch(-y/scale);
|
||||
}
|
||||
|
||||
if (arg.zrel)
|
||||
if (arg.zrel && mControlSwitch["playerviewswitch"]) //Check to make sure you are allowed to zoomout and there is a change
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.zrel);
|
||||
MWBase::Environment::get().getWorld()->setCameraDistance(arg.zrel, true, true);
|
||||
|
@ -617,9 +649,15 @@ namespace MWInput
|
|||
if (MWBase::Environment::get().getWindowManager()->isGuiMode () && MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_Video)
|
||||
MWBase::Environment::get().getWorld ()->stopVideo ();
|
||||
else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu))
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getSoundManager()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
|
||||
MWBase::Environment::get().getSoundManager()->pauseSounds (MWBase::SoundManager::Play_TypeSfx);
|
||||
}
|
||||
}
|
||||
|
||||
void InputManager::toggleSpell()
|
||||
|
@ -773,13 +811,6 @@ namespace MWInput
|
|||
mAlwaysRunActive = !mAlwaysRunActive;
|
||||
}
|
||||
|
||||
// Exit program now button (which is disabled in GUI mode)
|
||||
void InputManager::exitNow()
|
||||
{
|
||||
if(!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
Ogre::Root::getSingleton().queueEndRendering ();
|
||||
}
|
||||
|
||||
void InputManager::resetIdleTime()
|
||||
{
|
||||
if (mTimeIdle < 0)
|
||||
|
|
|
@ -177,7 +177,6 @@ namespace MWInput
|
|||
void activate();
|
||||
void toggleWalking();
|
||||
void toggleAutoMove();
|
||||
void exitNow();
|
||||
void rest();
|
||||
|
||||
void quickKey (int index);
|
||||
|
@ -194,7 +193,7 @@ namespace MWInput
|
|||
|
||||
A_GameMenu,
|
||||
|
||||
A_Quit, // Exit the program
|
||||
A_Unused,
|
||||
|
||||
A_Screenshot, // Take a screenshot
|
||||
|
||||
|
|
|
@ -31,18 +31,24 @@ namespace MWMechanics
|
|||
calculateDynamicStats (ptr);
|
||||
calculateCreatureStatModifiers (ptr);
|
||||
|
||||
// AI
|
||||
if(!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
{
|
||||
// AI
|
||||
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||
creatureStats.getAiSequence().execute (ptr,duration);
|
||||
|
||||
// fatigue restoration
|
||||
calculateRestoration(ptr, duration);
|
||||
}
|
||||
}
|
||||
|
||||
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
|
||||
{
|
||||
if(!paused)
|
||||
{
|
||||
updateDrowning(ptr, duration);
|
||||
updateEquippedLight(ptr, duration);
|
||||
}
|
||||
}
|
||||
|
||||
void Actors::adjustMagicEffects (const MWWorld::Ptr& creature)
|
||||
|
@ -93,39 +99,29 @@ namespace MWMechanics
|
|||
void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration)
|
||||
{
|
||||
CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
|
||||
float capacity = MWWorld::Class::get(ptr).getCapacity(ptr);
|
||||
float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr);
|
||||
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
|
||||
if (normalizedEncumbrance > 1)
|
||||
normalizedEncumbrance = 1;
|
||||
|
||||
if (duration == 3600)
|
||||
{
|
||||
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0;
|
||||
// the actor is sleeping, restore health and magicka
|
||||
|
||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0;
|
||||
|
||||
DynamicStat<float> health = stats.getHealth();
|
||||
health.setCurrent (health.getCurrent() + 0.1 * endurance);
|
||||
stats.setHealth (health);
|
||||
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
float fFatigueReturnBase = store.get<ESM::GameSetting>().find("fFatigueReturnBase")->getFloat ();
|
||||
float fFatigueReturnMult = store.get<ESM::GameSetting>().find("fFatigueReturnMult")->getFloat ();
|
||||
float fEndFatigueMult = store.get<ESM::GameSetting>().find("fEndFatigueMult")->getFloat ();
|
||||
|
||||
float capacity = MWWorld::Class::get(ptr).getCapacity(ptr);
|
||||
float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr);
|
||||
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
|
||||
if (normalizedEncumbrance > 1)
|
||||
normalizedEncumbrance = 1;
|
||||
|
||||
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
||||
x *= fEndFatigueMult * endurance;
|
||||
|
||||
DynamicStat<float> fatigue = stats.getFatigue();
|
||||
fatigue.setCurrent (fatigue.getCurrent() + 3600 * x);
|
||||
stats.setFatigue (fatigue);
|
||||
|
||||
if (!stunted)
|
||||
{
|
||||
float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat ();
|
||||
float fRestMagicMult = settings.find("fRestMagicMult")->getFloat ();
|
||||
|
||||
DynamicStat<float> magicka = stats.getMagicka();
|
||||
magicka.setCurrent (magicka.getCurrent()
|
||||
|
@ -133,6 +129,19 @@ namespace MWMechanics
|
|||
stats.setMagicka (magicka);
|
||||
}
|
||||
}
|
||||
|
||||
// restore fatigue
|
||||
|
||||
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
|
||||
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
|
||||
float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat ();
|
||||
|
||||
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
||||
x *= fEndFatigueMult * endurance;
|
||||
|
||||
DynamicStat<float> fatigue = stats.getFatigue();
|
||||
fatigue.setCurrent (fatigue.getCurrent() + duration * x);
|
||||
stats.setFatigue (fatigue);
|
||||
}
|
||||
|
||||
void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr)
|
||||
|
@ -196,6 +205,49 @@ namespace MWMechanics
|
|||
stats.setTimeToStartDrowning(20);
|
||||
}
|
||||
|
||||
void Actors::updateEquippedLight (const MWWorld::Ptr& ptr, float duration)
|
||||
{
|
||||
//If holding a light...
|
||||
MWWorld::InventoryStore &inventoryStore = MWWorld::Class::get(ptr).getInventoryStore(ptr);
|
||||
MWWorld::ContainerStoreIterator heldIter =
|
||||
inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||
|
||||
if(heldIter.getType() == MWWorld::ContainerStore::Type_Light)
|
||||
{
|
||||
// Use time from the player's light
|
||||
bool isPlayer = ptr.getRefData().getHandle()=="player";
|
||||
if(isPlayer)
|
||||
{
|
||||
float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter);
|
||||
|
||||
// -1 is infinite light source. Other negative values are treated as 0.
|
||||
if(timeRemaining != -1.0f)
|
||||
{
|
||||
timeRemaining -= duration;
|
||||
|
||||
if(timeRemaining > 0.0f)
|
||||
heldIter->getClass().setRemainingUsageTime(*heldIter, timeRemaining);
|
||||
else
|
||||
{
|
||||
heldIter->getRefData().setCount(0); // remove it
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Both NPC and player lights extinguish in water.
|
||||
if(MWBase::Environment::get().getWorld()->isSwimming(ptr))
|
||||
{
|
||||
heldIter->getRefData().setCount(0); // remove it
|
||||
|
||||
// ...But, only the player makes a sound.
|
||||
if(isPlayer)
|
||||
MWBase::Environment::get().getSoundManager()->playSound("torch out",
|
||||
1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoEnv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Actors::Actors() : mDuration (0) {}
|
||||
|
||||
void Actors::addActor (const MWWorld::Ptr& ptr)
|
||||
|
@ -275,9 +327,9 @@ namespace MWMechanics
|
|||
continue;
|
||||
}
|
||||
|
||||
// workaround: always keep player alive for now
|
||||
// \todo remove workaround, once player death can be handled
|
||||
if(iter->first.getRefData().getHandle()=="player")
|
||||
// If it's the player and God Mode is turned on, keep it alive
|
||||
if(iter->first.getRefData().getHandle()=="player" &&
|
||||
MWBase::Environment::get().getWorld()->getGodModeState())
|
||||
{
|
||||
MWMechanics::DynamicStat<float> stat(stats.getHealth());
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ namespace MWMechanics
|
|||
|
||||
void updateDrowning (const MWWorld::Ptr& ptr, float duration);
|
||||
|
||||
void updateEquippedLight (const MWWorld::Ptr& ptr, float duration);
|
||||
|
||||
public:
|
||||
|
||||
Actors();
|
||||
|
|
|
@ -767,10 +767,25 @@ void CharacterController::update(float duration)
|
|||
}
|
||||
|
||||
if(sneak || inwater || flying)
|
||||
{
|
||||
vec.z = 0.0f;
|
||||
mFallHeight = mPtr.getRefData().getPosition().pos[2];
|
||||
}
|
||||
|
||||
if(!onground && !flying && !inwater)
|
||||
{
|
||||
// The player is in the air (either getting up —ascending part of jump— or falling).
|
||||
|
||||
if (world->isSlowFalling(mPtr))
|
||||
{
|
||||
// SlowFalling spell effect is active, do not keep previous fall height
|
||||
mFallHeight = mPtr.getRefData().getPosition().pos[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]);
|
||||
}
|
||||
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||
|
||||
forcestateupdate = (mJumpState != JumpState_Falling);
|
||||
|
@ -794,6 +809,8 @@ void CharacterController::update(float duration)
|
|||
}
|
||||
else if(vec.z > 0.0f && mJumpState == JumpState_None)
|
||||
{
|
||||
// The player has started a jump.
|
||||
|
||||
float z = cls.getJump(mPtr);
|
||||
if(vec.x == 0 && vec.y == 0)
|
||||
vec = Ogre::Vector3(0.0f, 0.0f, z);
|
||||
|
@ -803,13 +820,49 @@ void CharacterController::update(float duration)
|
|||
vec = Ogre::Vector3(lat.x, lat.y, 1.0f) * z * 0.707f;
|
||||
}
|
||||
|
||||
//decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult;
|
||||
// advance acrobatics
|
||||
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0);
|
||||
|
||||
// decrease fatigue
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||
const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->getFloat();
|
||||
const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->getFloat();
|
||||
const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr);
|
||||
const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult;
|
||||
DynamicStat<float> fatigue = cls.getCreatureStats(mPtr).getFatigue();
|
||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease);
|
||||
cls.getCreatureStats(mPtr).setFatigue(fatigue);
|
||||
}
|
||||
else if(mJumpState == JumpState_Falling)
|
||||
{
|
||||
// The player is landing.
|
||||
|
||||
forcestateupdate = true;
|
||||
mJumpState = JumpState_Landing;
|
||||
vec.z = 0.0f;
|
||||
|
||||
float healthLost = cls.getFallDamage(mPtr, mFallHeight - mPtr.getRefData().getPosition().pos[2]);
|
||||
if (healthLost > 0.0f)
|
||||
{
|
||||
const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm();
|
||||
|
||||
// inflict fall damages
|
||||
DynamicStat<float> health = cls.getCreatureStats(mPtr).getHealth();
|
||||
int realHealthLost = healthLost * (1.0f - 0.25 * fatigueTerm);
|
||||
health.setCurrent(health.getCurrent() - realHealthLost);
|
||||
cls.getCreatureStats(mPtr).setHealth(health);
|
||||
|
||||
// report acrobatics progression
|
||||
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1);
|
||||
|
||||
const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified();
|
||||
if (healthLost > (acrobaticsSkill * fatigueTerm))
|
||||
{
|
||||
//TODO: actor falls over
|
||||
}
|
||||
}
|
||||
|
||||
mFallHeight = mPtr.getRefData().getPosition().pos[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
|
@ -154,6 +156,9 @@ class CharacterController
|
|||
float mSecondsOfSwimming;
|
||||
float mSecondsOfRunning;
|
||||
|
||||
// used for acrobatics progress and fall damages
|
||||
float mFallHeight;
|
||||
|
||||
std::string mAttackType; // slash, chop or thrust
|
||||
|
||||
void refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force=false);
|
||||
|
|
|
@ -151,8 +151,7 @@ namespace MWMechanics
|
|||
for (Collection::const_iterator iter (prev.begin()); iter!=prev.end(); ++iter)
|
||||
{
|
||||
Collection::const_iterator other = now.mCollection.find (iter->first);
|
||||
|
||||
if (other==prev.end())
|
||||
if (other==now.end())
|
||||
{
|
||||
result.add (iter->first, EffectParam() - iter->second);
|
||||
}
|
||||
|
|
|
@ -187,6 +187,12 @@ namespace MWRender
|
|||
rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false);
|
||||
}
|
||||
|
||||
void Camera::setSneakOffset()
|
||||
{
|
||||
if(mAnimation)
|
||||
mAnimation->addFirstPersonOffset(Ogre::Vector3(0.f, 0.f, -9.8f));
|
||||
}
|
||||
|
||||
float Camera::getYaw()
|
||||
{
|
||||
if(mVanity.enabled || mPreviewMode)
|
||||
|
|
|
@ -79,6 +79,12 @@ namespace MWRender
|
|||
|
||||
void togglePreviewMode(bool enable);
|
||||
|
||||
/// \brief Lowers the camera for sneak.
|
||||
/// As animation is tied to the camera, this needs
|
||||
/// to be set each frame after the animation is
|
||||
/// applied.
|
||||
void setSneakOffset();
|
||||
|
||||
bool isFirstPerson() const
|
||||
{ return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); }
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue