mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 12:53:51 +00:00
Merge remote branch 'zini/master' into sound
This commit is contained in:
commit
2f8056dfab
275 changed files with 12259 additions and 3026 deletions
|
@ -15,7 +15,7 @@ include (OpenMWMacros)
|
|||
# Version
|
||||
|
||||
set (OPENMW_VERSION_MAJOR 0)
|
||||
set (OPENMW_VERSION_MINOR 14)
|
||||
set (OPENMW_VERSION_MINOR 16)
|
||||
set (OPENMW_VERSION_RELEASE 0)
|
||||
|
||||
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||
|
@ -370,6 +370,10 @@ if(WIN32)
|
|||
INSTALL(FILES
|
||||
"${OpenMW_BINARY_DIR}/plugins.cfg"
|
||||
"${OpenMW_SOURCE_DIR}/readme.txt"
|
||||
"${OpenMW_SOURCE_DIR}/GPL3.txt"
|
||||
"${OpenMW_SOURCE_DIR}/OFL.txt"
|
||||
"${OpenMW_SOURCE_DIR}/Bitstream Vera License.txt"
|
||||
"${OpenMW_SOURCE_DIR}/Daedric Font License.txt"
|
||||
"${OpenMW_BINARY_DIR}/launcher.qss"
|
||||
"${OpenMW_BINARY_DIR}/settings-default.cfg"
|
||||
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
|
||||
|
@ -391,8 +395,8 @@ if(WIN32)
|
|||
!insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
|
||||
Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Readme.lnk\\\"
|
||||
")
|
||||
SET(CPACK_RESOURCE_FILE_README "${OpenMW_SOURCE_DIR}/readme.txt")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
|
||||
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
|
||||
SET(CPACK_NSIS_DISPLAY_NAME "OpenMW")
|
||||
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
|
||||
|
|
|
@ -8,6 +8,7 @@ set(LAUNCHER
|
|||
playpage.cpp
|
||||
pluginsmodel.cpp
|
||||
pluginsview.cpp
|
||||
filedialog.cpp
|
||||
|
||||
launcher.rc
|
||||
)
|
||||
|
@ -22,6 +23,7 @@ set(LAUNCHER_HEADER
|
|||
playpage.hpp
|
||||
pluginsmodel.hpp
|
||||
pluginsview.hpp
|
||||
filedialog.hpp
|
||||
)
|
||||
|
||||
# Headers that must be pre-processed
|
||||
|
@ -34,6 +36,7 @@ set(LAUNCHER_HEADER_MOC
|
|||
playpage.hpp
|
||||
pluginsmodel.hpp
|
||||
pluginsview.hpp
|
||||
filedialog.hpp
|
||||
)
|
||||
|
||||
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC})
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "datafilespage.hpp"
|
||||
#include "lineedit.hpp"
|
||||
#include "filedialog.hpp"
|
||||
#include "naturalsort.hpp"
|
||||
#include "pluginsmodel.hpp"
|
||||
#include "pluginsview.hpp"
|
||||
|
@ -139,7 +140,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent)
|
|||
|
||||
createActions();
|
||||
setupConfig();
|
||||
setupDataFiles();
|
||||
//setupDataFiles();
|
||||
|
||||
}
|
||||
|
||||
|
@ -188,7 +189,7 @@ void DataFilesPage::setupConfig()
|
|||
}
|
||||
|
||||
|
||||
void DataFilesPage::setupDataFiles()
|
||||
bool DataFilesPage::setupDataFiles()
|
||||
{
|
||||
// We use the Configuration Manager to retrieve the configuration values
|
||||
boost::program_options::variables_map variables;
|
||||
|
@ -203,8 +204,7 @@ void DataFilesPage::setupDataFiles()
|
|||
mCfgMgr.readConfiguration(variables, desc);
|
||||
|
||||
// Put the paths in a boost::filesystem vector to use with Files::Collections
|
||||
Files::PathContainer dataDirs(variables["data"].as<Files::PathContainer>());
|
||||
mDataDirs = dataDirs;
|
||||
mDataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||
|
||||
// std::string local = variables["data-local"].as<std::string>();
|
||||
// if (!local.empty()) {
|
||||
|
@ -212,14 +212,12 @@ void DataFilesPage::setupDataFiles()
|
|||
// dataDirs.push_back(Files::PathContainer::value_type(local));
|
||||
// }
|
||||
|
||||
if (dataDirs.size()>1)
|
||||
dataDirs.resize (1);
|
||||
if (mDataDirs.size()>1)
|
||||
mDataDirs.resize (1);
|
||||
|
||||
mCfgMgr.processPaths(dataDirs);
|
||||
|
||||
while (dataDirs.empty()) {
|
||||
// No valid data files directory found
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
|
||||
while (mDataDirs.empty()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error detecting Morrowind installation");
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
|
@ -235,27 +233,29 @@ void DataFilesPage::setupDataFiles()
|
|||
|
||||
if (msgBox.clickedButton() == dirSelectButton) {
|
||||
|
||||
QString dataDir = QFileDialog::getExistingDirectory(
|
||||
// Show a custom dir selection dialog which only accepts valid dirs
|
||||
QString selectedDir = FileDialog::getExistingDirectory(
|
||||
this, tr("Select Data Files Directory"),
|
||||
"/home",
|
||||
QDir::currentPath(),
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
dataDirs.push_back(Files::PathContainer::value_type(dataDir.toStdString()));
|
||||
mDataDirs.push_back(Files::PathContainer::value_type(dataDir.toStdString()));
|
||||
// Add the user selected data directory
|
||||
if (!selectedDir.isEmpty()) {
|
||||
mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString()));
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
} else {
|
||||
// Cancel from within the dir selection dialog
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Cancel
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if cancel was clicked because we can't exit from while loop
|
||||
if (dataDirs.empty()) {
|
||||
QApplication::exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a file collection for the dataDirs
|
||||
Files::Collections fileCollections(dataDirs, !variables["fs-strict"].as<bool>());
|
||||
// Create a file collection for the data dirs
|
||||
Files::Collections fileCollections(mDataDirs, !variables["fs-strict"].as<bool>());
|
||||
|
||||
// First we add all the master files
|
||||
const Files::MultiDirCollection &esm = fileCollections.getCollection(".esm");
|
||||
|
@ -356,6 +356,7 @@ void DataFilesPage::setupDataFiles()
|
|||
}
|
||||
|
||||
readConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DataFilesPage::createActions()
|
||||
|
@ -1057,8 +1058,25 @@ void DataFilesPage::writeConfig(QString profile)
|
|||
return;
|
||||
}
|
||||
|
||||
QString pathStr = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||
QDir userPath(pathStr);
|
||||
|
||||
if (!userPath.exists()) {
|
||||
if (!userPath.mkpath(pathStr)) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error creating OpenMW configuration directory");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not create %0</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>").arg(pathStr));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Open the OpenMW config as a QFile
|
||||
QFile file(QString::fromStdString((mCfgMgr.getUserPath() / "openmw.cfg").string()));
|
||||
QFile file(pathStr.append("openmw.cfg"));
|
||||
|
||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||
// File cannot be opened or created
|
||||
|
@ -1070,7 +1088,7 @@ void DataFilesPage::writeConfig(QString profile)
|
|||
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->exit(1);
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1101,7 +1119,7 @@ void DataFilesPage::writeConfig(QString profile)
|
|||
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->exit(1);
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
ComboBox *mProfilesComboBox;
|
||||
|
||||
void writeConfig(QString profile = QString());
|
||||
bool setupDataFiles();
|
||||
|
||||
public slots:
|
||||
void masterSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
||||
|
@ -92,7 +93,6 @@ private:
|
|||
void removePlugins(const QModelIndex &index);
|
||||
void uncheckPlugins();
|
||||
void createActions();
|
||||
void setupDataFiles();
|
||||
void setupConfig();
|
||||
void readConfig();
|
||||
void scrollToSelection();
|
||||
|
|
57
apps/launcher/filedialog.cpp
Normal file
57
apps/launcher/filedialog.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "filedialog.hpp"
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
|
||||
FileDialog::FileDialog(QWidget *parent)
|
||||
: QFileDialog(parent)
|
||||
{
|
||||
// Remove the default Choose button to prevent it being updated elsewhere
|
||||
QDialogButtonBox *box = qFindChild<QDialogButtonBox*>(this);
|
||||
Q_ASSERT(box);
|
||||
box->removeButton(box->button(QDialogButtonBox::Open));
|
||||
|
||||
// Add our own button so we can disable/enable it
|
||||
mChooseButton = new QPushButton(tr("&Choose"));
|
||||
mChooseButton->setIcon(QIcon::fromTheme("document-open"));
|
||||
mChooseButton->setEnabled(false);
|
||||
box->addButton(mChooseButton, QDialogButtonBox::AcceptRole);
|
||||
|
||||
connect(this, SIGNAL(directoryEntered(const QString&)), this, SLOT(updateChooseButton(const QString&)));
|
||||
emit directoryEntered(QDir::currentPath());
|
||||
}
|
||||
|
||||
QString FileDialog::getExistingDirectory(QWidget *parent,
|
||||
const QString &caption,
|
||||
const QString &dir,
|
||||
Options options)
|
||||
{
|
||||
// create a non-native file dialog
|
||||
FileDialog dialog;
|
||||
dialog.setFileMode(DirectoryOnly);
|
||||
dialog.setOptions(options |= QFileDialog::DontUseNativeDialog | QFileDialog::ShowDirsOnly | QFileDialog::ReadOnly);
|
||||
|
||||
if (!caption.isEmpty())
|
||||
dialog.setWindowTitle(caption);
|
||||
|
||||
if (!dir.isEmpty())
|
||||
dialog.setDirectory(dir);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
return dialog.selectedFiles().value(0);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void FileDialog::updateChooseButton(const QString &directory)
|
||||
{
|
||||
QDir currentDir = QDir(directory);
|
||||
currentDir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
|
||||
currentDir.setNameFilters(QStringList() << "*.esm" << "*.esp");
|
||||
|
||||
if (!currentDir.entryList().isEmpty()) {
|
||||
// There are data files in the current dir
|
||||
mChooseButton->setEnabled(true);
|
||||
} else {
|
||||
mChooseButton->setEnabled(false);
|
||||
}
|
||||
}
|
28
apps/launcher/filedialog.hpp
Normal file
28
apps/launcher/filedialog.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef FILEDIALOG_HPP
|
||||
#define FILEDIALOG_HPP
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
class QPushButton;
|
||||
|
||||
class FileDialog : public QFileDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FileDialog(QWidget *parent = 0);
|
||||
|
||||
static QString getExistingDirectory(QWidget *parent = 0,
|
||||
const QString &caption = QString(),
|
||||
const QString &dir = QString(),
|
||||
Options options = ShowDirsOnly);
|
||||
|
||||
private slots:
|
||||
void updateChooseButton(const QString &directory);
|
||||
|
||||
private:
|
||||
QPushButton *mChooseButton;
|
||||
};
|
||||
|
||||
|
||||
#endif // FILEDIALOG_HPP
|
|
@ -1,7 +1,11 @@
|
|||
#include "graphicspage.hpp"
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
#include "graphicspage.hpp"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
|
@ -17,12 +21,9 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent)
|
|||
renderSystemLayout->addWidget(rendererLabel, 0, 0, 1, 1);
|
||||
renderSystemLayout->addWidget(mRendererComboBox, 0, 1, 1, 1);
|
||||
|
||||
mRendererStackedWidget = new QStackedWidget(rendererGroup);
|
||||
|
||||
QVBoxLayout *rendererGroupLayout = new QVBoxLayout(rendererGroup);
|
||||
|
||||
rendererGroupLayout->addLayout(renderSystemLayout);
|
||||
rendererGroupLayout->addWidget(mRendererStackedWidget);
|
||||
|
||||
// Display
|
||||
QGroupBox *displayGroup = new QGroupBox(tr("Display"), this);
|
||||
|
@ -44,118 +45,36 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent)
|
|||
connect(mRendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&)));
|
||||
|
||||
createPages();
|
||||
setupConfig();
|
||||
setupOgre();
|
||||
|
||||
readConfig();
|
||||
}
|
||||
|
||||
void GraphicsPage::createPages()
|
||||
{
|
||||
// OpenGL rendering settings
|
||||
QWidget *mOGLRendererPage = new QWidget();
|
||||
QWidget *main = new QWidget();
|
||||
QGridLayout *grid = new QGridLayout(main);
|
||||
|
||||
QLabel *OGLRTTLabel = new QLabel(tr("Preferred RTT Mode:"), mOGLRendererPage);
|
||||
mOGLRTTComboBox = new QComboBox(mOGLRendererPage);
|
||||
mVSyncCheckBox = new QCheckBox(tr("Vertical Sync"), main);
|
||||
grid->addWidget(mVSyncCheckBox, 0, 0, 1, 1);
|
||||
|
||||
QLabel *OGLAntiAliasingLabel = new QLabel(tr("Antialiasing:"), mOGLRendererPage);
|
||||
mOGLAntiAliasingComboBox = new QComboBox(mOGLRendererPage);
|
||||
mFullScreenCheckBox = new QCheckBox(tr("Full Screen"), main);
|
||||
grid->addWidget(mFullScreenCheckBox, 1, 0, 1, 1);
|
||||
|
||||
QLabel *antiAliasingLabel = new QLabel(tr("Antialiasing:"), main);
|
||||
mAntiAliasingComboBox = new QComboBox(main);
|
||||
grid->addWidget(antiAliasingLabel, 2, 0, 1, 1);
|
||||
grid->addWidget(mAntiAliasingComboBox, 2, 1, 1, 1);
|
||||
|
||||
QLabel *resolutionLabel = new QLabel(tr("Resolution:"), main);
|
||||
mResolutionComboBox = new QComboBox(main);
|
||||
grid->addWidget(resolutionLabel, 3, 0, 1, 1);
|
||||
grid->addWidget(mResolutionComboBox, 3, 1, 1, 1);
|
||||
|
||||
QGridLayout *OGLRendererLayout = new QGridLayout(mOGLRendererPage);
|
||||
QSpacerItem *vSpacer1 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
grid->addItem(vSpacer1, 4, 0, 1, 1);
|
||||
|
||||
OGLRendererLayout->addWidget(OGLRTTLabel, 0, 0, 1, 1);
|
||||
OGLRendererLayout->addWidget(mOGLRTTComboBox, 0, 1, 1, 1);
|
||||
OGLRendererLayout->addWidget(OGLAntiAliasingLabel, 1, 0, 1, 1);
|
||||
OGLRendererLayout->addWidget(mOGLAntiAliasingComboBox, 1, 1, 1, 1);
|
||||
OGLRendererLayout->addItem(vSpacer1, 2, 1, 1, 1);
|
||||
|
||||
// OpenGL display settings
|
||||
QWidget *mOGLDisplayPage = new QWidget();
|
||||
|
||||
QLabel *OGLResolutionLabel = new QLabel(tr("Resolution:"), mOGLDisplayPage);
|
||||
mOGLResolutionComboBox = new QComboBox(mOGLDisplayPage);
|
||||
|
||||
QLabel *OGLFrequencyLabel = new QLabel(tr("Display Frequency:"), mOGLDisplayPage);
|
||||
mOGLFrequencyComboBox = new QComboBox(mOGLDisplayPage);
|
||||
|
||||
mOGLVSyncCheckBox = new QCheckBox(tr("Vertical Sync"), mOGLDisplayPage);
|
||||
mOGLFullScreenCheckBox = new QCheckBox(tr("Full Screen"), mOGLDisplayPage);
|
||||
|
||||
QGridLayout *OGLDisplayLayout = new QGridLayout(mOGLDisplayPage);
|
||||
QSpacerItem *vSpacer2 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
||||
OGLDisplayLayout->addWidget(OGLResolutionLabel, 0, 0, 1, 1);
|
||||
OGLDisplayLayout->addWidget(mOGLResolutionComboBox, 0, 1, 1, 1);
|
||||
OGLDisplayLayout->addWidget(OGLFrequencyLabel, 1, 0, 1, 1);
|
||||
OGLDisplayLayout->addWidget(mOGLFrequencyComboBox, 1, 1, 1, 1);
|
||||
|
||||
OGLDisplayLayout->addItem(vSpacer2, 2, 1, 1, 1);
|
||||
OGLDisplayLayout->addWidget(mOGLVSyncCheckBox, 3, 0, 1, 1);
|
||||
OGLDisplayLayout->addWidget(mOGLFullScreenCheckBox, 6, 0, 1, 1);
|
||||
|
||||
// Direct3D rendering settings
|
||||
QWidget *mD3DRendererPage = new QWidget();
|
||||
|
||||
QLabel *D3DRenderDeviceLabel = new QLabel(tr("Rendering Device:"), mD3DRendererPage);
|
||||
mD3DRenderDeviceComboBox = new QComboBox(mD3DRendererPage);
|
||||
|
||||
QLabel *D3DAntiAliasingLabel = new QLabel(tr("Antialiasing:"), mD3DRendererPage);
|
||||
mD3DAntiAliasingComboBox = new QComboBox(mD3DRendererPage);
|
||||
|
||||
QLabel *D3DFloatingPointLabel = new QLabel(tr("Floating-point Mode:"), mD3DRendererPage);
|
||||
mD3DFloatingPointComboBox = new QComboBox(mD3DRendererPage);
|
||||
|
||||
mD3DNvPerfCheckBox = new QCheckBox(tr("Allow NVPerfHUD"), mD3DRendererPage);
|
||||
|
||||
QGridLayout *D3DRendererLayout = new QGridLayout(mD3DRendererPage);
|
||||
QSpacerItem *vSpacer3 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
QSpacerItem *vSpacer4 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
|
||||
D3DRendererLayout->addWidget(D3DRenderDeviceLabel, 0, 0, 1, 1);
|
||||
D3DRendererLayout->addWidget(mD3DRenderDeviceComboBox, 0, 1, 1, 1);
|
||||
D3DRendererLayout->addWidget(D3DAntiAliasingLabel, 1, 0, 1, 1);
|
||||
D3DRendererLayout->addWidget(mD3DAntiAliasingComboBox, 1, 1, 1, 1);
|
||||
D3DRendererLayout->addWidget(D3DFloatingPointLabel, 2, 0, 1, 1);
|
||||
D3DRendererLayout->addWidget(mD3DFloatingPointComboBox, 2, 1, 1, 1);
|
||||
D3DRendererLayout->addItem(vSpacer3, 3, 1, 1, 1);
|
||||
D3DRendererLayout->addWidget(mD3DNvPerfCheckBox, 4, 0, 1, 1);
|
||||
D3DRendererLayout->addItem(vSpacer4, 5, 1, 1, 1);
|
||||
|
||||
// Direct3D display settings
|
||||
QWidget *mD3DDisplayPage = new QWidget();
|
||||
|
||||
QLabel *D3DResolutionLabel = new QLabel(tr("Resolution:"), mD3DDisplayPage);
|
||||
mD3DResolutionComboBox = new QComboBox(mD3DDisplayPage);
|
||||
|
||||
mD3DVSyncCheckBox = new QCheckBox(tr("Vertical Sync"), mD3DDisplayPage);
|
||||
mD3DFullScreenCheckBox = new QCheckBox(tr("Full Screen"), mD3DDisplayPage);
|
||||
|
||||
QGridLayout *mD3DDisplayLayout = new QGridLayout(mD3DDisplayPage);
|
||||
QSpacerItem *vSpacer5 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
||||
mD3DDisplayLayout->addWidget(D3DResolutionLabel, 0, 0, 1, 1);
|
||||
mD3DDisplayLayout->addWidget(mD3DResolutionComboBox, 0, 1, 1, 1);
|
||||
mD3DDisplayLayout->addItem(vSpacer5, 1, 1, 1, 1);
|
||||
mD3DDisplayLayout->addWidget(mD3DVSyncCheckBox, 2, 0, 1, 1);
|
||||
mD3DDisplayLayout->addWidget(mD3DFullScreenCheckBox, 5, 0, 1, 1);
|
||||
|
||||
// Add the created pages
|
||||
mRendererStackedWidget->addWidget(mOGLRendererPage);
|
||||
mRendererStackedWidget->addWidget(mD3DRendererPage);
|
||||
|
||||
mDisplayStackedWidget->addWidget(mOGLDisplayPage);
|
||||
mDisplayStackedWidget->addWidget(mD3DDisplayPage);
|
||||
mDisplayStackedWidget->addWidget(main);
|
||||
}
|
||||
|
||||
void GraphicsPage::setupConfig()
|
||||
{
|
||||
QString ogreCfg = mCfgMgr.getOgreConfigPath().string().c_str();
|
||||
QFile file(ogreCfg);
|
||||
mOgreConfig = new QSettings(ogreCfg, QSettings::IniFormat);
|
||||
}
|
||||
|
||||
void GraphicsPage::setupOgre()
|
||||
bool GraphicsPage::setupOgre()
|
||||
{
|
||||
QString pluginCfg = mCfgMgr.getPluginsConfigPath().string().c_str();
|
||||
QFile file(pluginCfg);
|
||||
|
@ -164,32 +83,12 @@ void GraphicsPage::setupOgre()
|
|||
Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager;
|
||||
logMgr->createLog((mCfgMgr.getLogPath().string() + "/launcherOgre.log"), true, false, false);
|
||||
|
||||
QString ogreCfg = QString::fromStdString(mCfgMgr.getOgreConfigPath().string());
|
||||
file.setFileName(ogreCfg);
|
||||
|
||||
//we need to check that the path to the configuration file exists before we
|
||||
//try and create an instance of Ogre::Root otherwise Ogre raises an exception
|
||||
QDir configDir = QFileInfo(file).dir();
|
||||
if ( !configDir.exists() && !configDir.mkpath(configDir.path()) )
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error creating config file");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(QString(tr("<br><b>Failed to create the configuration file</b><br><br> \
|
||||
Make sure you have write access to<br>%1<br><br>")).arg(configDir.path()));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9)
|
||||
mOgre = new Ogre::Root("", file.fileName().toStdString(), "./launcherOgre.log");
|
||||
mOgre = new Ogre::Root("", "", "./launcherOgre.log");
|
||||
#else
|
||||
mOgre = new Ogre::Root(pluginCfg.toStdString(), file.fileName().toStdString(), "./launcherOgre.log");
|
||||
mOgre = new Ogre::Root(pluginCfg.toStdString(), "", "./launcherOgre.log");
|
||||
#endif
|
||||
}
|
||||
catch(Ogre::Exception &ex)
|
||||
|
@ -206,9 +105,7 @@ void GraphicsPage::setupOgre()
|
|||
msgBox.exec();
|
||||
|
||||
qCritical("Error creating Ogre::Root, the error reported was:\n %s", qPrintable(ogreError));
|
||||
|
||||
qApp->exit(1);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_PLUGIN_GL
|
||||
|
@ -228,11 +125,19 @@ void GraphicsPage::setupOgre()
|
|||
mRendererComboBox->addItem((*r)->getName().c_str());
|
||||
}
|
||||
|
||||
int index = mRendererComboBox->findText(mOgreConfig->value("Render System").toString());
|
||||
int index = mRendererComboBox->findText(QString::fromStdString(Settings::Manager::getString("render system", "Video")));
|
||||
|
||||
if ( index != -1) {
|
||||
mRendererComboBox->setCurrentIndex(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||
mRendererComboBox->setCurrentIndex(mRendererComboBox->findText("Direct3D9 Rendering Subsystem"));
|
||||
#else
|
||||
mRendererComboBox->setCurrentIndex(mRendererComboBox->findText("OpenGL Rendering Subsystem"));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create separate rendersystems
|
||||
QString openGLName = mRendererComboBox->itemText(mRendererComboBox->findText(QString("OpenGL"), Qt::MatchStartsWith));
|
||||
|
@ -250,222 +155,52 @@ void GraphicsPage::setupOgre()
|
|||
Please make sure the plugins.cfg file exists and contains a valid rendering plugin.<br>"));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->exit(1);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now fill the GUI elements
|
||||
// OpenGL
|
||||
if (mOpenGLRenderSystem) {
|
||||
mOGLRTTComboBox->addItems(getAvailableOptions(QString("RTT Preferred Mode"), mOpenGLRenderSystem));
|
||||
mOGLAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mOpenGLRenderSystem));
|
||||
mOGLResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mOpenGLRenderSystem));
|
||||
mOGLFrequencyComboBox->addItems(getAvailableOptions(QString("Display Frequency"), mOpenGLRenderSystem));
|
||||
}
|
||||
mAntiAliasingComboBox->clear();
|
||||
mResolutionComboBox->clear();
|
||||
mAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||
mResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mSelectedRenderSystem));
|
||||
|
||||
// Direct3D
|
||||
if (mDirect3DRenderSystem) {
|
||||
mD3DRenderDeviceComboBox->addItems(getAvailableOptions(QString("Rendering Device"), mDirect3DRenderSystem));
|
||||
mD3DAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mDirect3DRenderSystem));
|
||||
mD3DFloatingPointComboBox->addItems(getAvailableOptions(QString("Floating-point mode"), mDirect3DRenderSystem));
|
||||
mD3DResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mDirect3DRenderSystem));
|
||||
}
|
||||
readConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GraphicsPage::readConfig()
|
||||
{
|
||||
// Read the config file settings
|
||||
if (mOpenGLRenderSystem) {
|
||||
if (Settings::Manager::getBool("vsync", "Video"))
|
||||
mVSyncCheckBox->setCheckState(Qt::Checked);
|
||||
|
||||
int index = mOGLRTTComboBox->findText(getConfigValue("RTT Preferred Mode", mOpenGLRenderSystem));
|
||||
if ( index != -1) {
|
||||
mOGLRTTComboBox->setCurrentIndex(index);
|
||||
}
|
||||
if (Settings::Manager::getBool("fullscreen", "Video"))
|
||||
mFullScreenCheckBox->setCheckState(Qt::Checked);
|
||||
|
||||
index = mOGLAntiAliasingComboBox->findText(getConfigValue("FSAA", mOpenGLRenderSystem));
|
||||
if ( index != -1){
|
||||
mOGLAntiAliasingComboBox->setCurrentIndex(index);
|
||||
}
|
||||
int aaIndex = mAntiAliasingComboBox->findText(QString::fromStdString(Settings::Manager::getString("antialiasing", "Video")));
|
||||
if (aaIndex != -1)
|
||||
mAntiAliasingComboBox->setCurrentIndex(aaIndex);
|
||||
|
||||
index = mOGLResolutionComboBox->findText(getConfigValue("Video Mode", mOpenGLRenderSystem));
|
||||
if ( index != -1) {
|
||||
mOGLResolutionComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
index = mOGLFrequencyComboBox->findText(getConfigValue("Display Frequency", mOpenGLRenderSystem));
|
||||
if ( index != -1) {
|
||||
mOGLFrequencyComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
// Now we do the same for the checkboxes
|
||||
if (getConfigValue("VSync", mOpenGLRenderSystem) == QLatin1String("Yes")) {
|
||||
mOGLVSyncCheckBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
|
||||
if (getConfigValue("Full Screen", mOpenGLRenderSystem) == QLatin1String("Yes")) {
|
||||
mOGLFullScreenCheckBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
if (mDirect3DRenderSystem) {
|
||||
|
||||
int index = mD3DRenderDeviceComboBox->findText(getConfigValue("Rendering Device", mDirect3DRenderSystem));
|
||||
if ( index != -1) {
|
||||
mD3DRenderDeviceComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
index = mD3DAntiAliasingComboBox->findText(getConfigValue("FSAA", mDirect3DRenderSystem));
|
||||
if ( index != -1) {
|
||||
mD3DAntiAliasingComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
index = mD3DFloatingPointComboBox->findText(getConfigValue("Floating-point mode", mDirect3DRenderSystem));
|
||||
if ( index != -1) {
|
||||
mD3DFloatingPointComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
index = mD3DResolutionComboBox->findText(getConfigValue("Video Mode", mDirect3DRenderSystem));
|
||||
if ( index != -1) {
|
||||
mD3DResolutionComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
if (getConfigValue("Allow NVPerfHUD", mDirect3DRenderSystem) == QLatin1String("Yes")) {
|
||||
mD3DNvPerfCheckBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
|
||||
if (getConfigValue("VSync", mDirect3DRenderSystem) == QLatin1String("Yes")) {
|
||||
mD3DVSyncCheckBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
|
||||
if (getConfigValue("Full Screen", mDirect3DRenderSystem) == QLatin1String("Yes")) {
|
||||
mD3DFullScreenCheckBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
std::string resolution = boost::lexical_cast<std::string>(Settings::Manager::getInt("resolution x", "Video"))
|
||||
+ " x " + boost::lexical_cast<std::string>(Settings::Manager::getInt("resolution y", "Video"));
|
||||
int resIndex = mResolutionComboBox->findText(QString::fromStdString(resolution));
|
||||
if (resIndex != -1)
|
||||
mResolutionComboBox->setCurrentIndex(resIndex);
|
||||
}
|
||||
|
||||
void GraphicsPage::writeConfig()
|
||||
{
|
||||
mOgre->setRenderSystem(mSelectedRenderSystem);
|
||||
Settings::Manager::setBool("vsync", "Video", mVSyncCheckBox->checkState());
|
||||
Settings::Manager::setBool("fullscreen", "Video", mFullScreenCheckBox->checkState());
|
||||
Settings::Manager::setString("antialiasing", "Video", mAntiAliasingComboBox->currentText().toStdString());
|
||||
Settings::Manager::setString("render system", "Video", mRendererComboBox->currentText().toStdString());
|
||||
|
||||
if (mDirect3DRenderSystem) {
|
||||
// Nvidia Performance HUD
|
||||
if (mD3DNvPerfCheckBox->checkState() == Qt::Checked) {
|
||||
mDirect3DRenderSystem->setConfigOption("Allow NVPerfHUD", "Yes");
|
||||
} else {
|
||||
mDirect3DRenderSystem->setConfigOption("Allow NVPerfHUD", "No");
|
||||
}
|
||||
|
||||
// Antialiasing
|
||||
mDirect3DRenderSystem->setConfigOption("FSAA", mD3DAntiAliasingComboBox->currentText().toStdString());
|
||||
|
||||
// Full screen
|
||||
if (mD3DFullScreenCheckBox->checkState() == Qt::Checked) {
|
||||
mDirect3DRenderSystem->setConfigOption("Full Screen", "Yes");
|
||||
} else {
|
||||
mDirect3DRenderSystem->setConfigOption("Full Screen", "No");
|
||||
}
|
||||
|
||||
// Rendering device
|
||||
mDirect3DRenderSystem->setConfigOption("Rendering Device", mD3DRenderDeviceComboBox->currentText().toStdString());
|
||||
|
||||
// VSync
|
||||
if (mD3DVSyncCheckBox->checkState() == Qt::Checked) {
|
||||
mDirect3DRenderSystem->setConfigOption("VSync", "Yes");
|
||||
} else {
|
||||
mDirect3DRenderSystem->setConfigOption("VSync", "No");
|
||||
}
|
||||
|
||||
// Resolution
|
||||
mDirect3DRenderSystem->setConfigOption("Video Mode", mD3DResolutionComboBox->currentText().toStdString());
|
||||
}
|
||||
|
||||
if (mOpenGLRenderSystem) {
|
||||
// Display Frequency
|
||||
mOpenGLRenderSystem->setConfigOption("Display Frequency", mOGLFrequencyComboBox->currentText().toStdString());
|
||||
|
||||
// Antialiasing
|
||||
mOpenGLRenderSystem->setConfigOption("FSAA", mOGLAntiAliasingComboBox->currentText().toStdString());
|
||||
|
||||
// Full screen
|
||||
if (mOGLFullScreenCheckBox->checkState() == Qt::Checked) {
|
||||
mOpenGLRenderSystem->setConfigOption("Full Screen", "Yes");
|
||||
} else {
|
||||
mOpenGLRenderSystem->setConfigOption("Full Screen", "No");
|
||||
}
|
||||
|
||||
// RTT mode
|
||||
mOpenGLRenderSystem->setConfigOption("RTT Preferred Mode", mOGLRTTComboBox->currentText().toStdString());
|
||||
|
||||
// VSync
|
||||
if (mOGLVSyncCheckBox->checkState() == Qt::Checked) {
|
||||
mOpenGLRenderSystem->setConfigOption("VSync", "Yes");
|
||||
} else {
|
||||
mOpenGLRenderSystem->setConfigOption("VSync", "No");
|
||||
}
|
||||
|
||||
// Resolution
|
||||
mOpenGLRenderSystem->setConfigOption("Video Mode", mOGLResolutionComboBox->currentText().toStdString());
|
||||
}
|
||||
|
||||
// Now we validate the options
|
||||
QString ogreError = QString::fromStdString(mSelectedRenderSystem->validateConfigOptions());
|
||||
|
||||
if (!ogreError.isEmpty()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error validating Ogre configuration");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>A problem occured while validating the graphics options</b><br><br> \
|
||||
The graphics options could not be saved.<br><br> \
|
||||
Press \"Show Details...\" for more information.<br>"));
|
||||
msgBox.setDetailedText(ogreError);
|
||||
msgBox.exec();
|
||||
|
||||
Ogre::LogManager::getSingletonPtr()->logMessage( "Caught exception in validateConfigOptions");
|
||||
|
||||
qCritical("Error validating configuration");
|
||||
|
||||
qApp->exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the settings to the config file
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
mOgre->saveConfig();
|
||||
}
|
||||
catch(Ogre::Exception &ex)
|
||||
{
|
||||
QString ogreError = QString::fromStdString(ex.getFullDescription().c_str());
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error writing Ogre configuration file");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not write the graphics configuration</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br><br> \
|
||||
Press \"Show Details...\" for more information.<br>"));
|
||||
msgBox.setDetailedText(ogreError);
|
||||
msgBox.exec();
|
||||
|
||||
qCritical("Error saving Ogre configuration, the error reported was:\n %s", qPrintable(ogreError));
|
||||
|
||||
qApp->exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString GraphicsPage::getConfigValue(const QString &key, Ogre::RenderSystem *renderer)
|
||||
{
|
||||
QString result;
|
||||
|
||||
mOgreConfig->beginGroup(renderer->getName().c_str());
|
||||
result = mOgreConfig->value(key).toString();
|
||||
mOgreConfig->endGroup();
|
||||
|
||||
return result;
|
||||
// parse resolution x and y from a string like "800 x 600"
|
||||
QString resolution = mResolutionComboBox->currentText();
|
||||
QStringList tokens = resolution.split(" ", QString::SkipEmptyParts);
|
||||
int resX = boost::lexical_cast<int>(tokens.at(0).toStdString());
|
||||
int resY = boost::lexical_cast<int>(tokens.at(2).toStdString());
|
||||
Settings::Manager::setInt("resolution x", "Video", resX);
|
||||
Settings::Manager::setInt("resolution y", "Video", resY);
|
||||
}
|
||||
|
||||
QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer)
|
||||
|
@ -484,7 +219,48 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy
|
|||
{
|
||||
|
||||
if (strcmp (key.toStdString().c_str(), i->first.c_str()) == 0)
|
||||
result << QString::fromStdString((*opt_it).c_str()).simplified();
|
||||
{
|
||||
if (key == "FSAA" && *opt_it == "0")
|
||||
result << QString("none");
|
||||
else
|
||||
result << ((key == "FSAA") ? QString("MSAA ") : QString("")) + QString::fromStdString((*opt_it).c_str()).simplified();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer)
|
||||
{
|
||||
QString key ("Video Mode");
|
||||
QStringList result;
|
||||
|
||||
uint row = 0;
|
||||
Ogre::ConfigOptionMap options = renderer->getConfigOptions();
|
||||
|
||||
for (Ogre::ConfigOptionMap::iterator i = options.begin (); i != options.end (); i++, row++)
|
||||
{
|
||||
if (key.toStdString() != i->first)
|
||||
continue;
|
||||
|
||||
Ogre::StringVector::iterator opt_it;
|
||||
uint idx = 0;
|
||||
for (opt_it = i->second.possibleValues.begin ();
|
||||
opt_it != i->second.possibleValues.end (); opt_it++, idx++)
|
||||
{
|
||||
QString qval = QString::fromStdString(*opt_it).simplified();
|
||||
// remove extra tokens after the resolution (for example bpp, can be there or not depending on rendersystem)
|
||||
QStringList tokens = qval.split(" ", QString::SkipEmptyParts);
|
||||
assert (tokens.size() >= 3);
|
||||
QString resolutionStr = tokens.at(0) + QString(" x ") + tokens.at(2);
|
||||
{
|
||||
|
||||
// do not add duplicate resolutions
|
||||
if (!result.contains(resolutionStr))
|
||||
result << resolutionStr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -494,15 +270,11 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy
|
|||
|
||||
void GraphicsPage::rendererChanged(const QString &renderer)
|
||||
{
|
||||
if (renderer.contains("Direct3D")) {
|
||||
mRendererStackedWidget->setCurrentIndex(1);
|
||||
mDisplayStackedWidget->setCurrentIndex(1);
|
||||
}
|
||||
|
||||
if (renderer.contains("OpenGL")) {
|
||||
mRendererStackedWidget->setCurrentIndex(0);
|
||||
mDisplayStackedWidget->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString());
|
||||
|
||||
mAntiAliasingComboBox->clear();
|
||||
mResolutionComboBox->clear();
|
||||
|
||||
mAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||
mResolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem));
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ class GraphicsPage : public QWidget
|
|||
public:
|
||||
GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent = 0);
|
||||
|
||||
bool setupOgre();
|
||||
void writeConfig();
|
||||
|
||||
public slots:
|
||||
|
@ -49,38 +50,19 @@ private:
|
|||
|
||||
QComboBox *mRendererComboBox;
|
||||
|
||||
QStackedWidget *mRendererStackedWidget;
|
||||
QStackedWidget *mDisplayStackedWidget;
|
||||
|
||||
// OpenGL
|
||||
QComboBox *mOGLRTTComboBox;
|
||||
QComboBox *mOGLAntiAliasingComboBox;
|
||||
QComboBox *mOGLResolutionComboBox;
|
||||
QComboBox *mOGLFrequencyComboBox;
|
||||
|
||||
QCheckBox *mOGLVSyncCheckBox;
|
||||
QCheckBox *mOGLFullScreenCheckBox;
|
||||
|
||||
// Direct3D
|
||||
QComboBox *mD3DRenderDeviceComboBox;
|
||||
QComboBox *mD3DAntiAliasingComboBox;
|
||||
QComboBox *mD3DFloatingPointComboBox;
|
||||
QComboBox *mD3DResolutionComboBox;
|
||||
|
||||
QCheckBox *mD3DNvPerfCheckBox;
|
||||
QCheckBox *mD3DVSyncCheckBox;
|
||||
QCheckBox *mD3DFullScreenCheckBox;
|
||||
|
||||
QSettings *mOgreConfig;
|
||||
QComboBox *mAntiAliasingComboBox;
|
||||
QComboBox *mResolutionComboBox;
|
||||
QCheckBox *mVSyncCheckBox;
|
||||
QCheckBox *mFullScreenCheckBox;
|
||||
|
||||
Files::ConfigurationManager &mCfgMgr;
|
||||
|
||||
QString getConfigValue(const QString &key, Ogre::RenderSystem *renderer);
|
||||
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
||||
QStringList getAvailableResolutions(Ogre::RenderSystem *renderer);
|
||||
|
||||
void createPages();
|
||||
void setupConfig();
|
||||
void setupOgre();
|
||||
void readConfig();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2007 Trolltech ASA <info@trolltech.com>
|
||||
**
|
||||
** Use, modification and distribution is allowed without limitation,
|
||||
** warranty, liability or support of any kind.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "lineedit.hpp"
|
||||
#include <QToolButton>
|
||||
#include <QStyle>
|
||||
|
@ -14,33 +5,33 @@
|
|||
LineEdit::LineEdit(QWidget *parent)
|
||||
: QLineEdit(parent)
|
||||
{
|
||||
clearButton = new QToolButton(this);
|
||||
mClearButton = new QToolButton(this);
|
||||
QPixmap pixmap(":images/clear.png");
|
||||
clearButton->setIcon(QIcon(pixmap));
|
||||
clearButton->setIconSize(pixmap.size());
|
||||
clearButton->setCursor(Qt::ArrowCursor);
|
||||
clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
||||
clearButton->hide();
|
||||
connect(clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
||||
mClearButton->setIcon(QIcon(pixmap));
|
||||
mClearButton->setIconSize(pixmap.size());
|
||||
mClearButton->setCursor(Qt::ArrowCursor);
|
||||
mClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
||||
mClearButton->hide();
|
||||
connect(mClearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
||||
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&)));
|
||||
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||
setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(clearButton->sizeHint().width() + frameWidth + 1));
|
||||
setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1));
|
||||
QSize msz = minimumSizeHint();
|
||||
setMinimumSize(qMax(msz.width(), clearButton->sizeHint().height() + frameWidth * 2 + 2),
|
||||
qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2));
|
||||
setMinimumSize(qMax(msz.width(), mClearButton->sizeHint().height() + frameWidth * 2 + 2),
|
||||
qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2));
|
||||
}
|
||||
|
||||
void LineEdit::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
QSize sz = clearButton->sizeHint();
|
||||
QSize sz = mClearButton->sizeHint();
|
||||
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||
clearButton->move(rect().right() - frameWidth - sz.width(),
|
||||
mClearButton->move(rect().right() - frameWidth - sz.width(),
|
||||
(rect().bottom() + 1 - sz.height())/2);
|
||||
}
|
||||
|
||||
void LineEdit::updateCloseButton(const QString& text)
|
||||
{
|
||||
clearButton->setVisible(!text.isEmpty());
|
||||
mClearButton->setVisible(!text.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ private slots:
|
|||
void updateCloseButton(const QString &text);
|
||||
|
||||
private:
|
||||
QToolButton *clearButton;
|
||||
QToolButton *mClearButton;
|
||||
};
|
||||
|
||||
#endif // LIENEDIT_H
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "maindialog.hpp"
|
||||
|
||||
|
@ -31,8 +30,14 @@ int main(int argc, char *argv[])
|
|||
|
||||
QDir::setCurrent(dir.absolutePath());
|
||||
|
||||
MainDialog dialog;
|
||||
return dialog.exec();
|
||||
MainDialog mainWin;
|
||||
|
||||
if (mainWin.setup()) {
|
||||
|
||||
mainWin.show();
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
|
||||
MainDialog::MainDialog()
|
||||
{
|
||||
mIconWidget = new QListWidget;
|
||||
QWidget *centralWidget = new QWidget(this);
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
mIconWidget = new QListWidget(centralWidget);
|
||||
mIconWidget->setObjectName("IconWidget");
|
||||
mIconWidget->setViewMode(QListView::IconMode);
|
||||
mIconWidget->setWrapping(false);
|
||||
|
@ -21,7 +24,7 @@ MainDialog::MainDialog()
|
|||
mIconWidget->setCurrentRow(0);
|
||||
mIconWidget->setFlow(QListView::LeftToRight);
|
||||
|
||||
QGroupBox *groupBox = new QGroupBox(this);
|
||||
QGroupBox *groupBox = new QGroupBox(centralWidget);
|
||||
QVBoxLayout *groupLayout = new QVBoxLayout(groupBox);
|
||||
|
||||
mPagesWidget = new QStackedWidget(groupBox);
|
||||
|
@ -29,16 +32,15 @@ MainDialog::MainDialog()
|
|||
|
||||
QPushButton *playButton = new QPushButton(tr("Play"));
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(centralWidget);
|
||||
buttonBox->setStandardButtons(QDialogButtonBox::Close);
|
||||
buttonBox->addButton(playButton, QDialogButtonBox::AcceptRole);
|
||||
|
||||
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
||||
QVBoxLayout *dialogLayout = new QVBoxLayout(centralWidget);
|
||||
dialogLayout->addWidget(mIconWidget);
|
||||
dialogLayout->addWidget(groupBox);
|
||||
dialogLayout->addWidget(buttonBox);
|
||||
|
||||
|
||||
setWindowTitle(tr("OpenMW Launcher"));
|
||||
setWindowIcon(QIcon(":/images/openmw.png"));
|
||||
// Remove what's this? button
|
||||
|
@ -77,7 +79,6 @@ MainDialog::MainDialog()
|
|||
qApp->setStyleSheet(styleSheet);
|
||||
file.close();
|
||||
|
||||
|
||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(play()));
|
||||
|
||||
|
@ -148,6 +149,53 @@ void MainDialog::createPages()
|
|||
|
||||
}
|
||||
|
||||
|
||||
bool MainDialog::setup()
|
||||
{
|
||||
// Create the settings manager and load default settings file
|
||||
const std::string localdefault = (mCfgMgr.getLocalPath() / "settings-default.cfg").string();
|
||||
const std::string globaldefault = (mCfgMgr.getGlobalPath() / "settings-default.cfg").string();
|
||||
|
||||
// prefer local
|
||||
if (boost::filesystem::exists(localdefault)) {
|
||||
mSettings.loadDefault(localdefault);
|
||||
} else if (boost::filesystem::exists(globaldefault)) {
|
||||
mSettings.loadDefault(globaldefault);
|
||||
} else {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error reading OpenMW configuration file");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not find %0</b><br><br> \
|
||||
The problem may be due to an incomplete installation of OpenMW.<br> \
|
||||
Reinstalling OpenMW may resolve the problem.").arg(QString::fromStdString(globaldefault)));
|
||||
msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
|
||||
// load user settings if they exist, otherwise just load the default settings as user settings
|
||||
const std::string settingspath = (mCfgMgr.getUserPath() / "settings.cfg").string();
|
||||
|
||||
if (boost::filesystem::exists(settingspath))
|
||||
mSettings.loadUser(settingspath);
|
||||
else if (boost::filesystem::exists(localdefault))
|
||||
mSettings.loadUser(localdefault);
|
||||
else if (boost::filesystem::exists(globaldefault))
|
||||
mSettings.loadUser(globaldefault);
|
||||
|
||||
// Setup the Graphics page
|
||||
if (!mGraphicsPage->setupOgre()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Setup the Data Files page
|
||||
if (!mDataFilesPage->setupDataFiles()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainDialog::profileChanged(int index)
|
||||
{
|
||||
// Just to be sure, should always have a selection
|
||||
|
@ -178,6 +226,12 @@ void MainDialog::closeEvent(QCloseEvent *event)
|
|||
// Now write all config files
|
||||
mDataFilesPage->writeConfig();
|
||||
mGraphicsPage->writeConfig();
|
||||
|
||||
// Save user settings
|
||||
const std::string settingspath = (mCfgMgr.getUserPath() / "settings.cfg").string();
|
||||
qDebug() << QString::fromStdString(settingspath);
|
||||
mSettings.saveUser(settingspath);
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
|
@ -219,7 +273,7 @@ void MainDialog::play()
|
|||
if (!info.isExecutable()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error starting OpenMW");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not start OpenMW</b><br><br> \
|
||||
The OpenMW application is not executable.<br> \
|
||||
|
@ -243,6 +297,7 @@ void MainDialog::play()
|
|||
|
||||
return;
|
||||
} else {
|
||||
close();
|
||||
qApp->quit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#ifndef MAINDIALOG_H
|
||||
#define MAINDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMainWindow>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
|
@ -16,7 +17,7 @@ class PlayPage;
|
|||
class GraphicsPage;
|
||||
class DataFilesPage;
|
||||
|
||||
class MainDialog : public QDialog
|
||||
class MainDialog : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -27,6 +28,7 @@ public slots:
|
|||
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
|
||||
void play();
|
||||
void profileChanged(int index);
|
||||
bool setup();
|
||||
|
||||
private:
|
||||
void createIcons();
|
||||
|
@ -41,6 +43,7 @@ private:
|
|||
DataFilesPage *mDataFilesPage;
|
||||
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
Settings::Manager mSettings;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
@ -8,7 +8,9 @@
|
|||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
MwIniImporter::MwIniImporter() {
|
||||
MwIniImporter::MwIniImporter()
|
||||
: mVerbose(false)
|
||||
{
|
||||
const char *map[][2] =
|
||||
{
|
||||
{ "fps", "General:Show FPS" },
|
||||
|
@ -124,9 +126,9 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) {
|
|||
void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) {
|
||||
multistrmap::iterator cfgIt;
|
||||
multistrmap::iterator iniIt;
|
||||
for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); it++) {
|
||||
for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) {
|
||||
if((iniIt = ini.find(it->second)) != ini.end()) {
|
||||
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) {
|
||||
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
|
||||
cfg.erase(it->first);
|
||||
insertMultistrmap(cfg, it->first, *vc);
|
||||
}
|
||||
|
@ -139,9 +141,9 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) {
|
|||
|
||||
multistrmap::iterator cfgIt;
|
||||
multistrmap::iterator iniIt;
|
||||
for(std::vector<std::string>::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); it++) {
|
||||
for(std::vector<std::string>::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) {
|
||||
if((iniIt = ini.find(*it)) != ini.end()) {
|
||||
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) {
|
||||
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
|
||||
std::string value(*it);
|
||||
std::replace( value.begin(), value.end(), ' ', '_' );
|
||||
std::replace( value.begin(), value.end(), ':', '_' );
|
||||
|
@ -176,7 +178,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
|||
break;
|
||||
}
|
||||
|
||||
for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); entry++) {
|
||||
for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
||||
std::string filetype(entry->substr(entry->length()-4, 3));
|
||||
std::transform(filetype.begin(), filetype.end(), filetype.begin(), ::tolower);
|
||||
|
||||
|
@ -194,22 +196,22 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
|||
cfg.erase("master");
|
||||
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("master", std::vector<std::string>() ) );
|
||||
|
||||
for(std::vector<std::string>::iterator it=esmFiles.begin(); it!=esmFiles.end(); it++) {
|
||||
for(std::vector<std::string>::iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) {
|
||||
cfg["master"].push_back(*it);
|
||||
}
|
||||
|
||||
cfg.erase("plugin");
|
||||
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("plugin", std::vector<std::string>() ) );
|
||||
|
||||
for(std::vector<std::string>::iterator it=espFiles.begin(); it!=espFiles.end(); it++) {
|
||||
for(std::vector<std::string>::iterator it=espFiles.begin(); it!=espFiles.end(); ++it) {
|
||||
cfg["plugin"].push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg) {
|
||||
|
||||
for(multistrmap::iterator it=cfg.begin(); it != cfg.end(); it++) {
|
||||
for(std::vector<std::string>::iterator entry=it->second.begin(); entry != it->second.end(); entry++) {
|
||||
for(multistrmap::iterator it=cfg.begin(); it != cfg.end(); ++it) {
|
||||
for(std::vector<std::string>::iterator entry=it->second.begin(); entry != it->second.end(); ++entry) {
|
||||
out << (it->first) << "=" << (*entry) << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
|
|||
add_openmw_dir (mwrender
|
||||
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
|
||||
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows shaderhelper
|
||||
compositors
|
||||
)
|
||||
|
||||
add_openmw_dir (mwinput
|
||||
|
@ -23,10 +24,11 @@ add_openmw_dir (mwinput
|
|||
)
|
||||
|
||||
add_openmw_dir (mwgui
|
||||
layouts text_input widgets race class birth review window_manager console dialogue
|
||||
text_input widgets race class birth review window_manager console dialogue
|
||||
dialogue_history window_base stats_window messagebox journalwindow charactercreation
|
||||
map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
|
||||
formatting
|
||||
formatting inventorywindow container hud countdialog tradewindow settingswindow
|
||||
confirmationdialog alchemywindow referenceinterface spellwindow
|
||||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
|
@ -47,7 +49,8 @@ add_openmw_dir (mwsound
|
|||
add_openmw_dir (mwworld
|
||||
refdata world physicssystem scene globals class action nullaction actionteleport
|
||||
containerstore actiontalk actiontake manualref player cellfunctors
|
||||
cells localscripts customdata weather inventorystore ptr actionread
|
||||
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
||||
actionequip timestamp actionalchemy
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
|
@ -57,6 +60,7 @@ add_openmw_dir (mwclass
|
|||
|
||||
add_openmw_dir (mwmechanics
|
||||
mechanicsmanager stat creaturestats magiceffects movement actors drawstate spells
|
||||
activespells
|
||||
)
|
||||
|
||||
add_openmw_dir (mwbase
|
||||
|
|
|
@ -105,7 +105,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
|||
// frame.
|
||||
|
||||
// passing of time
|
||||
if (MWBase::Environment::get().getWindowManager()->getMode()==MWGui::GM_Game)
|
||||
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
MWBase::Environment::get().getWorld()->advanceTime (
|
||||
mEnvironment.getFrameDuration()*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600);
|
||||
|
||||
|
@ -116,9 +116,9 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
|||
// update actors
|
||||
std::vector<std::pair<std::string, Ogre::Vector3> > movement;
|
||||
MWBase::Environment::get().getMechanicsManager()->update (movement, mEnvironment.getFrameDuration(),
|
||||
MWBase::Environment::get().getWindowManager()->getMode()!=MWGui::GM_Game);
|
||||
MWBase::Environment::get().getWindowManager()->isGuiMode());
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getMode()==MWGui::GM_Game)
|
||||
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration());
|
||||
|
||||
// update world
|
||||
|
@ -126,9 +126,9 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
|||
|
||||
// update GUI
|
||||
Ogre::RenderWindow* window = mOgre->getWindow();
|
||||
MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(),
|
||||
window->getTriangleCount(),
|
||||
window->getBatchCount());
|
||||
unsigned int tri, batch;
|
||||
MWBase::Environment::get().getWorld()->getTriangleBatchCount(tri, batch);
|
||||
MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(), tri, batch);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->onFrame(evt.timeSinceLastFrame);
|
||||
}
|
||||
|
@ -268,15 +268,6 @@ void OMW::Engine::go()
|
|||
|
||||
mOgre = new OEngine::Render::OgreRenderer;
|
||||
|
||||
//we need to ensure the path to the configuration exists before creating an
|
||||
//instance of ogre root so that Ogre doesn't raise an exception when trying to
|
||||
//access it
|
||||
const boost::filesystem::path configPath = mCfgMgr.getOgreConfigPath().parent_path();
|
||||
if ( !boost::filesystem::exists(configPath) )
|
||||
{
|
||||
boost::filesystem::create_directories(configPath);
|
||||
}
|
||||
|
||||
// Create the settings manager and load default settings file
|
||||
Settings::Manager settings;
|
||||
const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg";
|
||||
|
@ -308,10 +299,20 @@ void OMW::Engine::go()
|
|||
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"))
|
||||
nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg");
|
||||
|
||||
mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()),
|
||||
mCfgMgr.getOgreConfigPath().string(),
|
||||
std::string renderSystem = settings.getString("render system", "Video");
|
||||
if (renderSystem == "")
|
||||
{
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||
renderSystem = "Direct3D9 Rendering Subsystem";
|
||||
#else
|
||||
renderSystem = "OpenGL Rendering Subsystem";
|
||||
#endif
|
||||
}
|
||||
mOgre->configure(
|
||||
mCfgMgr.getLogPath().string(),
|
||||
mCfgMgr.getPluginsConfigPath().string(), false);
|
||||
mCfgMgr.getPluginsConfigPath().string(),
|
||||
renderSystem,
|
||||
false);
|
||||
|
||||
// This has to be added BEFORE MyGUI is initialized, as it needs
|
||||
// to find core.xml here.
|
||||
|
@ -325,7 +326,14 @@ void OMW::Engine::go()
|
|||
addZipResource(mResDir / "mygui" / "Obliviontt.zip");
|
||||
|
||||
// Create the window
|
||||
mOgre->createWindow("OpenMW");
|
||||
OEngine::Render::WindowSettings windowSettings;
|
||||
windowSettings.fullscreen = settings.getBool("fullscreen", "Video");
|
||||
windowSettings.window_x = settings.getInt("resolution x", "Video");
|
||||
windowSettings.window_y = settings.getInt("resolution y", "Video");
|
||||
windowSettings.vsync = settings.getBool("vsync", "Video");
|
||||
std::string aa = settings.getString("antialiasing", "Video");
|
||||
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
|
||||
mOgre->createWindow("OpenMW", windowSettings);
|
||||
|
||||
loadBSA();
|
||||
|
||||
|
@ -413,7 +421,7 @@ void OMW::Engine::go()
|
|||
|
||||
void OMW::Engine::activate()
|
||||
{
|
||||
if (MWBase::Environment::get().getWindowManager()->getMode()!=MWGui::GM_Game)
|
||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
return;
|
||||
|
||||
std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle();
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Activator>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
|
||||
std::string text;
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionalchemy.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
@ -100,6 +101,14 @@ namespace MWClass
|
|||
return std::string("Item Apparatus Down");
|
||||
}
|
||||
|
||||
std::string Apparatus::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Apparatus>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Apparatus::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
|
||||
|
@ -114,7 +123,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Apparatus>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -132,4 +141,10 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Apparatus::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionAlchemy());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,13 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
|
@ -198,6 +199,14 @@ namespace MWClass
|
|||
return std::string("Item Armor Heavy Down");
|
||||
}
|
||||
|
||||
std::string Armor::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Armor>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Armor::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
||||
|
@ -212,7 +221,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Armor>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
std::string text;
|
||||
|
@ -248,4 +257,19 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string Armor::getEnchantment (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Armor>();
|
||||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,17 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,14 @@ namespace MWClass
|
|||
return std::string("Item Book Down");
|
||||
}
|
||||
|
||||
std::string Book::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Book>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Book::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
|
@ -111,7 +119,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Book>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -132,4 +140,18 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string Book::getEnchantment (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Book>();
|
||||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,15 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
|
@ -166,6 +167,14 @@ namespace MWClass
|
|||
return std::string("Item Clothes Down");
|
||||
}
|
||||
|
||||
std::string Clothing::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Clothing>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Clothing::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
||||
|
@ -180,7 +189,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Clothing>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -201,4 +210,19 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string Clothing::getEnchantment (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Clothing>();
|
||||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,16 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
#include "../mwworld/actionopen.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
|
@ -86,6 +87,7 @@ namespace MWClass
|
|||
const std::string lockedSound = "LockedChest";
|
||||
const std::string trapActivationSound = "Disarm Trap Fail";
|
||||
|
||||
|
||||
if (ptr.getCellRef().lockLevel>0)
|
||||
{
|
||||
// TODO check for key
|
||||
|
@ -99,7 +101,8 @@ namespace MWClass
|
|||
if(ptr.getCellRef().trap.empty())
|
||||
{
|
||||
// Not trapped, Inventory GUI goes here
|
||||
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||
//return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionOpen(ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -176,4 +179,30 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
float Container::getCapacity (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Container>();
|
||||
|
||||
return ref->base->weight;
|
||||
}
|
||||
|
||||
float Container::getEncumbrance (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return getContainerStore (ptr).getWeight();
|
||||
}
|
||||
|
||||
void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const
|
||||
{
|
||||
if (lockLevel<0)
|
||||
lockLevel = 0;
|
||||
|
||||
ptr.getCellRef().lockLevel = lockLevel;
|
||||
}
|
||||
|
||||
void Container::unlock (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ptr.getCellRef().lockLevel = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,20 @@ namespace MWClass
|
|||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
||||
///< Return total weight that fits into the object. Throws an exception, if the object can't
|
||||
/// hold other objects.
|
||||
|
||||
virtual float getEncumbrance (const MWWorld::Ptr& ptr) const;
|
||||
///< Returns total weight of objects inside this object (including modifications from magic
|
||||
/// effects). Throws an exception, if the object can't hold other objects.
|
||||
|
||||
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
|
||||
///< Lock object
|
||||
|
||||
virtual void unlock (const MWWorld::Ptr& ptr) const;
|
||||
///< Unlock object
|
||||
|
||||
static void registerSelf();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include "../mwmechanics/magiceffects.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
|
@ -56,7 +57,10 @@ namespace MWClass
|
|||
|
||||
data->mCreatureStats.mLevel = ref->base->data.level;
|
||||
|
||||
// \todo add initial container content
|
||||
data->mCreatureStats.mHello = ref->base->AI.hello;
|
||||
data->mCreatureStats.mFight = ref->base->AI.fight;
|
||||
data->mCreatureStats.mFlee = ref->base->AI.flee;
|
||||
data->mCreatureStats.mAlarm = ref->base->AI.alarm;
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
|
@ -82,24 +86,15 @@ namespace MWClass
|
|||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Creature>();
|
||||
|
||||
|
||||
const std::string &model = ref->base->model;
|
||||
assert (ref->base != NULL);
|
||||
if(!model.empty()){
|
||||
physics.insertActorPhysics(ptr, "meshes\\" + model);
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::enable (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
|
||||
}
|
||||
|
||||
void Creature::disable (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->removeActor (ptr);
|
||||
}
|
||||
|
||||
std::string Creature::getName (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
|
||||
|
@ -166,4 +161,26 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
float Creature::getCapacity (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
return stats.mAttributes[0].getModified()*5;
|
||||
}
|
||||
|
||||
float Creature::getEncumbrance (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
float weight = getContainerStore (ptr).getWeight();
|
||||
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
|
||||
weight -= stats.mMagicEffects.get (MWMechanics::EffectKey (8)).mMagnitude; // feather
|
||||
|
||||
weight += stats.mMagicEffects.get (MWMechanics::EffectKey (7)).mMagnitude; // burden
|
||||
|
||||
if (weight<0)
|
||||
weight = 0;
|
||||
|
||||
return weight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,6 @@ namespace MWClass
|
|||
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
|
||||
|
||||
virtual void enable (const MWWorld::Ptr& ptr) const;
|
||||
///< Enable reference; only does the non-rendering part
|
||||
|
||||
virtual void disable (const MWWorld::Ptr& ptr) const;
|
||||
///< Enable reference; only does the non-rendering part
|
||||
|
||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
/// can return an empty string.
|
||||
|
@ -52,6 +46,14 @@ namespace MWClass
|
|||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
||||
///< Return total weight that fits into the object. Throws an exception, if the object can't
|
||||
/// hold other objects.
|
||||
|
||||
virtual float getEncumbrance (const MWWorld::Ptr& ptr) const;
|
||||
///< Returns total weight of objects inside this object (including modifications from magic
|
||||
/// effects). Throws an exception, if the object can't hold other objects.
|
||||
|
||||
static void registerSelf();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -98,6 +98,14 @@ namespace MWClass
|
|||
return std::string("Item Ingredient Down");
|
||||
}
|
||||
|
||||
std::string Ingredient::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Ingredient>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Ingredient::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
|
||||
|
@ -112,7 +120,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Ingredient>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -127,6 +135,19 @@ namespace MWClass
|
|||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
MWGui::Widgets::SpellEffectList list;
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
if (ref->base->data.effectID[i] < 0)
|
||||
continue;
|
||||
MWGui::Widgets::SpellEffectParams params;
|
||||
params.mEffectID = ref->base->data.effectID[i];
|
||||
params.mAttribute = ref->base->data.attributes[i];
|
||||
params.mSkill = ref->base->data.skills[i];
|
||||
list.push_back(params);
|
||||
}
|
||||
info.effects = list;
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
|
|
|
@ -41,6 +41,9 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
@ -55,12 +56,6 @@ namespace MWClass
|
|||
if(!model.empty()){
|
||||
physics.insertObjectPhysics(ptr, "meshes\\" + model);
|
||||
}
|
||||
}
|
||||
|
||||
void Light::enable (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Light>();
|
||||
|
||||
if (!ref->base->sound.empty())
|
||||
{
|
||||
|
@ -140,6 +135,15 @@ namespace MWClass
|
|||
return std::string("Item Misc Down");
|
||||
}
|
||||
|
||||
|
||||
std::string Light::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Light>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Light::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
||||
|
@ -154,7 +158,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Light>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -173,4 +177,11 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Light::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,6 @@ namespace MWClass
|
|||
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
|
||||
|
||||
virtual void enable (const MWWorld::Ptr& ptr) const;
|
||||
///< Enable reference; only does the non-rendering part
|
||||
/// \attention This is not the same as the script instruction with the same name. References
|
||||
/// should only be enabled while in an active cell.
|
||||
|
||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
/// can return an empty string.
|
||||
|
@ -50,6 +45,13 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
|
@ -110,6 +111,14 @@ namespace MWClass
|
|||
return std::string("Item Lockpick Down");
|
||||
}
|
||||
|
||||
std::string Lockpick::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
|
||||
|
@ -124,7 +133,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Tool>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -147,4 +156,11 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Lockpick::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,13 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include "misc.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/esm/loadmisc.hpp>
|
||||
|
||||
#include <components/esm_store/cell_store.hpp>
|
||||
|
@ -116,6 +118,14 @@ namespace MWClass
|
|||
return std::string("Item Misc Down");
|
||||
}
|
||||
|
||||
std::string Miscellaneous::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Miscellaneous::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
||||
|
@ -130,11 +140,24 @@ namespace MWClass
|
|||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
int count = ptr.getRefData().getCount();
|
||||
|
||||
bool isGold = (ref->base->name == store.gameSettings.search("sGold")->str);
|
||||
if (isGold && count == 1)
|
||||
count = ref->base->data.value;
|
||||
|
||||
std::string countString;
|
||||
if (!isGold)
|
||||
countString = MWGui::ToolTips::getCountString(count);
|
||||
else // gold displays its count also if it's 1.
|
||||
countString = " (" + boost::lexical_cast<std::string>(count) + ")";
|
||||
|
||||
info.caption = ref->base->name + countString;
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
if (ref->ref.soul != "")
|
||||
{
|
||||
const ESM::Creature *creature = store.creatures.search(ref->ref.soul);
|
||||
|
@ -143,9 +166,7 @@ namespace MWClass
|
|||
|
||||
std::string text;
|
||||
|
||||
if (ref->base->name == store.gameSettings.search("sGold")->str)
|
||||
info.caption += " (" + boost::lexical_cast<std::string>(ref->base->data.value) + ")";
|
||||
else
|
||||
if (!isGold)
|
||||
{
|
||||
text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight);
|
||||
text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str);
|
||||
|
|
|
@ -41,6 +41,9 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
|
@ -56,22 +58,24 @@ namespace MWClass
|
|||
// NPC stats
|
||||
if (!ref->base->faction.empty())
|
||||
{
|
||||
std::string faction = ref->base->faction;
|
||||
boost::algorithm::to_lower(faction);
|
||||
if(ref->base->npdt52.gold != -10)
|
||||
{
|
||||
data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt52.rank;
|
||||
data->mNpcStats.mFactionRank[faction] = (int)ref->base->npdt52.rank;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt12.rank;
|
||||
data->mNpcStats.mFactionRank[faction] = (int)ref->base->npdt12.rank;
|
||||
}
|
||||
}
|
||||
|
||||
// creature stats
|
||||
if(ref->base->npdt52.gold != -10)
|
||||
{
|
||||
for (int i=0; i<27; ++i)
|
||||
data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]);
|
||||
|
||||
// creature stats
|
||||
data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength);
|
||||
data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence);
|
||||
data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower);
|
||||
|
@ -88,10 +92,13 @@ namespace MWClass
|
|||
}
|
||||
else
|
||||
{
|
||||
//TODO: do something with npdt12 maybe:p
|
||||
/// \todo do something with npdt12 maybe:p
|
||||
}
|
||||
|
||||
// \todo add initial container content
|
||||
data->mCreatureStats.mHello = ref->base->AI.hello;
|
||||
data->mCreatureStats.mFight = ref->base->AI.fight;
|
||||
data->mCreatureStats.mFlee = ref->base->AI.flee;
|
||||
data->mCreatureStats.mAlarm = ref->base->AI.alarm;
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
|
@ -108,44 +115,27 @@ namespace MWClass
|
|||
|
||||
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||
{
|
||||
|
||||
|
||||
renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr));
|
||||
|
||||
}
|
||||
|
||||
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
|
||||
{
|
||||
|
||||
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::NPC>();
|
||||
|
||||
|
||||
assert (ref->base != NULL);
|
||||
std::string headID = ref->base->head;
|
||||
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
|
||||
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
|
||||
|
||||
|
||||
std::string smodel = "meshes\\base_anim.nif";
|
||||
if(beast)
|
||||
smodel = "meshes\\base_animkna.nif";
|
||||
physics.insertActorPhysics(ptr, smodel);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Npc::enable (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
|
||||
}
|
||||
|
||||
void Npc::disable (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->removeActor (ptr);
|
||||
}
|
||||
|
||||
std::string Npc::getName (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
|
||||
|
@ -325,4 +315,26 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
float Npc::getCapacity (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
return stats.mAttributes[0].getModified()*5;
|
||||
}
|
||||
|
||||
float Npc::getEncumbrance (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
float weight = getContainerStore (ptr).getWeight();
|
||||
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
|
||||
weight -= stats.mMagicEffects.get (MWMechanics::EffectKey (8)).mMagnitude; // feather
|
||||
|
||||
weight += stats.mMagicEffects.get (MWMechanics::EffectKey (7)).mMagnitude; // burden
|
||||
|
||||
if (weight<0)
|
||||
weight = 0;
|
||||
|
||||
return weight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,6 @@ namespace MWClass
|
|||
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
|
||||
|
||||
virtual void enable (const MWWorld::Ptr& ptr) const;
|
||||
///< Enable reference; only does the non-rendering part
|
||||
|
||||
virtual void disable (const MWWorld::Ptr& ptr) const;
|
||||
///< Enable reference; only does the non-rendering part
|
||||
|
||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
/// can return an empty string.
|
||||
|
@ -74,6 +68,14 @@ namespace MWClass
|
|||
///< Return desired movement vector (determined based on movement settings,
|
||||
/// stance and stats).
|
||||
|
||||
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
||||
///< Return total weight that fits into the object. Throws an exception, if the object can't
|
||||
/// hold other objects.
|
||||
|
||||
virtual float getEncumbrance (const MWWorld::Ptr& ptr) const;
|
||||
///< Returns total weight of objects inside this object (including modifications from magic
|
||||
/// effects). Throws an exception, if the object can't hold other objects.
|
||||
|
||||
static void registerSelf();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -100,6 +100,14 @@ namespace MWClass
|
|||
return std::string("Item Potion Down");
|
||||
}
|
||||
|
||||
std::string Potion::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Potion>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Potion::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
|
||||
|
@ -114,7 +122,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Potion>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -124,7 +132,7 @@ namespace MWClass
|
|||
text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight);
|
||||
text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str);
|
||||
|
||||
info.effects = &ref->base->effects;
|
||||
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->base->effects);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
|
|
|
@ -41,6 +41,9 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
|
@ -109,6 +110,14 @@ namespace MWClass
|
|||
return std::string("Item Probe Down");
|
||||
}
|
||||
|
||||
std::string Probe::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Probe>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Probe::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
|
||||
|
@ -123,7 +132,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Probe>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -146,4 +155,11 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Probe::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,13 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,14 @@ namespace MWClass
|
|||
return std::string("Item Repair Down");
|
||||
}
|
||||
|
||||
std::string Repair::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Repair>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Repair::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
|
||||
|
@ -113,7 +121,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Repair>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
std::string text;
|
||||
|
|
|
@ -41,6 +41,9 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
|
@ -250,6 +251,14 @@ namespace MWClass
|
|||
return std::string("Item Misc Down");
|
||||
}
|
||||
|
||||
std::string Weapon::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Weapon::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
||||
|
@ -264,7 +273,7 @@ namespace MWClass
|
|||
ptr.get<ESM::Weapon>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -339,4 +348,19 @@ namespace MWClass
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string Weapon::getEnchantment (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,17 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ namespace MWDialogue
|
|||
if(!NPCstats.mFactionRank.empty())
|
||||
{
|
||||
std::string NPCFaction = NPCstats.mFactionRank.begin()->first;
|
||||
if(PCstats.mFactionRank.find(NPCFaction) != PCstats.mFactionRank.end()) sameFaction = 1;
|
||||
if(PCstats.mFactionRank.find(toLower(NPCFaction)) != PCstats.mFactionRank.end()) sameFaction = 1;
|
||||
}
|
||||
if(!selectCompare<int,int>(comp,sameFaction,select.i)) return false;
|
||||
}
|
||||
|
@ -363,7 +363,7 @@ namespace MWDialogue
|
|||
int sum = 0;
|
||||
|
||||
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
|
||||
if (iter->getCellRef().refID==name)
|
||||
if (toLower(iter->getCellRef().refID) == toLower(name))
|
||||
sum += iter->getRefData().getCount();
|
||||
if(!selectCompare<int,int>(comp,sum,select.i)) return false;
|
||||
}
|
||||
|
@ -525,7 +525,7 @@ namespace MWDialogue
|
|||
|
||||
//MWWorld::Class npcClass = MWWorld::Class::get(actor);
|
||||
MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
|
||||
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.npcFaction);
|
||||
std::map<std::string,int>::iterator it = stats.mFactionRank.find(toLower(info.npcFaction));
|
||||
if(it!=stats.mFactionRank.end())
|
||||
{
|
||||
//check rank
|
||||
|
@ -542,7 +542,7 @@ namespace MWDialogue
|
|||
if(!info.pcFaction.empty())
|
||||
{
|
||||
MWMechanics::NpcStats stats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.pcFaction);
|
||||
std::map<std::string,int>::iterator it = stats.mFactionRank.find(toLower(info.pcFaction));
|
||||
if(it!=stats.mFactionRank.end())
|
||||
{
|
||||
//check rank
|
||||
|
@ -607,7 +607,7 @@ namespace MWDialogue
|
|||
void DialogueManager::parseText(std::string text)
|
||||
{
|
||||
std::list<std::string>::iterator it;
|
||||
for(it = actorKnownTopics.begin();it != actorKnownTopics.end();it++)
|
||||
for(it = actorKnownTopics.begin();it != actorKnownTopics.end();++it)
|
||||
{
|
||||
size_t pos = find_str_ci(text,*it,0);
|
||||
if(pos !=std::string::npos)
|
||||
|
@ -635,9 +635,9 @@ namespace MWDialogue
|
|||
actorKnownTopics.clear();
|
||||
|
||||
//initialise the GUI
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Dialogue);
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue);
|
||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
||||
win->startDialogue(MWWorld::Class::get (actor).getName (actor));
|
||||
win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor));
|
||||
|
||||
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
|
||||
updateTopics();
|
||||
|
@ -767,6 +767,36 @@ namespace MWDialogue
|
|||
}
|
||||
}
|
||||
|
||||
// check the available services of this actor
|
||||
int services = 0;
|
||||
if (mActor.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mActor.get<ESM::NPC>();
|
||||
if (ref->base->hasAI)
|
||||
services = ref->base->AI.services;
|
||||
}
|
||||
else if (mActor.getTypeName() == typeid(ESM::Creature).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mActor.get<ESM::Creature>();
|
||||
if (ref->base->hasAI)
|
||||
services = ref->base->AI.services;
|
||||
}
|
||||
|
||||
if (services & ESM::NPC::Weapon
|
||||
|| services & ESM::NPC::Armor
|
||||
|| services & ESM::NPC::Clothing
|
||||
|| services & ESM::NPC::Books
|
||||
|| services & ESM::NPC::Ingredients
|
||||
|| services & ESM::NPC::Picks
|
||||
|| services & ESM::NPC::Probes
|
||||
|| services & ESM::NPC::Lights
|
||||
|| services & ESM::NPC::Apparatus
|
||||
|| services & ESM::NPC::RepairItem
|
||||
|| services & ESM::NPC::Misc)
|
||||
win->setShowTrade(true);
|
||||
else
|
||||
win->setShowTrade(false);
|
||||
|
||||
// sort again, because the previous sort was case-sensitive
|
||||
keywordList.sort(stringCompareNoCase);
|
||||
win->setKeywords(keywordList);
|
||||
|
@ -813,7 +843,7 @@ namespace MWDialogue
|
|||
|
||||
void DialogueManager::goodbyeSelected()
|
||||
{
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game);
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
|
||||
}
|
||||
|
||||
void DialogueManager::questionAnswered(std::string answere)
|
||||
|
|
512
apps/openmw/mwgui/alchemywindow.cpp
Normal file
512
apps/openmw/mwgui/alchemywindow.cpp
Normal file
|
@ -0,0 +1,512 @@
|
|||
#include "alchemywindow.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string getIconPath(MWWorld::Ptr ptr)
|
||||
{
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(ptr).getInventoryIcon(ptr);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
AlchemyWindow::AlchemyWindow(WindowManager& parWindowManager)
|
||||
: WindowBase("openmw_alchemy_window_layout.xml", parWindowManager)
|
||||
, ContainerBase(0)
|
||||
{
|
||||
getWidget(mCreateButton, "CreateButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
getWidget(mIngredient1, "Ingredient1");
|
||||
getWidget(mIngredient2, "Ingredient2");
|
||||
getWidget(mIngredient3, "Ingredient3");
|
||||
getWidget(mIngredient4, "Ingredient4");
|
||||
getWidget(mApparatus1, "Apparatus1");
|
||||
getWidget(mApparatus2, "Apparatus2");
|
||||
getWidget(mApparatus3, "Apparatus3");
|
||||
getWidget(mApparatus4, "Apparatus4");
|
||||
getWidget(mEffectsBox, "CreatedEffects");
|
||||
getWidget(mNameEdit, "NameEdit");
|
||||
|
||||
mIngredient1->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
|
||||
mIngredient2->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
|
||||
mIngredient3->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
|
||||
mIngredient4->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
|
||||
|
||||
MyGUI::Widget* buttonBox = mCancelButton->getParent();
|
||||
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
|
||||
mCancelButton->setCoord(buttonBox->getWidth() - cancelButtonWidth,
|
||||
mCancelButton->getTop(), cancelButtonWidth, mCancelButton->getHeight());
|
||||
int createButtonWidth = mCreateButton->getTextSize().width + 24;
|
||||
mCreateButton->setCoord(buttonBox->getWidth() - createButtonWidth - cancelButtonWidth - 4,
|
||||
mCreateButton->getTop(), createButtonWidth, mCreateButton->getHeight());
|
||||
|
||||
mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked);
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked);
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
center();
|
||||
}
|
||||
|
||||
void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
mWindowManager.removeGuiMode(GM_Alchemy);
|
||||
mWindowManager.removeGuiMode(GM_Inventory);
|
||||
}
|
||||
|
||||
void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
// check if mortar & pestle is available (always needed)
|
||||
/// \todo check albemic, calcinator, retort (sometimes needed)
|
||||
if (!mApparatus1->isUserString("ToolTipType"))
|
||||
{
|
||||
mWindowManager.messageBox("#{sNotifyMessage45}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure 2 or more ingredients were selected
|
||||
int numIngreds = 0;
|
||||
if (mIngredient1->isUserString("ToolTipType"))
|
||||
++numIngreds;
|
||||
if (mIngredient2->isUserString("ToolTipType"))
|
||||
++numIngreds;
|
||||
if (mIngredient3->isUserString("ToolTipType"))
|
||||
++numIngreds;
|
||||
if (mIngredient4->isUserString("ToolTipType"))
|
||||
++numIngreds;
|
||||
if (numIngreds < 2)
|
||||
{
|
||||
mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure a name was entered
|
||||
std::string name = mNameEdit->getCaption();
|
||||
boost::algorithm::trim(name);
|
||||
if (name == "")
|
||||
{
|
||||
mWindowManager.messageBox("#{sNotifyMessage37}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
// if there are no created effects, the potion will always fail (but the ingredients won't be destroyed)
|
||||
if (mEffects.empty())
|
||||
{
|
||||
mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>());
|
||||
MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rand() % 2 == 0) /// \todo
|
||||
{
|
||||
ESM::Potion newPotion;
|
||||
newPotion.name = mNameEdit->getCaption();
|
||||
ESM::EffectList effects;
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
{
|
||||
if (mEffects.size() >= i+1)
|
||||
{
|
||||
ESM::ENAMstruct effect;
|
||||
effect.effectID = mEffects[i].mEffectID;
|
||||
effect.area = 0;
|
||||
effect.range = ESM::RT_Self;
|
||||
effect.skill = mEffects[i].mSkill;
|
||||
effect.attribute = mEffects[i].mAttribute;
|
||||
effect.magnMin = 1; /// \todo
|
||||
effect.magnMax = 10; /// \todo
|
||||
effect.duration = 60; /// \todo
|
||||
effects.list.push_back(effect);
|
||||
}
|
||||
}
|
||||
|
||||
// UESP Wiki / Morrowind:Alchemy
|
||||
// "The weight of a potion is an average of the weight of the ingredients, rounded down."
|
||||
// note by scrawl: not rounding down here, I can't imagine a created potion to
|
||||
// have 0 weight when using ingredients with 0.1 weight respectively
|
||||
float weight = 0;
|
||||
if (mIngredient1->isUserString("ToolTipType"))
|
||||
weight += mIngredient1->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->data.weight;
|
||||
if (mIngredient2->isUserString("ToolTipType"))
|
||||
weight += mIngredient2->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->data.weight;
|
||||
if (mIngredient3->isUserString("ToolTipType"))
|
||||
weight += mIngredient3->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->data.weight;
|
||||
if (mIngredient4->isUserString("ToolTipType"))
|
||||
weight += mIngredient4->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->data.weight;
|
||||
newPotion.data.weight = weight / float(numIngreds);
|
||||
|
||||
newPotion.data.value = 100; /// \todo
|
||||
newPotion.effects = effects;
|
||||
// pick a random mesh and icon
|
||||
std::vector<std::string> names;
|
||||
/// \todo is the mesh/icon dependent on alchemy skill?
|
||||
names.push_back("standard");
|
||||
names.push_back("bargain");
|
||||
names.push_back("cheap");
|
||||
names.push_back("fresh");
|
||||
names.push_back("exclusive");
|
||||
names.push_back("quality");
|
||||
int random = rand() % names.size();
|
||||
newPotion.model = "m\\misc_potion_" + names[random ] + "_01.nif";
|
||||
newPotion.icon = "m\\tx_potion_" + names[random ] + "_01.dds";
|
||||
|
||||
// check if a similiar potion record exists already
|
||||
bool found = false;
|
||||
std::string objectId;
|
||||
typedef std::map<std::string, ESM::Potion> PotionMap;
|
||||
PotionMap potions = MWBase::Environment::get().getWorld()->getStore().potions.list;
|
||||
for (PotionMap::const_iterator it = potions.begin(); it != potions.end(); ++it)
|
||||
{
|
||||
if (found) break;
|
||||
|
||||
if (it->second.data.value == newPotion.data.value
|
||||
&& it->second.data.weight == newPotion.data.weight
|
||||
&& it->second.name == newPotion.name
|
||||
&& it->second.effects.list.size() == newPotion.effects.list.size())
|
||||
{
|
||||
// check effects
|
||||
for (unsigned int i=0; i < it->second.effects.list.size(); ++i)
|
||||
{
|
||||
const ESM::ENAMstruct& a = it->second.effects.list[i];
|
||||
const ESM::ENAMstruct& b = newPotion.effects.list[i];
|
||||
if (a.effectID == b.effectID
|
||||
&& a.area == b.area
|
||||
&& a.range == b.range
|
||||
&& a.skill == b.skill
|
||||
&& a.attribute == b.attribute
|
||||
&& a.magnMin == b.magnMin
|
||||
&& a.magnMax == b.magnMax
|
||||
&& a.duration == b.duration)
|
||||
{
|
||||
found = true;
|
||||
objectId = it->first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
std::pair<std::string, const ESM::Potion*> result = MWBase::Environment::get().getWorld()->createRecord(newPotion);
|
||||
objectId = result.first;
|
||||
}
|
||||
|
||||
// create a reference and add it to player inventory
|
||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), objectId);
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
ref.getPtr().getRefData().setCount(1);
|
||||
store.add(ref.getPtr());
|
||||
|
||||
mWindowManager.messageBox("#{sPotionSuccess}", std::vector<std::string>());
|
||||
MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// potion failed
|
||||
mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>());
|
||||
MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
|
||||
}
|
||||
|
||||
// reduce count of the ingredients
|
||||
if (mIngredient1->isUserString("ToolTipType"))
|
||||
{
|
||||
MWWorld::Ptr ingred = *mIngredient1->getUserData<MWWorld::Ptr>();
|
||||
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
|
||||
if (ingred.getRefData().getCount() == 0)
|
||||
removeIngredient(mIngredient1);
|
||||
}
|
||||
if (mIngredient2->isUserString("ToolTipType"))
|
||||
{
|
||||
MWWorld::Ptr ingred = *mIngredient2->getUserData<MWWorld::Ptr>();
|
||||
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
|
||||
if (ingred.getRefData().getCount() == 0)
|
||||
removeIngredient(mIngredient2);
|
||||
}
|
||||
if (mIngredient3->isUserString("ToolTipType"))
|
||||
{
|
||||
MWWorld::Ptr ingred = *mIngredient3->getUserData<MWWorld::Ptr>();
|
||||
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
|
||||
if (ingred.getRefData().getCount() == 0)
|
||||
removeIngredient(mIngredient3);
|
||||
}
|
||||
if (mIngredient4->isUserString("ToolTipType"))
|
||||
{
|
||||
MWWorld::Ptr ingred = *mIngredient4->getUserData<MWWorld::Ptr>();
|
||||
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
|
||||
if (ingred.getRefData().getCount() == 0)
|
||||
removeIngredient(mIngredient4);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void AlchemyWindow::open()
|
||||
{
|
||||
openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
setFilter(ContainerBase::Filter_Ingredients);
|
||||
|
||||
// pick the best available apparatus
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
MWWorld::Ptr bestAlbemic;
|
||||
MWWorld::Ptr bestMortarPestle;
|
||||
MWWorld::Ptr bestCalcinator;
|
||||
MWWorld::Ptr bestRetort;
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it(store.begin(MWWorld::ContainerStore::Type_Apparatus));
|
||||
it != store.end(); ++it)
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData>* ref = it->get<ESM::Apparatus>();
|
||||
if (ref->base->data.type == ESM::Apparatus::Albemic
|
||||
&& (bestAlbemic.isEmpty() || ref->base->data.quality > bestAlbemic.get<ESM::Apparatus>()->base->data.quality))
|
||||
bestAlbemic = *it;
|
||||
else if (ref->base->data.type == ESM::Apparatus::MortarPestle
|
||||
&& (bestMortarPestle.isEmpty() || ref->base->data.quality > bestMortarPestle.get<ESM::Apparatus>()->base->data.quality))
|
||||
bestMortarPestle = *it;
|
||||
else if (ref->base->data.type == ESM::Apparatus::Calcinator
|
||||
&& (bestCalcinator.isEmpty() || ref->base->data.quality > bestCalcinator.get<ESM::Apparatus>()->base->data.quality))
|
||||
bestCalcinator = *it;
|
||||
else if (ref->base->data.type == ESM::Apparatus::Retort
|
||||
&& (bestRetort.isEmpty() || ref->base->data.quality > bestRetort.get<ESM::Apparatus>()->base->data.quality))
|
||||
bestRetort = *it;
|
||||
}
|
||||
|
||||
if (!bestMortarPestle.isEmpty())
|
||||
{
|
||||
mApparatus1->setUserString("ToolTipType", "ItemPtr");
|
||||
mApparatus1->setUserData(bestMortarPestle);
|
||||
mApparatus1->setImageTexture(getIconPath(bestMortarPestle));
|
||||
}
|
||||
if (!bestAlbemic.isEmpty())
|
||||
{
|
||||
mApparatus2->setUserString("ToolTipType", "ItemPtr");
|
||||
mApparatus2->setUserData(bestAlbemic);
|
||||
mApparatus2->setImageTexture(getIconPath(bestAlbemic));
|
||||
}
|
||||
if (!bestCalcinator.isEmpty())
|
||||
{
|
||||
mApparatus3->setUserString("ToolTipType", "ItemPtr");
|
||||
mApparatus3->setUserData(bestCalcinator);
|
||||
mApparatus3->setImageTexture(getIconPath(bestCalcinator));
|
||||
}
|
||||
if (!bestRetort.isEmpty())
|
||||
{
|
||||
mApparatus4->setUserString("ToolTipType", "ItemPtr");
|
||||
mApparatus4->setUserData(bestRetort);
|
||||
mApparatus4->setImageTexture(getIconPath(bestRetort));
|
||||
}
|
||||
}
|
||||
|
||||
void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender)
|
||||
{
|
||||
removeIngredient(_sender);
|
||||
drawItems();
|
||||
update();
|
||||
}
|
||||
|
||||
void AlchemyWindow::onSelectedItemImpl(MWWorld::Ptr item)
|
||||
{
|
||||
MyGUI::ImageBox* add = NULL;
|
||||
|
||||
// don't allow to add an ingredient that is already added
|
||||
// (which could happen if two similiar ingredients don't stack because of script / owner)
|
||||
bool alreadyAdded = false;
|
||||
std::string name = MWWorld::Class::get(item).getName(item);
|
||||
if (mIngredient1->isUserString("ToolTipType"))
|
||||
{
|
||||
MWWorld::Ptr item2 = *mIngredient1->getUserData<MWWorld::Ptr>();
|
||||
std::string name2 = MWWorld::Class::get(item2).getName(item2);
|
||||
if (name == name2)
|
||||
alreadyAdded = true;
|
||||
}
|
||||
if (mIngredient2->isUserString("ToolTipType"))
|
||||
{
|
||||
MWWorld::Ptr item2 = *mIngredient2->getUserData<MWWorld::Ptr>();
|
||||
std::string name2 = MWWorld::Class::get(item2).getName(item2);
|
||||
if (name == name2)
|
||||
alreadyAdded = true;
|
||||
}
|
||||
if (mIngredient3->isUserString("ToolTipType"))
|
||||
{
|
||||
MWWorld::Ptr item2 = *mIngredient3->getUserData<MWWorld::Ptr>();
|
||||
std::string name2 = MWWorld::Class::get(item2).getName(item2);
|
||||
if (name == name2)
|
||||
alreadyAdded = true;
|
||||
}
|
||||
if (mIngredient4->isUserString("ToolTipType"))
|
||||
{
|
||||
MWWorld::Ptr item2 = *mIngredient4->getUserData<MWWorld::Ptr>();
|
||||
std::string name2 = MWWorld::Class::get(item2).getName(item2);
|
||||
if (name == name2)
|
||||
alreadyAdded = true;
|
||||
}
|
||||
if (alreadyAdded)
|
||||
return;
|
||||
|
||||
if (!mIngredient1->isUserString("ToolTipType"))
|
||||
add = mIngredient1;
|
||||
if (add == NULL && !mIngredient2->isUserString("ToolTipType"))
|
||||
add = mIngredient2;
|
||||
if (add == NULL && !mIngredient3->isUserString("ToolTipType"))
|
||||
add = mIngredient3;
|
||||
if (add == NULL && !mIngredient4->isUserString("ToolTipType"))
|
||||
add = mIngredient4;
|
||||
|
||||
if (add != NULL)
|
||||
{
|
||||
add->setUserString("ToolTipType", "ItemPtr");
|
||||
add->setUserData(item);
|
||||
add->setImageTexture(getIconPath(item));
|
||||
drawItems();
|
||||
update();
|
||||
|
||||
std::string sound = MWWorld::Class::get(item).getUpSoundId(item);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> AlchemyWindow::itemsToIgnore()
|
||||
{
|
||||
std::vector<MWWorld::Ptr> ignore;
|
||||
// don't show ingredients that are currently selected in the "available ingredients" box.
|
||||
if (mIngredient1->isUserString("ToolTipType"))
|
||||
ignore.push_back(*mIngredient1->getUserData<MWWorld::Ptr>());
|
||||
if (mIngredient2->isUserString("ToolTipType"))
|
||||
ignore.push_back(*mIngredient2->getUserData<MWWorld::Ptr>());
|
||||
if (mIngredient3->isUserString("ToolTipType"))
|
||||
ignore.push_back(*mIngredient3->getUserData<MWWorld::Ptr>());
|
||||
if (mIngredient4->isUserString("ToolTipType"))
|
||||
ignore.push_back(*mIngredient4->getUserData<MWWorld::Ptr>());
|
||||
|
||||
return ignore;
|
||||
}
|
||||
|
||||
void AlchemyWindow::update()
|
||||
{
|
||||
Widgets::SpellEffectList effects;
|
||||
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
MyGUI::ImageBox* ingredient;
|
||||
if (i==0)
|
||||
ingredient = mIngredient1;
|
||||
else if (i==1)
|
||||
ingredient = mIngredient2;
|
||||
else if (i==2)
|
||||
ingredient = mIngredient3;
|
||||
else if (i==3)
|
||||
ingredient = mIngredient4;
|
||||
|
||||
if (!ingredient->isUserString("ToolTipType"))
|
||||
continue;
|
||||
|
||||
// add the effects of this ingredient to list of effects
|
||||
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData>* ref = ingredient->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>();
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
if (ref->base->data.effectID[i] < 0)
|
||||
continue;
|
||||
MWGui::Widgets::SpellEffectParams params;
|
||||
params.mEffectID = ref->base->data.effectID[i];
|
||||
params.mAttribute = ref->base->data.attributes[i];
|
||||
params.mSkill = ref->base->data.skills[i];
|
||||
effects.push_back(params);
|
||||
}
|
||||
|
||||
// update ingredient count labels
|
||||
if (ingredient->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0));
|
||||
|
||||
MyGUI::TextBox* text = ingredient->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
|
||||
text->setTextAlign(MyGUI::Align::Right);
|
||||
text->setNeedMouseFocus(false);
|
||||
text->setTextShadow(true);
|
||||
text->setTextShadowColour(MyGUI::Colour(0,0,0));
|
||||
text->setCaption(getCountString(ingredient->getUserData<MWWorld::Ptr>()->getRefData().getCount()));
|
||||
}
|
||||
|
||||
// now remove effects that are only present once
|
||||
Widgets::SpellEffectList::iterator it = effects.begin();
|
||||
while (it != effects.end())
|
||||
{
|
||||
Widgets::SpellEffectList::iterator next = it;
|
||||
++next;
|
||||
bool found = false;
|
||||
for (; next != effects.end(); ++next)
|
||||
{
|
||||
if (*next == *it)
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
it = effects.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
// now remove duplicates, and don't allow more than 4 effects
|
||||
Widgets::SpellEffectList old = effects;
|
||||
effects.clear();
|
||||
int i=0;
|
||||
for (Widgets::SpellEffectList::iterator it = old.begin();
|
||||
it != old.end(); ++it)
|
||||
{
|
||||
bool found = false;
|
||||
for (Widgets::SpellEffectList::iterator it2 = effects.begin();
|
||||
it2 != effects.end(); ++it2)
|
||||
{
|
||||
// MW considers all "foritfy attribute" effects as the same effect. See the
|
||||
// "Can't create multi-state boost potions" discussion on http://www.uesp.net/wiki/Morrowind_talk:Alchemy
|
||||
// thus, we are only checking effectID here and not attribute or skill
|
||||
if (it2->mEffectID == it->mEffectID)
|
||||
found = true;
|
||||
}
|
||||
if (!found && i<4)
|
||||
{
|
||||
++i;
|
||||
effects.push_back(*it);
|
||||
}
|
||||
}
|
||||
mEffects = effects;
|
||||
|
||||
while (mEffectsBox->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(mEffectsBox->getChildAt(0));
|
||||
|
||||
MyGUI::IntCoord coord(0, 0, mEffectsBox->getWidth(), 24);
|
||||
Widgets::MWEffectListPtr effectsWidget = mEffectsBox->createWidget<Widgets::MWEffectList>
|
||||
("MW_StatName", coord, Align::Left | Align::Top);
|
||||
effectsWidget->setWindowManager(&mWindowManager);
|
||||
effectsWidget->setEffectList(effects);
|
||||
|
||||
std::vector<MyGUI::WidgetPtr> effectItems;
|
||||
effectsWidget->createEffectWidgets(effectItems, mEffectsBox, coord, false, 0);
|
||||
effectsWidget->setCoord(coord);
|
||||
}
|
||||
|
||||
void AlchemyWindow::removeIngredient(MyGUI::Widget* ingredient)
|
||||
{
|
||||
ingredient->clearUserStrings();
|
||||
static_cast<MyGUI::ImageBox*>(ingredient)->setImageTexture("");
|
||||
if (ingredient->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0));
|
||||
}
|
||||
}
|
51
apps/openmw/mwgui/alchemywindow.hpp
Normal file
51
apps/openmw/mwgui/alchemywindow.hpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
#ifndef MWGUI_ALCHEMY_H
|
||||
#define MWGUI_ALCHEMY_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
#include "container.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class AlchemyWindow : public WindowBase, public ContainerBase
|
||||
{
|
||||
public:
|
||||
AlchemyWindow(WindowManager& parWindowManager);
|
||||
|
||||
virtual void open();
|
||||
|
||||
protected:
|
||||
MyGUI::Button* mCreateButton;
|
||||
MyGUI::Button* mCancelButton;
|
||||
|
||||
MyGUI::ImageBox* mIngredient1;
|
||||
MyGUI::ImageBox* mIngredient2;
|
||||
MyGUI::ImageBox* mIngredient3;
|
||||
MyGUI::ImageBox* mIngredient4;
|
||||
|
||||
MyGUI::ImageBox* mApparatus1;
|
||||
MyGUI::ImageBox* mApparatus2;
|
||||
MyGUI::ImageBox* mApparatus3;
|
||||
MyGUI::ImageBox* mApparatus4;
|
||||
|
||||
MyGUI::Widget* mEffectsBox;
|
||||
|
||||
MyGUI::EditBox* mNameEdit;
|
||||
|
||||
Widgets::SpellEffectList mEffects; // effects of created potion
|
||||
|
||||
void onCancelButtonClicked(MyGUI::Widget* _sender);
|
||||
void onCreateButtonClicked(MyGUI::Widget* _sender);
|
||||
void onIngredientSelected(MyGUI::Widget* _sender);
|
||||
|
||||
virtual void onSelectedItemImpl(MWWorld::Ptr item);
|
||||
virtual std::vector<MWWorld::Ptr> itemsToIgnore();
|
||||
|
||||
void removeIngredient(MyGUI::Widget* ingredient);
|
||||
|
||||
virtual void onReferenceUnavailable() { ; }
|
||||
|
||||
void update();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -27,7 +27,6 @@ BirthDialog::BirthDialog(WindowManager& parWindowManager)
|
|||
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked);
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
#include "bookwindow.hpp"
|
||||
|
||||
#include "formatting.hpp"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "formatting.hpp"
|
||||
#include "window_manager.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
|
@ -52,7 +53,7 @@ void BookWindow::open (MWWorld::Ptr book)
|
|||
clearPages();
|
||||
mCurrentPage = 0;
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (book, "book open", 1.0, 1.0);
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
|
||||
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
mBook.get<ESM::Book>();
|
||||
|
@ -77,23 +78,31 @@ void BookWindow::open (MWWorld::Ptr book)
|
|||
}
|
||||
|
||||
updatePages();
|
||||
|
||||
setTakeButtonShow(true);
|
||||
}
|
||||
|
||||
void BookWindow::setTakeButtonShow(bool show)
|
||||
{
|
||||
mTakeButton->setVisible(show);
|
||||
}
|
||||
|
||||
void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (mBook, "book close", 1.0, 1.0);
|
||||
// no 3d sounds because the object could be in a container.
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game);
|
||||
mWindowManager.removeGuiMode(GM_Book);
|
||||
}
|
||||
|
||||
void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (mBook, "Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
|
||||
|
||||
MWWorld::ActionTake take(mBook);
|
||||
take.execute();
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||
mWindowManager.removeGuiMode(GM_Book);
|
||||
}
|
||||
|
||||
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* _sender)
|
||||
|
|
|
@ -11,7 +11,9 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
BookWindow(WindowManager& parWindowManager);
|
||||
|
||||
void open(MWWorld::Ptr book);
|
||||
void setTakeButtonShow(bool show);
|
||||
|
||||
protected:
|
||||
void onNextPageButtonClicked (MyGUI::Widget* _sender);
|
||||
|
|
|
@ -110,7 +110,6 @@ using namespace MWGui;
|
|||
CharacterCreation::CharacterCreation(WindowManager* _wm)
|
||||
: mNameDialog(0)
|
||||
, mRaceDialog(0)
|
||||
, mDialogueWindow(0)
|
||||
, mClassChoiceDialog(0)
|
||||
, mGenerateClassQuestionDialog(0)
|
||||
, mGenerateClassResultDialog(0)
|
||||
|
@ -118,11 +117,62 @@ CharacterCreation::CharacterCreation(WindowManager* _wm)
|
|||
, mCreateClassDialog(0)
|
||||
, mBirthSignDialog(0)
|
||||
, mReviewDialog(0)
|
||||
, mGenerateClassStep(0)
|
||||
, mWM(_wm)
|
||||
{
|
||||
mCreationStage = CSE_NotStarted;
|
||||
}
|
||||
|
||||
void CharacterCreation::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
|
||||
{
|
||||
if (mReviewDialog)
|
||||
{
|
||||
static const char *ids[] =
|
||||
{
|
||||
"AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5",
|
||||
"AttribVal6", "AttribVal7", "AttribVal8",
|
||||
0
|
||||
};
|
||||
|
||||
for (int i=0; ids[i]; ++i)
|
||||
{
|
||||
if (ids[i]==id)
|
||||
mReviewDialog->setAttribute(ESM::Attribute::AttributeID(i), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterCreation::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
|
||||
{
|
||||
if (mReviewDialog)
|
||||
{
|
||||
if (id == "HBar")
|
||||
{
|
||||
mReviewDialog->setHealth (value);
|
||||
}
|
||||
else if (id == "MBar")
|
||||
{
|
||||
mReviewDialog->setMagicka (value);
|
||||
}
|
||||
else if (id == "FBar")
|
||||
{
|
||||
mReviewDialog->setFatigue (value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterCreation::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
|
||||
{
|
||||
if (mReviewDialog)
|
||||
mReviewDialog->setSkillValue(parSkill, value);
|
||||
}
|
||||
|
||||
void CharacterCreation::configureSkills (const SkillList& major, const SkillList& minor)
|
||||
{
|
||||
if (mReviewDialog)
|
||||
mReviewDialog->configureSkills(major, minor);
|
||||
}
|
||||
|
||||
void CharacterCreation::spawnDialog(const char id)
|
||||
{
|
||||
switch (id)
|
||||
|
@ -173,7 +223,6 @@ void CharacterCreation::spawnDialog(const char id)
|
|||
mWM->removeDialog(mBirthSignDialog);
|
||||
mBirthSignDialog = new BirthDialog(*mWM);
|
||||
mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen);
|
||||
mBirthSignDialog->setBirthId(mPlayerBirthSignId);
|
||||
mBirthSignDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogDone);
|
||||
mBirthSignDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogBack);
|
||||
mBirthSignDialog->open();
|
||||
|
@ -210,20 +259,22 @@ void CharacterCreation::spawnDialog(const char id)
|
|||
mReviewDialog->setFatigue(mPlayerFatigue);
|
||||
|
||||
{
|
||||
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator end = mPlayerAttributes.end();
|
||||
for (std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator it = mPlayerAttributes.begin(); it != end; ++it)
|
||||
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > attributes = mWM->getPlayerAttributeValues();
|
||||
for (std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator it = attributes.begin();
|
||||
it != attributes.end(); ++it)
|
||||
{
|
||||
mReviewDialog->setAttribute(it->first, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator end = mPlayerSkillValues.end();
|
||||
for (std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator it = mPlayerSkillValues.begin(); it != end; ++it)
|
||||
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > skills = mWM->getPlayerSkillValues();
|
||||
for (std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator it = skills.begin();
|
||||
it != skills.end(); ++it)
|
||||
{
|
||||
mReviewDialog->setSkillValue(it->first, it->second);
|
||||
}
|
||||
mReviewDialog->configureSkills(mPlayerMajorSkills, mPlayerMinorSkills);
|
||||
mReviewDialog->configureSkills(mWM->getPlayerMajorSkills(), mWM->getPlayerMinorSkills());
|
||||
}
|
||||
|
||||
mReviewDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogDone);
|
||||
|
@ -254,7 +305,7 @@ void CharacterCreation::onReviewDialogDone(WindowBase* parWindow)
|
|||
if (mReviewDialog)
|
||||
mWM->removeDialog(mReviewDialog);
|
||||
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
|
||||
void CharacterCreation::onReviewDialogBack()
|
||||
|
@ -262,7 +313,7 @@ void CharacterCreation::onReviewDialogBack()
|
|||
if (mReviewDialog)
|
||||
mWM->removeDialog(mReviewDialog);
|
||||
|
||||
mWM->setGuiMode(GM_Birth);
|
||||
mWM->pushGuiMode(GM_Birth);
|
||||
}
|
||||
|
||||
void CharacterCreation::onReviewActivateDialog(int parDialog)
|
||||
|
@ -271,19 +322,21 @@ void CharacterCreation::onReviewActivateDialog(int parDialog)
|
|||
mWM->removeDialog(mReviewDialog);
|
||||
mCreationStage = CSE_ReviewNext;
|
||||
|
||||
mWM->popGuiMode();
|
||||
|
||||
switch(parDialog)
|
||||
{
|
||||
case ReviewDialog::NAME_DIALOG:
|
||||
mWM->setGuiMode(GM_Name);
|
||||
mWM->pushGuiMode(GM_Name);
|
||||
break;
|
||||
case ReviewDialog::RACE_DIALOG:
|
||||
mWM->setGuiMode(GM_Race);
|
||||
mWM->pushGuiMode(GM_Race);
|
||||
break;
|
||||
case ReviewDialog::CLASS_DIALOG:
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
break;
|
||||
case ReviewDialog::BIRTHSIGN_DIALOG:
|
||||
mWM->setGuiMode(GM_Birth);
|
||||
mWM->pushGuiMode(GM_Birth);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -305,13 +358,19 @@ void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow)
|
|||
|
||||
//TODO This bit gets repeated a few times; wrap it in a function
|
||||
if (mCreationStage == CSE_ReviewNext)
|
||||
mWM->setGuiMode(GM_Review);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Review);
|
||||
}
|
||||
else if (mCreationStage >= CSE_ClassChosen)
|
||||
mWM->setGuiMode(GM_Birth);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Birth);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCreationStage = CSE_ClassChosen;
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,7 +384,8 @@ void CharacterCreation::onPickClassDialogBack()
|
|||
mWM->removeDialog(mPickClassDialog);
|
||||
}
|
||||
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
|
||||
void CharacterCreation::onClassChoice(int _index)
|
||||
|
@ -335,19 +395,21 @@ void CharacterCreation::onClassChoice(int _index)
|
|||
mWM->removeDialog(mClassChoiceDialog);
|
||||
}
|
||||
|
||||
mWM->popGuiMode();
|
||||
|
||||
switch(_index)
|
||||
{
|
||||
case ClassChoiceDialog::Class_Generate:
|
||||
mWM->setGuiMode(GM_ClassGenerate);
|
||||
mWM->pushGuiMode(GM_ClassGenerate);
|
||||
break;
|
||||
case ClassChoiceDialog::Class_Pick:
|
||||
mWM->setGuiMode(GM_ClassPick);
|
||||
mWM->pushGuiMode(GM_ClassPick);
|
||||
break;
|
||||
case ClassChoiceDialog::Class_Create:
|
||||
mWM->setGuiMode(GM_ClassCreate);
|
||||
mWM->pushGuiMode(GM_ClassCreate);
|
||||
break;
|
||||
case ClassChoiceDialog::Class_Back:
|
||||
mWM->setGuiMode(GM_Race);
|
||||
mWM->pushGuiMode(GM_Race);
|
||||
break;
|
||||
|
||||
};
|
||||
|
@ -364,13 +426,19 @@ void CharacterCreation::onNameDialogDone(WindowBase* parWindow)
|
|||
}
|
||||
|
||||
if (mCreationStage == CSE_ReviewNext)
|
||||
mWM->setGuiMode(GM_Review);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Review);
|
||||
}
|
||||
else if (mCreationStage >= CSE_NameChosen)
|
||||
mWM->setGuiMode(GM_Race);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Race);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCreationStage = CSE_NameChosen;
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,7 +452,8 @@ void CharacterCreation::onRaceDialogBack()
|
|||
mWM->removeDialog(mRaceDialog);
|
||||
}
|
||||
|
||||
mWM->setGuiMode(GM_Name);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Name);
|
||||
}
|
||||
|
||||
void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
|
||||
|
@ -399,13 +468,19 @@ void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
|
|||
}
|
||||
|
||||
if (mCreationStage == CSE_ReviewNext)
|
||||
mWM->setGuiMode(GM_Review);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Review);
|
||||
}
|
||||
else if (mCreationStage >= CSE_RaceChosen)
|
||||
mWM->setGuiMode(GM_Class);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCreationStage = CSE_RaceChosen;
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,18 +489,20 @@ void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
|
|||
if (mBirthSignDialog)
|
||||
{
|
||||
mPlayerBirthSignId = mBirthSignDialog->getBirthId();
|
||||
mWM->setBirthSign(mPlayerBirthSignId);
|
||||
if (!mPlayerBirthSignId.empty())
|
||||
MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mPlayerBirthSignId);
|
||||
mWM->removeDialog(mBirthSignDialog);
|
||||
}
|
||||
|
||||
if (mCreationStage >= CSE_BirthSignChosen)
|
||||
mWM->setGuiMode(GM_Review);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Review);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCreationStage = CSE_BirthSignChosen;
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,7 +514,8 @@ void CharacterCreation::onBirthSignDialogBack()
|
|||
mWM->removeDialog(mBirthSignDialog);
|
||||
}
|
||||
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
|
||||
void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
|
||||
|
@ -472,13 +550,19 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
|
|||
}
|
||||
|
||||
if (mCreationStage == CSE_ReviewNext)
|
||||
mWM->setGuiMode(GM_Review);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Review);
|
||||
}
|
||||
else if (mCreationStage >= CSE_ClassChosen)
|
||||
mWM->setGuiMode(GM_Birth);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Birth);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCreationStage = CSE_ClassChosen;
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -487,7 +571,8 @@ void CharacterCreation::onCreateClassDialogBack()
|
|||
if (mCreateClassDialog)
|
||||
mWM->removeDialog(mCreateClassDialog);
|
||||
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
|
||||
void CharacterCreation::onClassQuestionChosen(int _index)
|
||||
|
@ -498,7 +583,8 @@ void CharacterCreation::onClassQuestionChosen(int _index)
|
|||
mWM->removeDialog(mGenerateClassQuestionDialog);
|
||||
if (_index < 0 || _index >= 3)
|
||||
{
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -583,7 +669,8 @@ void CharacterCreation::showClassQuestionDialog()
|
|||
|
||||
if (mGenerateClassStep > sGenerateClassSteps.size())
|
||||
{
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -612,7 +699,8 @@ void CharacterCreation::onGenerateClassBack()
|
|||
mWM->removeDialog(mGenerateClassResultDialog);
|
||||
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass);
|
||||
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
|
||||
void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
|
||||
|
@ -620,15 +708,24 @@ void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
|
|||
if (mGenerateClassResultDialog)
|
||||
mWM->removeDialog(mGenerateClassResultDialog);
|
||||
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass);
|
||||
const ESM::Class *klass = MWBase::Environment::get().getWorld()->getStore().classes.find(mGenerateClass);
|
||||
mPlayerClass = *klass;
|
||||
mWM->setPlayerClass(mPlayerClass);
|
||||
|
||||
if (mCreationStage == CSE_ReviewNext)
|
||||
mWM->setGuiMode(GM_Review);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Review);
|
||||
}
|
||||
else if (mCreationStage >= CSE_ClassChosen)
|
||||
mWM->setGuiMode(GM_Birth);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Birth);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCreationStage = CSE_ClassChosen;
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -636,7 +733,6 @@ CharacterCreation::~CharacterCreation()
|
|||
{
|
||||
delete mNameDialog;
|
||||
delete mRaceDialog;
|
||||
delete mDialogueWindow;
|
||||
delete mClassChoiceDialog;
|
||||
delete mGenerateClassQuestionDialog;
|
||||
delete mGenerateClassResultDialog;
|
||||
|
|
|
@ -42,11 +42,15 @@ namespace MWGui
|
|||
|
||||
void setPlayerFatigue (const MWMechanics::DynamicStat<int>& value);
|
||||
|
||||
void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
|
||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
||||
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
||||
void configureSkills (const SkillList& major, const SkillList& minor);
|
||||
|
||||
private:
|
||||
//Dialogs
|
||||
TextInputDialog* mNameDialog;
|
||||
RaceDialog* mRaceDialog;
|
||||
DialogueWindow* mDialogueWindow;
|
||||
ClassChoiceDialog* mClassChoiceDialog;
|
||||
InfoBoxDialog* mGenerateClassQuestionDialog;
|
||||
GenerateClassResultDialog* mGenerateClassResultDialog;
|
||||
|
@ -62,9 +66,6 @@ namespace MWGui
|
|||
std::string mPlayerRaceId;
|
||||
std::string mPlayerBirthSignId;
|
||||
ESM::Class mPlayerClass;
|
||||
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > mPlayerAttributes;
|
||||
SkillList mPlayerMajorSkills, mPlayerMinorSkills;
|
||||
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > mPlayerSkillValues;
|
||||
MWMechanics::DynamicStat<int> mPlayerHealth;
|
||||
MWMechanics::DynamicStat<int> mPlayerMagicka;
|
||||
MWMechanics::DynamicStat<int> mPlayerFatigue;
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#include "class.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "components/esm_store/store.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iterator>
|
||||
|
@ -8,6 +6,11 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
|
@ -28,7 +31,6 @@ GenerateClassResultDialog::GenerateClassResultDialog(WindowManager& parWindowMan
|
|||
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked);
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
|
@ -80,17 +82,13 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager)
|
|||
// Centre dialog
|
||||
center();
|
||||
|
||||
setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization"));
|
||||
getWidget(specializationName, "SpecializationName");
|
||||
|
||||
setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:"));
|
||||
getWidget(favoriteAttribute[0], "FavoriteAttribute0");
|
||||
getWidget(favoriteAttribute[1], "FavoriteAttribute1");
|
||||
favoriteAttribute[0]->setWindowManager(&mWindowManager);
|
||||
favoriteAttribute[1]->setWindowManager(&mWindowManager);
|
||||
|
||||
setText("MajorSkillT", mWindowManager.getGameSettingString("sChooseClassMenu3", "Major Skills:"));
|
||||
setText("MinorSkillT", mWindowManager.getGameSettingString("sChooseClassMenu4", "Minor Skills:"));
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
char theIndex = '0'+i;
|
||||
|
@ -111,7 +109,6 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager)
|
|||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked);
|
||||
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
|
@ -233,15 +230,21 @@ void PickClassDialog::updateStats()
|
|||
"sSpecializationMagic",
|
||||
"sSpecializationStealth"
|
||||
};
|
||||
specializationName->setCaption(mWindowManager.getGameSettingString(specIds[specialization], specIds[specialization]));
|
||||
std::string specName = mWindowManager.getGameSettingString(specIds[specialization], specIds[specialization]);
|
||||
specializationName->setCaption(specName);
|
||||
ToolTips::createSpecializationToolTip(specializationName, specName, specialization);
|
||||
|
||||
favoriteAttribute[0]->setAttributeId(klass->data.attribute[0]);
|
||||
favoriteAttribute[1]->setAttributeId(klass->data.attribute[1]);
|
||||
ToolTips::createAttributeToolTip(favoriteAttribute[0], favoriteAttribute[0]->getAttributeId());
|
||||
ToolTips::createAttributeToolTip(favoriteAttribute[1], favoriteAttribute[1]->getAttributeId());
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
majorSkill[i]->setSkillNumber(klass->data.skills[i][0]);
|
||||
minorSkill[i]->setSkillNumber(klass->data.skills[i][1]);
|
||||
minorSkill[i]->setSkillNumber(klass->data.skills[i][0]);
|
||||
majorSkill[i]->setSkillNumber(klass->data.skills[i][1]);
|
||||
ToolTips::createSkillToolTip(minorSkill[i], klass->data.skills[i][0]);
|
||||
ToolTips::createSkillToolTip(majorSkill[i], klass->data.skills[i][1]);
|
||||
}
|
||||
|
||||
classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds");
|
||||
|
@ -389,7 +392,6 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
|
|||
|
||||
setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization"));
|
||||
getWidget(specializationName, "SpecializationName");
|
||||
specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], ""));
|
||||
specializationName->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked);
|
||||
|
||||
setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:"));
|
||||
|
@ -432,7 +434,6 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
|
|||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onBackClicked);
|
||||
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
|
@ -454,6 +455,9 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
|
|||
minorSkill[2]->setSkillId(ESM::Skill::Spear);
|
||||
minorSkill[3]->setSkillId(ESM::Skill::Athletics);
|
||||
minorSkill[4]->setSkillId(ESM::Skill::Enchant);
|
||||
|
||||
setSpecialization(0);
|
||||
update();
|
||||
}
|
||||
|
||||
CreateClassDialog::~CreateClassDialog()
|
||||
|
@ -464,6 +468,18 @@ CreateClassDialog::~CreateClassDialog()
|
|||
delete descDialog;
|
||||
}
|
||||
|
||||
void CreateClassDialog::update()
|
||||
{
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
ToolTips::createSkillToolTip(majorSkill[i], majorSkill[i]->getSkillId());
|
||||
ToolTips::createSkillToolTip(minorSkill[i], minorSkill[i]->getSkillId());
|
||||
}
|
||||
|
||||
ToolTips::createAttributeToolTip(favoriteAttribute0, favoriteAttribute0->getAttributeId());
|
||||
ToolTips::createAttributeToolTip(favoriteAttribute1, favoriteAttribute1->getAttributeId());
|
||||
}
|
||||
|
||||
std::string CreateClassDialog::getName() const
|
||||
{
|
||||
return editName->getOnlyText();
|
||||
|
@ -502,7 +518,7 @@ std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMinorSkills() const
|
|||
std::vector<ESM::Skill::SkillEnum> v;
|
||||
for(int i=0; i < 5; i++)
|
||||
{
|
||||
v.push_back(majorSkill[i]->getSkillId());
|
||||
v.push_back(minorSkill[i]->getSkillId());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
@ -542,19 +558,29 @@ void CreateClassDialog::open()
|
|||
void CreateClassDialog::onDialogCancel()
|
||||
{
|
||||
if (specDialog)
|
||||
specDialog->setVisible(false);
|
||||
{
|
||||
mWindowManager.removeDialog(specDialog);
|
||||
specDialog = 0;
|
||||
}
|
||||
if (attribDialog)
|
||||
attribDialog->setVisible(false);
|
||||
{
|
||||
mWindowManager.removeDialog(attribDialog);
|
||||
attribDialog = 0;
|
||||
}
|
||||
if (skillDialog)
|
||||
skillDialog->setVisible(false);
|
||||
{
|
||||
mWindowManager.removeDialog(skillDialog);
|
||||
skillDialog = 0;
|
||||
}
|
||||
if (descDialog)
|
||||
descDialog->setVisible(false);
|
||||
// TODO: Delete dialogs here
|
||||
{
|
||||
mWindowManager.removeDialog(descDialog);
|
||||
descDialog = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender)
|
||||
{
|
||||
if (specDialog)
|
||||
delete specDialog;
|
||||
specDialog = new SelectSpecializationDialog(mWindowManager);
|
||||
specDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
|
||||
|
@ -565,13 +591,27 @@ void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender)
|
|||
void CreateClassDialog::onSpecializationSelected()
|
||||
{
|
||||
specializationId = specDialog->getSpecializationId();
|
||||
specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[specializationId], ""));
|
||||
specDialog->setVisible(false);
|
||||
setSpecialization(specializationId);
|
||||
|
||||
mWindowManager.removeDialog(specDialog);
|
||||
specDialog = 0;
|
||||
}
|
||||
|
||||
void CreateClassDialog::setSpecialization(int id)
|
||||
{
|
||||
specializationId = (ESM::Class::Specialization) id;
|
||||
static const char *specIds[3] = {
|
||||
"sSpecializationCombat",
|
||||
"sSpecializationMagic",
|
||||
"sSpecializationStealth"
|
||||
};
|
||||
std::string specName = mWindowManager.getGameSettingString(specIds[specializationId], specIds[specializationId]);
|
||||
specializationName->setCaption(specName);
|
||||
ToolTips::createSpecializationToolTip(specializationName, specName, specializationId);
|
||||
}
|
||||
|
||||
void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
|
||||
{
|
||||
if (attribDialog)
|
||||
delete attribDialog;
|
||||
attribDialog = new SelectAttributeDialog(mWindowManager);
|
||||
attribDialog->setAffectedWidget(_sender);
|
||||
|
@ -595,12 +635,14 @@ void CreateClassDialog::onAttributeSelected()
|
|||
favoriteAttribute0->setAttributeId(favoriteAttribute1->getAttributeId());
|
||||
}
|
||||
attribute->setAttributeId(id);
|
||||
attribDialog->setVisible(false);
|
||||
mWindowManager.removeDialog(attribDialog);
|
||||
attribDialog = 0;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
|
||||
{
|
||||
if (skillDialog)
|
||||
delete skillDialog;
|
||||
skillDialog = new SelectSkillDialog(mWindowManager);
|
||||
skillDialog->setAffectedWidget(_sender);
|
||||
|
@ -628,7 +670,9 @@ void CreateClassDialog::onSkillSelected()
|
|||
}
|
||||
|
||||
skill->setSkillId(skillDialog->getSkillId());
|
||||
skillDialog->setVisible(false);
|
||||
mWindowManager.removeDialog(skillDialog);
|
||||
skillDialog = 0;
|
||||
update();
|
||||
}
|
||||
|
||||
void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender)
|
||||
|
@ -643,6 +687,7 @@ void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow)
|
|||
{
|
||||
description = descDialog->getTextInput();
|
||||
mWindowManager.removeDialog(descDialog);
|
||||
descDialog = 0;
|
||||
}
|
||||
|
||||
void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender)
|
||||
|
@ -668,20 +713,35 @@ SelectSpecializationDialog::SelectSpecializationDialog(WindowManager& parWindowM
|
|||
getWidget(specialization0, "Specialization0");
|
||||
getWidget(specialization1, "Specialization1");
|
||||
getWidget(specialization2, "Specialization2");
|
||||
specialization0->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], ""));
|
||||
std::string combat = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "");
|
||||
std::string magic = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], "");
|
||||
std::string stealth = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], "");
|
||||
|
||||
specialization0->setCaption(combat);
|
||||
specialization0->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked);
|
||||
specialization1->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], ""));
|
||||
specialization1->setCaption(magic);
|
||||
specialization1->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked);
|
||||
specialization2->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], ""));
|
||||
specialization2->setCaption(stealth);
|
||||
specialization2->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked);
|
||||
specializationId = ESM::Class::Combat;
|
||||
|
||||
ToolTips::createSpecializationToolTip(specialization0, combat, ESM::Class::Combat);
|
||||
ToolTips::createSpecializationToolTip(specialization1, magic, ESM::Class::Magic);
|
||||
ToolTips::createSpecializationToolTip(specialization2, stealth, ESM::Class::Stealth);
|
||||
|
||||
MyGUI::ButtonPtr cancelButton;
|
||||
getWidget(cancelButton, "CancelButton");
|
||||
cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", ""));
|
||||
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked);
|
||||
int buttonWidth = cancelButton->getTextSize().width + 24;
|
||||
cancelButton->setCoord(216 - buttonWidth, 90, buttonWidth, 21);
|
||||
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
SelectSpecializationDialog::~SelectSpecializationDialog()
|
||||
{
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
// widget controls
|
||||
|
@ -724,6 +784,7 @@ SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager)
|
|||
attribute->setWindowManager(&parWindowManager);
|
||||
attribute->setAttributeId(ESM::Attribute::attributeIds[i]);
|
||||
attribute->eventClicked += MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked);
|
||||
ToolTips::createAttributeToolTip(attribute, attribute->getAttributeId());
|
||||
}
|
||||
|
||||
MyGUI::ButtonPtr cancelButton;
|
||||
|
@ -732,6 +793,13 @@ SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager)
|
|||
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked);
|
||||
int buttonWidth = cancelButton->getTextSize().width + 24;
|
||||
cancelButton->setCoord(186 - buttonWidth, 180, buttonWidth, 21);
|
||||
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
SelectAttributeDialog::~SelectAttributeDialog()
|
||||
{
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
// widget controls
|
||||
|
@ -813,6 +881,7 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager)
|
|||
skills[spec][i].widget->setWindowManager(&mWindowManager);
|
||||
skills[spec][i].widget->setSkillId(skills[spec][i].skillId);
|
||||
skills[spec][i].widget->eventClicked += MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked);
|
||||
ToolTips::createSkillToolTip(skills[spec][i].widget, skills[spec][i].widget->getSkillId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -822,6 +891,13 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager)
|
|||
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked);
|
||||
int buttonWidth = cancelButton->getTextSize().width + 24;
|
||||
cancelButton->setCoord(447 - buttonWidth, 218, buttonWidth, 21);
|
||||
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
SelectSkillDialog::~SelectSkillDialog()
|
||||
{
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
// widget controls
|
||||
|
@ -856,6 +932,13 @@ DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager)
|
|||
|
||||
// Make sure the edit box has focus
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit);
|
||||
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
DescriptionDialog::~DescriptionDialog()
|
||||
{
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
// widget controls
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace MWGui
|
|||
typedef delegates::CMultiDelegate1<int> EventHandle_Int;
|
||||
|
||||
/** Event : Button was clicked.\n
|
||||
signature : void method(MyGUI::WidgetPtr widget, int index)\n
|
||||
signature : void method(int index)\n
|
||||
*/
|
||||
EventHandle_Int eventButtonSelected;
|
||||
|
||||
|
@ -139,6 +139,7 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
SelectSpecializationDialog(WindowManager& parWindowManager);
|
||||
~SelectSpecializationDialog();
|
||||
|
||||
ESM::Class::Specialization getSpecializationId() const { return specializationId; }
|
||||
|
||||
|
@ -169,6 +170,7 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
SelectAttributeDialog(WindowManager& parWindowManager);
|
||||
~SelectAttributeDialog();
|
||||
|
||||
ESM::Attribute::AttributeID getAttributeId() const { return attributeId; }
|
||||
Widgets::MWAttributePtr getAffectedWidget() const { return affectedWidget; }
|
||||
|
@ -201,6 +203,7 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
SelectSkillDialog(WindowManager& parWindowManager);
|
||||
~SelectSkillDialog();
|
||||
|
||||
ESM::Skill::SkillEnum getSkillId() const { return skillId; }
|
||||
Widgets::MWSkillPtr getAffectedWidget() const { return affectedWidget; }
|
||||
|
@ -236,6 +239,7 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
DescriptionDialog(WindowManager& parWindowManager);
|
||||
~DescriptionDialog();
|
||||
|
||||
std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; }
|
||||
void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); }
|
||||
|
@ -285,6 +289,10 @@ namespace MWGui
|
|||
void onDescriptionEntered(WindowBase* parWindow);
|
||||
void onDialogCancel();
|
||||
|
||||
void setSpecialization(int id);
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
MyGUI::EditPtr editName;
|
||||
MyGUI::TextBox* specializationName;
|
||||
|
|
70
apps/openmw/mwgui/confirmationdialog.cpp
Normal file
70
apps/openmw/mwgui/confirmationdialog.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "confirmationdialog.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
ConfirmationDialog::ConfirmationDialog(WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_confirmation_dialog_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mMessage, "Message");
|
||||
getWidget(mOkButton, "OkButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ConfirmationDialog::onCancelButtonClicked);
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ConfirmationDialog::onOkButtonClicked);
|
||||
}
|
||||
|
||||
void ConfirmationDialog::open(const std::string& message)
|
||||
{
|
||||
setVisible(true);
|
||||
|
||||
mMessage->setCaptionWithReplacing(message);
|
||||
|
||||
int height = mMessage->getTextSize().height + 72;
|
||||
|
||||
mMainWidget->setSize(mMainWidget->getWidth(), height);
|
||||
|
||||
mMessage->setSize(mMessage->getWidth(), mMessage->getTextSize().height+24);
|
||||
|
||||
center();
|
||||
|
||||
// make other gui elements inaccessible while this dialog is open
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
|
||||
int okButtonWidth = mOkButton->getTextSize().width + 24;
|
||||
mOkButton->setCoord(mMainWidget->getWidth() - 30 - okButtonWidth,
|
||||
mOkButton->getTop(),
|
||||
okButtonWidth,
|
||||
mOkButton->getHeight());
|
||||
|
||||
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
|
||||
mCancelButton->setCoord(mMainWidget->getWidth() - 30 - okButtonWidth - cancelButtonWidth - 8,
|
||||
mCancelButton->getTop(),
|
||||
cancelButtonWidth,
|
||||
mCancelButton->getHeight());
|
||||
}
|
||||
|
||||
void ConfirmationDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
eventCancelClicked();
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void ConfirmationDialog::onOkButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
eventOkClicked();
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void ConfirmationDialog::close()
|
||||
{
|
||||
setVisible(false);
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
}
|
35
apps/openmw/mwgui/confirmationdialog.hpp
Normal file
35
apps/openmw/mwgui/confirmationdialog.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef MWGUI_CONFIRMATIONDIALOG_H
|
||||
#define MWGUI_CONFIRMATIONDIALOG_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class ConfirmationDialog : public WindowBase
|
||||
{
|
||||
public:
|
||||
ConfirmationDialog(WindowManager& parWindowManager);
|
||||
void open(const std::string& message);
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
||||
|
||||
/** Event : Ok button was clicked.\n
|
||||
signature : void method()\n
|
||||
*/
|
||||
EventHandle_Void eventOkClicked;
|
||||
EventHandle_Void eventCancelClicked;
|
||||
|
||||
private:
|
||||
MyGUI::EditBox* mMessage;
|
||||
MyGUI::Button* mOkButton;
|
||||
MyGUI::Button* mCancelButton;
|
||||
|
||||
void onCancelButtonClicked(MyGUI::Widget* _sender);
|
||||
void onOkButtonClicked(MyGUI::Widget* _sender);
|
||||
|
||||
void close();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -138,6 +138,7 @@ namespace MWGui
|
|||
void Console::disable()
|
||||
{
|
||||
setVisible(false);
|
||||
setSelectedObject(MWWorld::Ptr());
|
||||
// Remove keyboard focus from the console input whenever the
|
||||
// console is turned off
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL);
|
||||
|
@ -240,7 +241,7 @@ namespace MWGui
|
|||
{
|
||||
try
|
||||
{
|
||||
ConsoleInterpreterContext interpreterContext (*this, MWWorld::Ptr());
|
||||
ConsoleInterpreterContext interpreterContext (*this, mPtr);
|
||||
Interpreter::Interpreter interpreter;
|
||||
MWScript::installOpcodes (interpreter);
|
||||
std::vector<Interpreter::Type_Code> code;
|
||||
|
@ -267,7 +268,7 @@ namespace MWGui
|
|||
/* Are there quotation marks? */
|
||||
if( tmp.find('"') != string::npos ) {
|
||||
int numquotes=0;
|
||||
for(string::iterator it=tmp.begin(); it < tmp.end(); it++) {
|
||||
for(string::iterator it=tmp.begin(); it < tmp.end(); ++it) {
|
||||
if( *it == '"' )
|
||||
numquotes++;
|
||||
}
|
||||
|
@ -310,7 +311,7 @@ namespace MWGui
|
|||
}
|
||||
|
||||
/* Iterate through the vector. */
|
||||
for(vector<string>::iterator it=mNames.begin(); it < mNames.end();it++) {
|
||||
for(vector<string>::iterator it=mNames.begin(); it < mNames.end();++it) {
|
||||
bool string_different=false;
|
||||
|
||||
/* Is the string shorter than the input string? If yes skip it. */
|
||||
|
@ -358,7 +359,7 @@ namespace MWGui
|
|||
int i = tmp.length();
|
||||
|
||||
for(string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) {
|
||||
for(vector<string>::iterator it=matches.begin(); it < matches.end();it++) {
|
||||
for(vector<string>::iterator it=matches.begin(); it < matches.end();++it) {
|
||||
if( tolower((*it)[i]) != tolower(*iter) ) {
|
||||
/* Append the longest match to the end of the output string*/
|
||||
output.append(matches.front().substr( 0, i));
|
||||
|
@ -370,4 +371,24 @@ namespace MWGui
|
|||
/* All keywords match with the shortest. Append it to the output string and return it. */
|
||||
return output.append(matches.front());
|
||||
}
|
||||
|
||||
void Console::onResChange(int width, int height)
|
||||
{
|
||||
setCoord(10,10, width-10, height/2);
|
||||
}
|
||||
|
||||
void Console::setSelectedObject(const MWWorld::Ptr& object)
|
||||
{
|
||||
mPtr = object;
|
||||
if (!mPtr.isEmpty())
|
||||
setTitle("#{sConsoleTitle} (" + mPtr.getCellRef().refID + ")");
|
||||
else
|
||||
setTitle("#{sConsoleTitle}");
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
||||
}
|
||||
|
||||
void Console::onReferenceUnavailable()
|
||||
{
|
||||
setSelectedObject(MWWorld::Ptr());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
#include "../mwscript/compilercontext.hpp"
|
||||
#include "../mwscript/interpretercontext.hpp"
|
||||
|
||||
#include "referenceinterface.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler
|
||||
class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler, public ReferenceInterface
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -39,6 +41,16 @@ namespace MWGui
|
|||
/// \note The list may contain duplicates (if a name is a keyword and an identifier at the same
|
||||
/// time).
|
||||
|
||||
public:
|
||||
|
||||
void setSelectedObject(const MWWorld::Ptr& object);
|
||||
///< Set the implicit object for script execution
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
|
||||
|
||||
public:
|
||||
MyGUI::EditPtr command;
|
||||
MyGUI::EditPtr history;
|
||||
|
@ -58,6 +70,8 @@ namespace MWGui
|
|||
|
||||
void setFont(const std::string &fntName);
|
||||
|
||||
void onResChange(int width, int height);
|
||||
|
||||
void clearHistory();
|
||||
|
||||
// Print a message to the console. Messages may contain color
|
||||
|
|
681
apps/openmw/mwgui/container.cpp
Normal file
681
apps/openmw/mwgui/container.cpp
Normal file
|
@ -0,0 +1,681 @@
|
|||
#include "container.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "countdialog.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace Widgets;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
bool compareType(std::string type1, std::string type2)
|
||||
{
|
||||
// this defines the sorting order of types. types that are first in the vector, appear before other types.
|
||||
std::vector<std::string> mapping;
|
||||
mapping.push_back( typeid(ESM::Weapon).name() );
|
||||
mapping.push_back( typeid(ESM::Armor).name() );
|
||||
mapping.push_back( typeid(ESM::Clothing).name() );
|
||||
mapping.push_back( typeid(ESM::Potion).name() );
|
||||
mapping.push_back( typeid(ESM::Ingredient).name() );
|
||||
mapping.push_back( typeid(ESM::Apparatus).name() );
|
||||
mapping.push_back( typeid(ESM::Book).name() );
|
||||
mapping.push_back( typeid(ESM::Light).name() );
|
||||
mapping.push_back( typeid(ESM::Miscellaneous).name() );
|
||||
mapping.push_back( typeid(ESM::Tool).name() );
|
||||
mapping.push_back( typeid(ESM::Repair).name() );
|
||||
mapping.push_back( typeid(ESM::Probe).name() );
|
||||
|
||||
assert( std::find(mapping.begin(), mapping.end(), type1) != mapping.end() );
|
||||
assert( std::find(mapping.begin(), mapping.end(), type2) != mapping.end() );
|
||||
|
||||
return std::find(mapping.begin(), mapping.end(), type1) < std::find(mapping.begin(), mapping.end(), type2);
|
||||
}
|
||||
|
||||
bool sortItems(MWWorld::Ptr left, MWWorld::Ptr right)
|
||||
{
|
||||
if (left.getTypeName() == right.getTypeName())
|
||||
{
|
||||
int cmp = MWWorld::Class::get(left).getName(left).compare(
|
||||
MWWorld::Class::get(right).getName(right));
|
||||
return cmp < 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return compareType(left.getTypeName(), right.getTypeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ContainerBase::ContainerBase(DragAndDrop* dragAndDrop) :
|
||||
mDragAndDrop(dragAndDrop),
|
||||
mFilter(ContainerBase::Filter_All)
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerBase::setWidgets(Widget* containerWidget, ScrollView* itemView)
|
||||
{
|
||||
mContainerWidget = containerWidget;
|
||||
mItemView = itemView;
|
||||
|
||||
mContainerWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onContainerClicked);
|
||||
mContainerWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerWindow::onMouseWheel);
|
||||
}
|
||||
|
||||
ContainerBase::~ContainerBase()
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
|
||||
{
|
||||
mSelectedItem = _sender;
|
||||
|
||||
if (mDragAndDrop && !isTrading())
|
||||
{
|
||||
if(!mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
|
||||
int count = object.getRefData().getCount();
|
||||
|
||||
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
|
||||
{
|
||||
startDragItem(_sender, count);
|
||||
}
|
||||
else if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
{
|
||||
startDragItem(_sender, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string message = MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTake")->str;
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::startDragItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
onContainerClicked(mContainerWidget);
|
||||
}
|
||||
else if (isTrading())
|
||||
{
|
||||
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
|
||||
int count = object.getRefData().getCount();
|
||||
|
||||
if (isInventory())
|
||||
{
|
||||
// the player is trying to sell an item, check if the merchant accepts it
|
||||
// also, don't allow selling gold (let's be better than Morrowind at this, can we?)
|
||||
if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object)
|
||||
|| MWWorld::Class::get(object).getName(object) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
|
||||
{
|
||||
// user notification "i don't buy this item"
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog4")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool buying = isTradeWindow(); // buying or selling?
|
||||
std::string message = buying ? MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage02")->str
|
||||
: MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage01")->str;
|
||||
|
||||
if (std::find(mBoughtItems.begin(), mBoughtItems.end(), object) != mBoughtItems.end())
|
||||
{
|
||||
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
|
||||
{
|
||||
sellAlreadyBoughtItem(NULL, count);
|
||||
}
|
||||
else if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
{
|
||||
sellAlreadyBoughtItem(NULL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellAlreadyBoughtItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
|
||||
{
|
||||
sellItem(NULL, count);
|
||||
}
|
||||
else if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
{
|
||||
sellItem(NULL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onSelectedItemImpl(*_sender->getUserData<MWWorld::Ptr>());
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
|
||||
{
|
||||
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
|
||||
|
||||
if (isInventory())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
}
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::sellItem(MyGUI::Widget* _sender, int count)
|
||||
{
|
||||
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
|
||||
|
||||
if (isInventory())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addBarteredItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addBarteredItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
}
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::startDragItem(MyGUI::Widget* _sender, int count)
|
||||
{
|
||||
mDragAndDrop->mIsOnDragAndDrop = true;
|
||||
mSelectedItem->detachFromWidget();
|
||||
mSelectedItem->attachToWidget(mDragAndDrop->mDragAndDropWidget);
|
||||
|
||||
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
|
||||
_unequipItem(object);
|
||||
|
||||
mDragAndDrop->mDraggedCount = count;
|
||||
|
||||
mDragAndDrop->mDraggedFrom = this;
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
mDragAndDrop->mDraggedWidget = mSelectedItem;
|
||||
static_cast<MyGUI::ImageBox*>(mSelectedItem)->setImageTexture(""); // remove the background texture (not visible during drag)
|
||||
static_cast<MyGUI::TextBox*>(mSelectedItem->getChildAt(0)->getChildAt(0))->setCaption(
|
||||
getCountString(mDragAndDrop->mDraggedCount));
|
||||
|
||||
drawItems();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(true);
|
||||
}
|
||||
|
||||
void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mDragAndDrop == NULL) return;
|
||||
|
||||
if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
|
||||
{
|
||||
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
{
|
||||
assert(object.getContainerStore() && "Item is not in a container!");
|
||||
|
||||
// check the container's Organic flag (if this is a container). container with Organic flag doesn't allow putting items inside
|
||||
if (mPtr.getTypeName() == typeid(ESM::Container).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mPtr.get<ESM::Container>();
|
||||
if (ref->base->flags & ESM::Container::Organic)
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage2")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int origCount = object.getRefData().getCount();
|
||||
|
||||
// check that we don't exceed the allowed weight (only for containers, not for inventory)
|
||||
if (!isInventory())
|
||||
{
|
||||
float capacity = MWWorld::Class::get(mPtr).getCapacity(mPtr);
|
||||
|
||||
// try adding the item, and if weight is exceeded, just remove it again.
|
||||
object.getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
MWWorld::ContainerStoreIterator it = containerStore.add(object);
|
||||
|
||||
float curWeight = MWWorld::Class::get(mPtr).getEncumbrance(mPtr);
|
||||
if (curWeight > capacity)
|
||||
{
|
||||
it->getRefData().setCount(0);
|
||||
object.getRefData().setCount(origCount);
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage3")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
std::cout << "container weight " << curWeight << "/" << capacity << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
object.getRefData().setCount (mDragAndDrop->mDraggedCount);
|
||||
containerStore.add(object);
|
||||
object.getRefData().setCount (origCount - mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
}
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
drawItems();
|
||||
mDragAndDrop->mDraggedFrom->drawItems();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (mItemView->getViewOffset().left + _rel*0.3 > 0)
|
||||
mItemView->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||
else
|
||||
mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0));
|
||||
}
|
||||
|
||||
void ContainerBase::setFilter(ContainerBase::Filter filter)
|
||||
{
|
||||
mFilter = filter;
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::openContainer(MWWorld::Ptr container)
|
||||
{
|
||||
mPtr = container;
|
||||
}
|
||||
|
||||
void ContainerBase::drawItems()
|
||||
{
|
||||
while (mContainerWidget->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0));
|
||||
}
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int maxHeight = mItemView->getSize().height - 58;
|
||||
|
||||
bool onlyMagic = false;
|
||||
int categories;
|
||||
if (mFilter == Filter_All)
|
||||
categories = MWWorld::ContainerStore::Type_All;
|
||||
else if (mFilter == Filter_Weapon)
|
||||
categories = MWWorld::ContainerStore::Type_Weapon;
|
||||
else if (mFilter == Filter_Apparel)
|
||||
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor;
|
||||
else if (mFilter == Filter_Magic)
|
||||
{
|
||||
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor
|
||||
+ MWWorld::ContainerStore::Type_Weapon + MWWorld::ContainerStore::Type_Book
|
||||
+ MWWorld::ContainerStore::Type_Potion;
|
||||
onlyMagic = true;
|
||||
}
|
||||
else if (mFilter == Filter_Misc)
|
||||
{
|
||||
categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book
|
||||
+ MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair
|
||||
+ MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light
|
||||
+ MWWorld::ContainerStore::Type_Apparatus + MWWorld::ContainerStore::Type_Probe;
|
||||
}
|
||||
else if (mFilter == Filter_Ingredients)
|
||||
categories = MWWorld::ContainerStore::Type_Ingredient;
|
||||
|
||||
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
|
||||
|
||||
std::vector< std::pair<MWWorld::Ptr, ItemState> > items;
|
||||
|
||||
std::vector<MWWorld::Ptr> equippedItems = getEquippedItems();
|
||||
|
||||
// add bought items (always at the beginning)
|
||||
std::vector<MWWorld::Ptr> boughtItems;
|
||||
for (MWWorld::ContainerStoreIterator it (mBoughtItems.begin()); it!=mBoughtItems.end(); ++it)
|
||||
{
|
||||
boughtItems.push_back(*it);
|
||||
}
|
||||
std::sort(boughtItems.begin(), boughtItems.end(), sortItems);
|
||||
|
||||
for (std::vector<MWWorld::Ptr>::iterator it=boughtItems.begin();
|
||||
it != boughtItems.end(); ++it)
|
||||
{
|
||||
items.push_back( std::make_pair(*it, ItemState_Barter) );
|
||||
}
|
||||
|
||||
// filter out the equipped items of categories we don't want
|
||||
std::vector<MWWorld::Ptr> unwantedItems = equippedItems;
|
||||
for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
|
||||
{
|
||||
std::vector<MWWorld::Ptr>::iterator found = std::find(unwantedItems.begin(), unwantedItems.end(), *iter);
|
||||
if (found != unwantedItems.end())
|
||||
{
|
||||
unwantedItems.erase(found);
|
||||
}
|
||||
}
|
||||
// now erase everything that's still in unwantedItems.
|
||||
for (std::vector<MWWorld::Ptr>::iterator it=unwantedItems.begin();
|
||||
it != unwantedItems.end(); ++it)
|
||||
{
|
||||
std::vector<MWWorld::Ptr>::iterator found = std::find(equippedItems.begin(), equippedItems.end(), *it);
|
||||
assert(found != equippedItems.end());
|
||||
equippedItems.erase(found);
|
||||
}
|
||||
// and add the items that are left (= have the correct category)
|
||||
if (!ignoreEquippedItems())
|
||||
{
|
||||
for (std::vector<MWWorld::Ptr>::const_iterator it=equippedItems.begin();
|
||||
it != equippedItems.end(); ++it)
|
||||
{
|
||||
items.push_back( std::make_pair(*it, ItemState_Equipped) );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> ignoreItems = itemsToIgnore();
|
||||
|
||||
// now add the regular items
|
||||
std::vector<MWWorld::Ptr> regularItems;
|
||||
for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
|
||||
{
|
||||
if (std::find(equippedItems.begin(), equippedItems.end(), *iter) == equippedItems.end()
|
||||
&& std::find(ignoreItems.begin(), ignoreItems.end(), *iter) == ignoreItems.end()
|
||||
&& std::find(mBoughtItems.begin(), mBoughtItems.end(), *iter) == mBoughtItems.end())
|
||||
regularItems.push_back(*iter);
|
||||
}
|
||||
|
||||
// sort them and add
|
||||
std::sort(regularItems.begin(), regularItems.end(), sortItems);
|
||||
for (std::vector<MWWorld::Ptr>::const_iterator it=regularItems.begin(); it!=regularItems.end(); ++it)
|
||||
{
|
||||
items.push_back( std::make_pair(*it, ItemState_Normal) );
|
||||
}
|
||||
|
||||
for (std::vector< std::pair<MWWorld::Ptr, ItemState> >::const_iterator it=items.begin();
|
||||
it != items.end(); ++it)
|
||||
{
|
||||
const MWWorld::Ptr* iter = &((*it).first);
|
||||
|
||||
int displayCount = iter->getRefData().getCount();
|
||||
if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>())
|
||||
{
|
||||
displayCount -= mDragAndDrop->mDraggedCount;
|
||||
}
|
||||
if(displayCount > 0 && !(onlyMagic && it->second != ItemState_Barter && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name()))
|
||||
{
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(*iter).getInventoryIcon(*iter);
|
||||
|
||||
// background widget (for the "equipped" frame and magic item background image)
|
||||
bool isMagic = (MWWorld::Class::get(*iter).getEnchantment(*iter) != "");
|
||||
MyGUI::ImageBox* backgroundWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
|
||||
backgroundWidget->setUserString("ToolTipType", "ItemPtr");
|
||||
backgroundWidget->setUserData(*iter);
|
||||
|
||||
std::string backgroundTex = "textures\\menu_icon";
|
||||
if (isMagic)
|
||||
backgroundTex += "_magic";
|
||||
if (it->second == ItemState_Normal)
|
||||
{
|
||||
if (!isMagic)
|
||||
backgroundTex = "";
|
||||
}
|
||||
else if (it->second == ItemState_Equipped)
|
||||
{
|
||||
backgroundTex += "_equip";
|
||||
}
|
||||
else if (it->second == ItemState_Barter)
|
||||
{
|
||||
backgroundTex += "_barter";
|
||||
}
|
||||
if (backgroundTex != "")
|
||||
backgroundTex += ".dds";
|
||||
|
||||
backgroundWidget->setImageTexture(backgroundTex);
|
||||
if (it->second == ItemState_Barter && !isMagic)
|
||||
backgroundWidget->setProperty("ImageCoord", "2 2 42 42");
|
||||
else
|
||||
backgroundWidget->setProperty("ImageCoord", "0 0 42 42");
|
||||
backgroundWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onSelectedItem);
|
||||
backgroundWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerBase::onMouseWheel);
|
||||
|
||||
// image
|
||||
ImageBox* image = backgroundWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
image->setImageTexture(path);
|
||||
image->setNeedMouseFocus(false);
|
||||
|
||||
// text widget that shows item count
|
||||
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
|
||||
text->setTextAlign(MyGUI::Align::Right);
|
||||
text->setNeedMouseFocus(false);
|
||||
text->setTextShadow(true);
|
||||
text->setTextShadowColour(MyGUI::Colour(0,0,0));
|
||||
text->setCaption(getCountString(displayCount));
|
||||
|
||||
y += 42;
|
||||
if (y > maxHeight)
|
||||
{
|
||||
x += 42;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
MyGUI::IntSize size = MyGUI::IntSize(std::max(mItemView->getSize().width, x+42), mItemView->getSize().height);
|
||||
mItemView->setCanvasSize(size);
|
||||
mContainerWidget->setSize(size);
|
||||
|
||||
notifyContentChanged();
|
||||
}
|
||||
|
||||
std::string ContainerBase::getCountString(const int count)
|
||||
{
|
||||
if (count == 1)
|
||||
return "";
|
||||
if (count > 9999)
|
||||
return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
|
||||
else
|
||||
return boost::lexical_cast<std::string>(count);
|
||||
}
|
||||
|
||||
void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
|
||||
{
|
||||
int origCount = item.getRefData().getCount();
|
||||
item.getRefData().setCount(count);
|
||||
MWWorld::ContainerStoreIterator it = mBoughtItems.add(item);
|
||||
item.getRefData().setCount(origCount - count);
|
||||
}
|
||||
|
||||
void ContainerBase::addItem(MWWorld::Ptr item, int count)
|
||||
{
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
int origCount = item.getRefData().getCount();
|
||||
|
||||
item.getRefData().setCount(count);
|
||||
MWWorld::ContainerStoreIterator it = containerStore.add(item);
|
||||
|
||||
item.getRefData().setCount(origCount - count);
|
||||
}
|
||||
|
||||
void ContainerBase::transferBoughtItems()
|
||||
{
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
|
||||
{
|
||||
containerStore.add(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
|
||||
{
|
||||
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
|
||||
{
|
||||
store.add(*it);
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::ContainerStore& ContainerBase::getContainerStore()
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
return store;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
ContainerWindow::ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)
|
||||
: ContainerBase(dragAndDrop)
|
||||
, WindowBase("openmw_container_window_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mTakeButton, "TakeButton");
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
|
||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
|
||||
|
||||
// adjust buttons size to fit text
|
||||
int closeButtonWidth = mCloseButton->getTextSize().width+24;
|
||||
int takeButtonWidth = mTakeButton->getTextSize().width+24;
|
||||
mCloseButton->setCoord(600-20-closeButtonWidth, mCloseButton->getCoord().top, closeButtonWidth, mCloseButton->getCoord().height);
|
||||
mTakeButton->setCoord(600-20-closeButtonWidth-takeButtonWidth-8, mTakeButton->getCoord().top, takeButtonWidth, mTakeButton->getCoord().height);
|
||||
|
||||
int w = MyGUI::RenderManager::getInstance().getViewSize().width;
|
||||
//int h = MyGUI::RenderManager::getInstance().getViewSize().height;
|
||||
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ContainerWindow::onWindowResize);
|
||||
|
||||
setCoord(w-600,0,600,300);
|
||||
}
|
||||
|
||||
ContainerWindow::~ContainerWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerWindow::onWindowResize(MyGUI::Window* window)
|
||||
{
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerWindow::open(MWWorld::Ptr container)
|
||||
{
|
||||
openContainer(container);
|
||||
setTitle(MWWorld::Class::get(container).getName(container));
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// transfer everything into the player's inventory
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);
|
||||
|
||||
int i=0;
|
||||
for (MWWorld::ContainerStoreIterator iter (containerStore.begin()); iter!=containerStore.end(); ++iter)
|
||||
{
|
||||
playerStore.add(*iter);
|
||||
|
||||
if (i==0)
|
||||
{
|
||||
// play the sound of the first object
|
||||
std::string sound = MWWorld::Class::get(*iter).getUpSoundId(*iter);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
containerStore.clear();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWindow::onReferenceUnavailable()
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
}
|
147
apps/openmw/mwgui/container.hpp
Normal file
147
apps/openmw/mwgui/container.hpp
Normal file
|
@ -0,0 +1,147 @@
|
|||
#ifndef MGUI_CONTAINER_H
|
||||
#define MGUI_CONTAINER_H
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "window_base.hpp"
|
||||
#include "referenceinterface.hpp"
|
||||
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Environment;
|
||||
}
|
||||
|
||||
namespace MyGUI
|
||||
{
|
||||
class Gui;
|
||||
class Widget;
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class WindowManager;
|
||||
class ContainerWindow;
|
||||
class ContainerBase;
|
||||
}
|
||||
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class DragAndDrop
|
||||
{
|
||||
public:
|
||||
bool mIsOnDragAndDrop;
|
||||
MyGUI::Widget* mDraggedWidget;
|
||||
MyGUI::Widget* mDragAndDropWidget;
|
||||
ContainerBase* mDraggedFrom;
|
||||
int mDraggedCount;
|
||||
};
|
||||
|
||||
class ContainerBase : public ReferenceInterface
|
||||
{
|
||||
public:
|
||||
ContainerBase(DragAndDrop* dragAndDrop);
|
||||
virtual ~ContainerBase();
|
||||
|
||||
enum Filter
|
||||
{
|
||||
Filter_All = 0x01,
|
||||
Filter_Weapon = 0x02,
|
||||
Filter_Apparel = 0x03,
|
||||
Filter_Magic = 0x04,
|
||||
Filter_Misc = 0x05,
|
||||
|
||||
Filter_Ingredients = 0x06
|
||||
};
|
||||
|
||||
enum ItemState
|
||||
{
|
||||
ItemState_Normal = 0x01,
|
||||
ItemState_Equipped = 0x02,
|
||||
ItemState_Barter = 0x03
|
||||
};
|
||||
|
||||
void setWidgets(MyGUI::Widget* containerWidget, MyGUI::ScrollView* itemView); ///< only call once
|
||||
|
||||
void addBarteredItem(MWWorld::Ptr item, int count);
|
||||
void addItem(MWWorld::Ptr item, int count);
|
||||
|
||||
void transferBoughtItems(); ///< transfer bought items into the inventory
|
||||
void returnBoughtItems(MWWorld::ContainerStore& store); ///< return bought items into the specified ContainerStore
|
||||
|
||||
MWWorld::ContainerStore& getContainerStore();
|
||||
MWWorld::ContainerStore& getBoughtItems() { return mBoughtItems; }
|
||||
|
||||
void openContainer(MWWorld::Ptr container);
|
||||
void setFilter(Filter filter); ///< set category filter
|
||||
void drawItems();
|
||||
|
||||
protected:
|
||||
MyGUI::ScrollView* mItemView;
|
||||
MyGUI::Widget* mContainerWidget;
|
||||
|
||||
MyGUI::Widget* mSelectedItem;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
Filter mFilter;
|
||||
|
||||
// bought items are put in a separate ContainerStore so that they don't stack with other (not bought) items.
|
||||
MWWorld::ContainerStore mBoughtItems;
|
||||
|
||||
void onSelectedItem(MyGUI::Widget* _sender);
|
||||
void onContainerClicked(MyGUI::Widget* _sender);
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
|
||||
/// start dragging an item (drag & drop)
|
||||
void startDragItem(MyGUI::Widget* _sender, int count);
|
||||
|
||||
/// sell an item from this container
|
||||
void sellItem(MyGUI::Widget* _sender, int count);
|
||||
|
||||
/// sell an item from this container, that was previously just bought
|
||||
void sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count);
|
||||
|
||||
std::string getCountString(const int count);
|
||||
|
||||
virtual bool isTradeWindow() { return false; }
|
||||
virtual bool isInventory() { return false; }
|
||||
virtual std::vector<MWWorld::Ptr> getEquippedItems() { return std::vector<MWWorld::Ptr>(); }
|
||||
virtual void _unequipItem(MWWorld::Ptr item) { ; }
|
||||
|
||||
virtual bool isTrading() { return false; }
|
||||
|
||||
virtual void onSelectedItemImpl(MWWorld::Ptr item) { ; }
|
||||
|
||||
virtual bool ignoreEquippedItems() { return false; }
|
||||
virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); }
|
||||
|
||||
virtual void notifyContentChanged() { ; }
|
||||
};
|
||||
|
||||
class ContainerWindow : public ContainerBase, public WindowBase
|
||||
{
|
||||
public:
|
||||
ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop);
|
||||
|
||||
virtual ~ContainerWindow();
|
||||
|
||||
void open(MWWorld::Ptr container);
|
||||
|
||||
protected:
|
||||
MyGUI::Button* mTakeButton;
|
||||
MyGUI::Button* mCloseButton;
|
||||
|
||||
void onWindowResize(MyGUI::Window* window);
|
||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
};
|
||||
}
|
||||
#endif // CONTAINER_H
|
108
apps/openmw/mwgui/countdialog.cpp
Normal file
108
apps/openmw/mwgui/countdialog.cpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
#include "countdialog.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
CountDialog::CountDialog(WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_count_window_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mSlider, "CountSlider");
|
||||
getWidget(mItemEdit, "ItemEdit");
|
||||
getWidget(mItemText, "ItemText");
|
||||
getWidget(mLabelText, "LabelText");
|
||||
getWidget(mOkButton, "OkButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked);
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked);
|
||||
mItemEdit->eventEditTextChange += MyGUI::newDelegate(this, &CountDialog::onEditTextChange);
|
||||
mSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &CountDialog::onSliderMoved);
|
||||
}
|
||||
|
||||
void CountDialog::open(const std::string& item, const std::string& message, const int maxCount)
|
||||
{
|
||||
setVisible(true);
|
||||
|
||||
mLabelText->setCaption(message);
|
||||
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
||||
mSlider->setScrollRange(maxCount);
|
||||
mItemText->setCaption(item);
|
||||
|
||||
int width = std::max(mItemText->getTextSize().width + 128, 320);
|
||||
setCoord(viewSize.width/2 - width/2,
|
||||
viewSize.height/2 - mMainWidget->getHeight()/2,
|
||||
width,
|
||||
mMainWidget->getHeight());
|
||||
|
||||
// make other gui elements inaccessible while this dialog is open
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit);
|
||||
|
||||
mSlider->setScrollPosition(maxCount-1);
|
||||
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));
|
||||
|
||||
int okButtonWidth = mOkButton->getTextSize().width + 24;
|
||||
mOkButton->setCoord(width - 30 - okButtonWidth,
|
||||
mOkButton->getTop(),
|
||||
okButtonWidth,
|
||||
mOkButton->getHeight());
|
||||
|
||||
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
|
||||
mCancelButton->setCoord(width - 30 - okButtonWidth - cancelButtonWidth - 8,
|
||||
mCancelButton->getTop(),
|
||||
cancelButtonWidth,
|
||||
mCancelButton->getHeight());
|
||||
}
|
||||
|
||||
void CountDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void CountDialog::onOkButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
eventOkClicked(NULL, mSlider->getScrollPosition()+1);
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void CountDialog::onEditTextChange(MyGUI::EditBox* _sender)
|
||||
{
|
||||
if (_sender->getCaption() == "")
|
||||
return;
|
||||
|
||||
unsigned int count;
|
||||
try
|
||||
{
|
||||
count = boost::lexical_cast<unsigned int>(_sender->getCaption());
|
||||
}
|
||||
catch (std::bad_cast&)
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
if (count > mSlider->getScrollRange())
|
||||
{
|
||||
count = mSlider->getScrollRange();
|
||||
}
|
||||
mSlider->setScrollPosition(count-1);
|
||||
onSliderMoved(mSlider, count-1);
|
||||
}
|
||||
|
||||
void CountDialog::onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position)
|
||||
{
|
||||
mItemEdit->setCaption(boost::lexical_cast<std::string>(_position+1));
|
||||
}
|
||||
|
||||
void CountDialog::close()
|
||||
{
|
||||
setVisible(false);
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
}
|
39
apps/openmw/mwgui/countdialog.hpp
Normal file
39
apps/openmw/mwgui/countdialog.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef MWGUI_COUNTDIALOG_H
|
||||
#define MWGUI_COUNTDIALOG_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class CountDialog : public WindowBase
|
||||
{
|
||||
public:
|
||||
CountDialog(WindowManager& parWindowManager);
|
||||
void open(const std::string& item, const std::string& message, const int maxCount);
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, int> EventHandle_WidgetInt;
|
||||
|
||||
/** Event : Ok button was clicked.\n
|
||||
signature : void method(MyGUI::Widget* _sender, int _count)\n
|
||||
*/
|
||||
EventHandle_WidgetInt eventOkClicked;
|
||||
|
||||
private:
|
||||
MyGUI::ScrollBar* mSlider;
|
||||
MyGUI::EditBox* mItemEdit;
|
||||
MyGUI::TextBox* mItemText;
|
||||
MyGUI::TextBox* mLabelText;
|
||||
MyGUI::Button* mOkButton;
|
||||
MyGUI::Button* mCancelButton;
|
||||
|
||||
void onCancelButtonClicked(MyGUI::Widget* _sender);
|
||||
void onOkButtonClicked(MyGUI::Widget* _sender);
|
||||
void onEditTextChange(MyGUI::EditBox* _sender);
|
||||
void onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position);
|
||||
|
||||
void close();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,11 +1,4 @@
|
|||
#include "dialogue.hpp"
|
||||
#include "dialogue_history.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "list.hpp"
|
||||
#include "components/esm_store/store.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwdialogue/dialoguemanager.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
@ -14,6 +7,18 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwdialogue/dialoguemanager.hpp"
|
||||
|
||||
#include "dialogue_history.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "list.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace Widgets;
|
||||
|
||||
|
@ -40,6 +45,7 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su
|
|||
DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
|
||||
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager)
|
||||
, mEnabled(true)
|
||||
, mShowTrade(false)
|
||||
{
|
||||
// Centre dialog
|
||||
center();
|
||||
|
@ -58,14 +64,11 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
|
|||
|
||||
//Topics list
|
||||
getWidget(topicsList, "TopicsList");
|
||||
//topicsList->eventListSelectAccept += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
||||
topicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
||||
//topicsList->eventListChangePosition += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
||||
|
||||
MyGUI::ButtonPtr byeButton;
|
||||
getWidget(byeButton, "ByeButton");
|
||||
byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
|
||||
byeButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->str);
|
||||
|
||||
getWidget(pDispositionBar, "Disposition");
|
||||
getWidget(pDispositionText,"DispositionText");
|
||||
|
@ -109,15 +112,6 @@ void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
|||
history->setVScrollPosition(history->getVScrollPosition() - _rel*0.3);
|
||||
}
|
||||
|
||||
void DialogueWindow::open()
|
||||
{
|
||||
topicsList->clear();
|
||||
pTopicsText.clear();
|
||||
history->eraseText(0,history->getTextLength());
|
||||
updateOptions();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||
|
@ -127,24 +121,46 @@ void DialogueWindow::onSelectTopic(std::string topic)
|
|||
{
|
||||
if (!mEnabled) return;
|
||||
|
||||
if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str)
|
||||
{
|
||||
/// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)?
|
||||
mWindowManager.pushGuiMode(GM_Barter);
|
||||
mWindowManager.getTradeWindow()->startTrade(mPtr);
|
||||
}
|
||||
|
||||
else
|
||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
|
||||
}
|
||||
|
||||
void DialogueWindow::startDialogue(std::string npcName)
|
||||
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
|
||||
{
|
||||
mEnabled = true;
|
||||
mPtr = actor;
|
||||
topicsList->setEnabled(true);
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(npcName);
|
||||
adjustWindowCaption();
|
||||
setTitle(npcName);
|
||||
|
||||
topicsList->clear();
|
||||
history->eraseText(0,history->getTextLength());
|
||||
updateOptions();
|
||||
}
|
||||
|
||||
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
|
||||
{
|
||||
topicsList->clear();
|
||||
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); it++)
|
||||
|
||||
bool anyService = mShowTrade;
|
||||
|
||||
if (mShowTrade)
|
||||
topicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str);
|
||||
|
||||
if (anyService)
|
||||
topicsList->addSeparator();
|
||||
|
||||
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
|
||||
{
|
||||
topicsList->addItem(*it);
|
||||
}
|
||||
topicsList->adjustSize();
|
||||
}
|
||||
|
||||
void DialogueWindow::removeKeyword(std::string keyWord)
|
||||
|
@ -152,8 +168,8 @@ void DialogueWindow::removeKeyword(std::string keyWord)
|
|||
if(topicsList->hasItem(keyWord))
|
||||
{
|
||||
topicsList->removeItem(keyWord);
|
||||
pTopicsText.erase(keyWord);
|
||||
}
|
||||
topicsList->adjustSize();
|
||||
}
|
||||
|
||||
void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2)
|
||||
|
@ -189,10 +205,14 @@ void addColorInString(std::string& str, const std::string& keyword,std::string c
|
|||
|
||||
std::string DialogueWindow::parseText(std::string text)
|
||||
{
|
||||
bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored)
|
||||
for(unsigned int i = 0;i<topicsList->getItemCount();i++)
|
||||
{
|
||||
std::string keyWord = topicsList->getItemNameAt(i);
|
||||
if (separatorReached && keyWord != "")
|
||||
addColorInString(text,keyWord,"#686EBA","#B29154");
|
||||
else
|
||||
separatorReached = true;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
@ -226,7 +246,6 @@ void DialogueWindow::updateOptions()
|
|||
{
|
||||
//Clear the list of topics
|
||||
topicsList->clear();
|
||||
pTopicsText.clear();
|
||||
history->eraseText(0,history->getTextLength());
|
||||
|
||||
pDispositionBar->setProgressRange(100);
|
||||
|
@ -241,3 +260,8 @@ void DialogueWindow::goodbye()
|
|||
topicsList->setEnabled(false);
|
||||
mEnabled = false;
|
||||
}
|
||||
|
||||
void DialogueWindow::onReferenceUnavailable()
|
||||
{
|
||||
mWindowManager.removeGuiMode(GM_Dialogue);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
#define MWGUI_DIALOGE_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
#include "referenceinterface.hpp"
|
||||
#include <boost/array.hpp>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class WindowManager;
|
||||
|
@ -23,13 +26,11 @@ namespace MWGui
|
|||
{
|
||||
class DialogueHistory;
|
||||
|
||||
class DialogueWindow: public WindowBase
|
||||
class DialogueWindow: public WindowBase, public ReferenceInterface
|
||||
{
|
||||
public:
|
||||
DialogueWindow(WindowManager& parWindowManager);
|
||||
|
||||
void open();
|
||||
|
||||
// Events
|
||||
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
||||
|
||||
|
@ -38,7 +39,7 @@ namespace MWGui
|
|||
*/
|
||||
EventHandle_Void eventBye;
|
||||
|
||||
void startDialogue(std::string npcName);
|
||||
void startDialogue(MWWorld::Ptr actor, std::string npcName);
|
||||
void stopDialogue();
|
||||
void setKeywords(std::list<std::string> keyWord);
|
||||
void removeKeyword(std::string keyWord);
|
||||
|
@ -47,6 +48,10 @@ namespace MWGui
|
|||
void askQuestion(std::string question);
|
||||
void goodbye();
|
||||
|
||||
// various service button visibilities, depending if the npc/creature talked to has these services
|
||||
// make sure to call these before setKeywords()
|
||||
void setShowTrade(bool show) { mShowTrade = show; }
|
||||
|
||||
protected:
|
||||
void onSelectTopic(std::string topic);
|
||||
void onByeClicked(MyGUI::Widget* _sender);
|
||||
|
@ -54,6 +59,8 @@ namespace MWGui
|
|||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
|
||||
private:
|
||||
void updateOptions();
|
||||
/**
|
||||
|
@ -61,13 +68,15 @@ namespace MWGui
|
|||
*/
|
||||
std::string parseText(std::string text);
|
||||
|
||||
// various service button visibilities, depending if the npc/creature talked to has these services
|
||||
bool mShowTrade;
|
||||
|
||||
bool mEnabled;
|
||||
|
||||
DialogueHistory* history;
|
||||
Widgets::MWList* topicsList;
|
||||
MyGUI::ProgressPtr pDispositionBar;
|
||||
MyGUI::EditPtr pDispositionText;
|
||||
std::map<std::string,std::string> pTopicsText;// this map links keyword and "real" text.
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
516
apps/openmw/mwgui/hud.cpp
Normal file
516
apps/openmw/mwgui/hud.cpp
Normal file
|
@ -0,0 +1,516 @@
|
|||
#include "hud.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <MyGUI.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "container.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
|
||||
: Layout("openmw_hud_layout.xml")
|
||||
, health(NULL)
|
||||
, magicka(NULL)
|
||||
, stamina(NULL)
|
||||
, weapImage(NULL)
|
||||
, spellImage(NULL)
|
||||
, weapStatus(NULL)
|
||||
, spellStatus(NULL)
|
||||
, effectBox(NULL)
|
||||
, effect1(NULL)
|
||||
, minimap(NULL)
|
||||
, compass(NULL)
|
||||
, crosshair(NULL)
|
||||
, fpsbox(NULL)
|
||||
, fpscounter(NULL)
|
||||
, trianglecounter(NULL)
|
||||
, batchcounter(NULL)
|
||||
, hmsBaseLeft(0)
|
||||
, weapBoxBaseLeft(0)
|
||||
, spellBoxBaseLeft(0)
|
||||
, effectBoxBaseRight(0)
|
||||
, minimapBoxBaseRight(0)
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mCellNameTimer(0.0f)
|
||||
, mCellNameBox(NULL)
|
||||
, mMapVisible(true)
|
||||
, mWeaponVisible(true)
|
||||
, mSpellVisible(true)
|
||||
, mWorldMouseOver(false)
|
||||
{
|
||||
setCoord(0,0, width, height);
|
||||
|
||||
// Energy bars
|
||||
getWidget(mHealthFrame, "HealthFrame");
|
||||
getWidget(health, "Health");
|
||||
getWidget(magicka, "Magicka");
|
||||
getWidget(stamina, "Stamina");
|
||||
|
||||
hmsBaseLeft = mHealthFrame->getLeft();
|
||||
|
||||
MyGUI::Widget *healthFrame, *magickaFrame, *fatigueFrame;
|
||||
getWidget(healthFrame, "HealthFrame");
|
||||
getWidget(magickaFrame, "MagickaFrame");
|
||||
getWidget(fatigueFrame, "FatigueFrame");
|
||||
healthFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
|
||||
magickaFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
|
||||
fatigueFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
|
||||
|
||||
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
||||
// Item and spell images and status bars
|
||||
getWidget(weapBox, "WeapBox");
|
||||
getWidget(weapImage, "WeapImage");
|
||||
getWidget(weapStatus, "WeapStatus");
|
||||
weapBoxBaseLeft = weapBox->getLeft();
|
||||
weapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWeaponClicked);
|
||||
|
||||
getWidget(spellBox, "SpellBox");
|
||||
getWidget(spellImage, "SpellImage");
|
||||
getWidget(spellStatus, "SpellStatus");
|
||||
spellBoxBaseLeft = spellBox->getLeft();
|
||||
spellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
|
||||
|
||||
getWidget(effectBox, "EffectBox");
|
||||
getWidget(effect1, "Effect1");
|
||||
effectBoxBaseRight = viewSize.width - effectBox->getRight();
|
||||
effectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
|
||||
|
||||
getWidget(minimapBox, "MiniMapBox");
|
||||
minimapBoxBaseRight = viewSize.width - minimapBox->getRight();
|
||||
minimapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
|
||||
getWidget(minimap, "MiniMap");
|
||||
getWidget(compass, "Compass");
|
||||
|
||||
getWidget(mCellNameBox, "CellName");
|
||||
getWidget(mWeaponSpellBox, "WeaponSpellName");
|
||||
|
||||
getWidget(crosshair, "Crosshair");
|
||||
|
||||
setFpsLevel(fpsLevel);
|
||||
|
||||
getWidget(trianglecounter, "TriangleCounter");
|
||||
getWidget(batchcounter, "BatchCounter");
|
||||
|
||||
setEffect("icons\\s\\tx_s_chameleon.dds");
|
||||
|
||||
LocalMapBase::init(minimap, compass, this);
|
||||
|
||||
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
|
||||
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
|
||||
mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus);
|
||||
}
|
||||
|
||||
void HUD::setFpsLevel(int level)
|
||||
{
|
||||
fpscounter = 0;
|
||||
|
||||
MyGUI::Widget* fps;
|
||||
getWidget(fps, "FPSBoxAdv");
|
||||
fps->setVisible(false);
|
||||
getWidget(fps, "FPSBox");
|
||||
fps->setVisible(false);
|
||||
|
||||
if (level == 2)
|
||||
{
|
||||
getWidget(fpsbox, "FPSBoxAdv");
|
||||
fpsbox->setVisible(true);
|
||||
getWidget(fpscounter, "FPSCounterAdv");
|
||||
}
|
||||
else if (level == 1)
|
||||
{
|
||||
getWidget(fpsbox, "FPSBox");
|
||||
fpsbox->setVisible(true);
|
||||
getWidget(fpscounter, "FPSCounter");
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setFPS(float fps)
|
||||
{
|
||||
if (fpscounter)
|
||||
fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps));
|
||||
}
|
||||
|
||||
void HUD::setTriangleCount(unsigned int count)
|
||||
{
|
||||
trianglecounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||
}
|
||||
|
||||
void HUD::setBatchCount(unsigned int count)
|
||||
{
|
||||
batchcounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||
}
|
||||
|
||||
void HUD::setEffect(const char *img)
|
||||
{
|
||||
effect1->setImageTexture(img);
|
||||
}
|
||||
|
||||
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& value)
|
||||
{
|
||||
static const char *ids[] =
|
||||
{
|
||||
"HBar", "MBar", "FBar", 0
|
||||
};
|
||||
|
||||
for (int i=0; ids[i]; ++i)
|
||||
if (ids[i]==id)
|
||||
{
|
||||
MyGUI::Widget* w;
|
||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
health->setProgressRange (value.getModified());
|
||||
health->setProgressPosition (value.getCurrent());
|
||||
getWidget(w, "HealthFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||
break;
|
||||
case 1:
|
||||
magicka->setProgressRange (value.getModified());
|
||||
magicka->setProgressPosition (value.getCurrent());
|
||||
getWidget(w, "MagickaFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||
break;
|
||||
case 2:
|
||||
stamina->setProgressRange (value.getModified());
|
||||
stamina->setProgressPosition (value.getCurrent());
|
||||
getWidget(w, "FatigueFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible)
|
||||
{
|
||||
int weapDx = 0, spellDx = 0;
|
||||
if (!hmsVisible)
|
||||
spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft;
|
||||
|
||||
if (!weapVisible)
|
||||
spellDx += spellBoxBaseLeft - weapBoxBaseLeft;
|
||||
|
||||
mWeaponVisible = weapVisible;
|
||||
mSpellVisible = spellVisible;
|
||||
if (!mWeaponVisible && !mSpellVisible)
|
||||
mWeaponSpellBox->setVisible(false);
|
||||
|
||||
health->setVisible(hmsVisible);
|
||||
stamina->setVisible(hmsVisible);
|
||||
magicka->setVisible(hmsVisible);
|
||||
weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop());
|
||||
weapBox->setVisible(weapVisible);
|
||||
spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop());
|
||||
spellBox->setVisible(spellVisible);
|
||||
}
|
||||
|
||||
void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible)
|
||||
{
|
||||
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
||||
// effect box can have variable width -> variable left coordinate
|
||||
int effectsDx = 0;
|
||||
if (!minimapBoxVisible)
|
||||
effectsDx = (viewSize.width - minimapBoxBaseRight) - (viewSize.width - effectBoxBaseRight);
|
||||
|
||||
mMapVisible = minimapBoxVisible;
|
||||
minimapBox->setVisible(minimapBoxVisible);
|
||||
effectBox->setPosition((viewSize.width - effectBoxBaseRight) - effectBox->getWidth() + effectsDx, effectBox->getTop());
|
||||
effectBox->setVisible(effectBoxVisible);
|
||||
}
|
||||
|
||||
void HUD::onWorldClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// drop item into the gameworld
|
||||
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
|
||||
MWWorld::World* world = MWBase::Environment::get().getWorld();
|
||||
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
|
||||
float mouseX = cursorPosition.left / float(viewSize.width);
|
||||
float mouseY = cursorPosition.top / float(viewSize.height);
|
||||
|
||||
int origCount = object.getRefData().getCount();
|
||||
object.getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
|
||||
if (world->canPlaceObject(mouseX, mouseY))
|
||||
world->placeObject(object, mouseX, mouseY);
|
||||
else
|
||||
world->dropObjectOnGround(object);
|
||||
|
||||
MyGUI::PointerManager::getInstance().setPointer("arrow");
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
// remove object from the container it was coming from
|
||||
object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
mDragAndDrop->mDraggedWidget = 0;
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode();
|
||||
|
||||
if ( (mode != GM_Console) && (mode != GM_Container) && (mode != GM_Inventory) )
|
||||
return;
|
||||
|
||||
std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle();
|
||||
MWWorld::Ptr object;
|
||||
try
|
||||
{
|
||||
object = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == GM_Console)
|
||||
MWBase::Environment::get().getWindowManager()->getConsole()->setSelectedObject(object);
|
||||
else if ((mode == GM_Container) || (mode == GM_Inventory))
|
||||
{
|
||||
// pick up object
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
mWorldMouseOver = false;
|
||||
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
|
||||
float mouseX = cursorPosition.left / float(viewSize.width);
|
||||
float mouseY = cursorPosition.top / float(viewSize.height);
|
||||
|
||||
MWWorld::World* world = MWBase::Environment::get().getWorld();
|
||||
|
||||
// if we can't drop the object at the wanted position, show the "drop on ground" cursor.
|
||||
bool canDrop = world->canPlaceObject(mouseX, mouseY);
|
||||
|
||||
if (!canDrop)
|
||||
MyGUI::PointerManager::getInstance().setPointer("drop_ground");
|
||||
else
|
||||
MyGUI::PointerManager::getInstance().setPointer("arrow");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
MyGUI::PointerManager::getInstance().setPointer("arrow");
|
||||
mWorldMouseOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new)
|
||||
{
|
||||
MyGUI::PointerManager::getInstance().setPointer("arrow");
|
||||
mWorldMouseOver = false;
|
||||
}
|
||||
|
||||
void HUD::onHMSClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Stats);
|
||||
}
|
||||
|
||||
void HUD::onMapClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Map);
|
||||
}
|
||||
|
||||
void HUD::onWeaponClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Inventory);
|
||||
}
|
||||
|
||||
void HUD::onMagicClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Magic);
|
||||
}
|
||||
|
||||
void HUD::setCellName(const std::string& cellName)
|
||||
{
|
||||
if (mCellName != cellName)
|
||||
{
|
||||
mCellNameTimer = 5.0f;
|
||||
mCellName = cellName;
|
||||
|
||||
mCellNameBox->setCaption(mCellName);
|
||||
mCellNameBox->setVisible(mMapVisible);
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::onFrame(float dt)
|
||||
{
|
||||
mCellNameTimer -= dt;
|
||||
mWeaponSpellTimer -= dt;
|
||||
if (mCellNameTimer < 0)
|
||||
mCellNameBox->setVisible(false);
|
||||
if (mWeaponSpellTimer < 0)
|
||||
mWeaponSpellBox->setVisible(false);
|
||||
}
|
||||
|
||||
void HUD::onResChange(int width, int height)
|
||||
{
|
||||
setCoord(0, 0, width, height);
|
||||
}
|
||||
|
||||
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
|
||||
std::string spellName = spell->name;
|
||||
if (spellName != mSpellName && mSpellVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mSpellName = spellName;
|
||||
mWeaponSpellBox->setCaption(mSpellName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
spellStatus->setProgressRange(100);
|
||||
spellStatus->setProgressPosition(successChancePercent);
|
||||
|
||||
if (spellImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0));
|
||||
|
||||
spellBox->setUserString("ToolTipType", "Spell");
|
||||
spellBox->setUserString("Spell", spellId);
|
||||
|
||||
// use the icon of the first effect
|
||||
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(spell->effects.list.front().effectID);
|
||||
std::string icon = effect->icon;
|
||||
int slashPos = icon.find("\\");
|
||||
icon.insert(slashPos+1, "b_");
|
||||
icon = std::string("icons\\") + icon;
|
||||
Widgets::fixTexturePath(icon);
|
||||
spellImage->setImageTexture(icon);
|
||||
}
|
||||
|
||||
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
|
||||
{
|
||||
std::string itemName = MWWorld::Class::get(item).getName(item);
|
||||
if (itemName != mSpellName && mSpellVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mSpellName = itemName;
|
||||
mWeaponSpellBox->setCaption(mSpellName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
spellStatus->setProgressRange(100);
|
||||
spellStatus->setProgressPosition(chargePercent);
|
||||
|
||||
if (spellImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0));
|
||||
|
||||
spellBox->setUserString("ToolTipType", "ItemPtr");
|
||||
spellBox->setUserData(item);
|
||||
|
||||
spellImage->setImageTexture("textures\\menu_icon_magic_mini.dds");
|
||||
MyGUI::ImageBox* itemBox = spellImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
|
||||
, MyGUI::Align::Stretch);
|
||||
|
||||
std::string path = std::string("icons\\");
|
||||
path+=MWWorld::Class::get(item).getInventoryIcon(item);
|
||||
Widgets::fixTexturePath(path);
|
||||
itemBox->setImageTexture(path);
|
||||
itemBox->setNeedMouseFocus(false);
|
||||
}
|
||||
|
||||
void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
|
||||
{
|
||||
std::string itemName = MWWorld::Class::get(item).getName(item);
|
||||
if (itemName != mWeaponName && mWeaponVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mWeaponName = itemName;
|
||||
mWeaponSpellBox->setCaption(mWeaponName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
weapBox->setUserString("ToolTipType", "ItemPtr");
|
||||
weapBox->setUserData(item);
|
||||
|
||||
weapStatus->setProgressRange(100);
|
||||
weapStatus->setProgressPosition(durabilityPercent);
|
||||
|
||||
if (weapImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(weapImage->getChildAt(0));
|
||||
|
||||
std::string path = std::string("icons\\");
|
||||
path+=MWWorld::Class::get(item).getInventoryIcon(item);
|
||||
Widgets::fixTexturePath(path);
|
||||
|
||||
if (MWWorld::Class::get(item).getEnchantment(item) != "")
|
||||
{
|
||||
weapImage->setImageTexture("textures\\menu_icon_magic_mini.dds");
|
||||
MyGUI::ImageBox* itemBox = weapImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
|
||||
, MyGUI::Align::Stretch);
|
||||
itemBox->setImageTexture(path);
|
||||
itemBox->setNeedMouseFocus(false);
|
||||
}
|
||||
else
|
||||
weapImage->setImageTexture(path);
|
||||
}
|
||||
|
||||
void HUD::unsetSelectedSpell()
|
||||
{
|
||||
std::string spellName = "#{sNone}";
|
||||
if (spellName != mSpellName && mSpellVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mSpellName = spellName;
|
||||
mWeaponSpellBox->setCaptionWithReplacing(mSpellName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
if (spellImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0));
|
||||
spellStatus->setProgressRange(100);
|
||||
spellStatus->setProgressPosition(0);
|
||||
spellImage->setImageTexture("");
|
||||
spellBox->clearUserStrings();
|
||||
}
|
||||
|
||||
void HUD::unsetSelectedWeapon()
|
||||
{
|
||||
std::string itemName = "#{sSkillHandtohand}";
|
||||
if (itemName != mWeaponName && mWeaponVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mWeaponName = itemName;
|
||||
mWeaponSpellBox->setCaptionWithReplacing(mWeaponName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
if (weapImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(weapImage->getChildAt(0));
|
||||
weapStatus->setProgressRange(100);
|
||||
weapStatus->setProgressPosition(0);
|
||||
weapImage->setImageTexture("icons\\k\\stealth_handtohand.dds");
|
||||
weapBox->clearUserStrings();
|
||||
}
|
85
apps/openmw/mwgui/hud.hpp
Normal file
85
apps/openmw/mwgui/hud.hpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include "map_window.hpp"
|
||||
|
||||
#include <openengine/gui/layout.hpp>
|
||||
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class DragAndDrop;
|
||||
|
||||
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
||||
{
|
||||
public:
|
||||
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
|
||||
void setEffect(const char *img);
|
||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
||||
void setFPS(float fps);
|
||||
void setTriangleCount(unsigned int count);
|
||||
void setBatchCount(unsigned int count);
|
||||
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
|
||||
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
|
||||
void setFpsLevel(const int level);
|
||||
|
||||
void setSelectedSpell(const std::string& spellId, int successChancePercent);
|
||||
void setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent);
|
||||
void setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent);
|
||||
void unsetSelectedSpell();
|
||||
void unsetSelectedWeapon();
|
||||
|
||||
void onFrame(float dt);
|
||||
void onResChange(int width, int height);
|
||||
|
||||
void setCellName(const std::string& cellName);
|
||||
|
||||
bool getWorldMouseOver() { return mWorldMouseOver; }
|
||||
|
||||
MyGUI::ProgressPtr health, magicka, stamina;
|
||||
MyGUI::Widget* mHealthFrame;
|
||||
MyGUI::Widget *weapBox, *spellBox;
|
||||
MyGUI::ImageBox *weapImage, *spellImage;
|
||||
MyGUI::ProgressPtr weapStatus, spellStatus;
|
||||
MyGUI::Widget *effectBox, *minimapBox;
|
||||
MyGUI::ImageBox* effect1;
|
||||
MyGUI::ScrollView* minimap;
|
||||
MyGUI::ImageBox* compass;
|
||||
MyGUI::ImageBox* crosshair;
|
||||
MyGUI::TextBox* mCellNameBox;
|
||||
MyGUI::TextBox* mWeaponSpellBox;
|
||||
|
||||
MyGUI::WidgetPtr fpsbox;
|
||||
MyGUI::TextBox* fpscounter;
|
||||
MyGUI::TextBox* trianglecounter;
|
||||
MyGUI::TextBox* batchcounter;
|
||||
|
||||
private:
|
||||
// bottom left elements
|
||||
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
|
||||
// bottom right elements
|
||||
int minimapBoxBaseRight, effectBoxBaseRight;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
std::string mCellName;
|
||||
float mCellNameTimer;
|
||||
|
||||
std::string mWeaponName;
|
||||
std::string mSpellName;
|
||||
float mWeaponSpellTimer;
|
||||
|
||||
bool mMapVisible;
|
||||
bool mWeaponVisible;
|
||||
bool mSpellVisible;
|
||||
|
||||
bool mWorldMouseOver;
|
||||
|
||||
void onWorldClicked(MyGUI::Widget* _sender);
|
||||
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
|
||||
void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new);
|
||||
void onHMSClicked(MyGUI::Widget* _sender);
|
||||
void onWeaponClicked(MyGUI::Widget* _sender);
|
||||
void onMagicClicked(MyGUI::Widget* _sender);
|
||||
void onMapClicked(MyGUI::Widget* _sender);
|
||||
};
|
||||
}
|
349
apps/openmw/mwgui/inventorywindow.cpp
Normal file
349
apps/openmw/mwgui/inventorywindow.cpp
Normal file
|
@ -0,0 +1,349 @@
|
|||
#include "inventorywindow.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "bookwindow.hpp"
|
||||
#include "scrollwindow.hpp"
|
||||
#include "spellwindow.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string toLower (const std::string& name)
|
||||
{
|
||||
std::string lowerCase;
|
||||
|
||||
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
|
||||
(int(*)(int)) std::tolower);
|
||||
|
||||
return lowerCase;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
InventoryWindow::InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)
|
||||
: ContainerBase(dragAndDrop)
|
||||
, WindowPinnableBase("openmw_inventory_window_layout.xml", parWindowManager)
|
||||
, mTrading(false)
|
||||
{
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
|
||||
|
||||
getWidget(mAvatar, "Avatar");
|
||||
getWidget(mEncumbranceBar, "EncumbranceBar");
|
||||
getWidget(mEncumbranceText, "EncumbranceBarT");
|
||||
getWidget(mFilterAll, "AllButton");
|
||||
getWidget(mFilterWeapon, "WeaponButton");
|
||||
getWidget(mFilterApparel, "ApparelButton");
|
||||
getWidget(mFilterMagic, "MagicButton");
|
||||
getWidget(mFilterMisc, "MiscButton");
|
||||
getWidget(mLeftPane, "LeftPane");
|
||||
getWidget(mRightPane, "RightPane");
|
||||
|
||||
mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
// adjust size of buttons to fit text
|
||||
int curX = 0;
|
||||
mFilterAll->setSize( mFilterAll->getTextSize().width + 24, mFilterAll->getSize().height );
|
||||
curX += mFilterAll->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterWeapon->setPosition(curX, mFilterWeapon->getPosition().top);
|
||||
mFilterWeapon->setSize( mFilterWeapon->getTextSize().width + 24, mFilterWeapon->getSize().height );
|
||||
curX += mFilterWeapon->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterApparel->setPosition(curX, mFilterApparel->getPosition().top);
|
||||
mFilterApparel->setSize( mFilterApparel->getTextSize().width + 24, mFilterApparel->getSize().height );
|
||||
curX += mFilterApparel->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMagic->setPosition(curX, mFilterMagic->getPosition().top);
|
||||
mFilterMagic->setSize( mFilterMagic->getTextSize().width + 24, mFilterMagic->getSize().height );
|
||||
curX += mFilterMagic->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMisc->setPosition(curX, mFilterMisc->getPosition().top);
|
||||
mFilterMisc->setSize( mFilterMisc->getTextSize().width + 24, mFilterMisc->getSize().height );
|
||||
|
||||
mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterMagic->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterMisc->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
|
||||
mFilterAll->setStateSelected(true);
|
||||
|
||||
setCoord(0, 342, 498, 258);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
openContainer(player);
|
||||
}
|
||||
|
||||
void InventoryWindow::open()
|
||||
{
|
||||
updateEncumbranceBar();
|
||||
|
||||
mTrading = false;
|
||||
|
||||
mBoughtItems.clear();
|
||||
|
||||
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
|
||||
}
|
||||
|
||||
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
{
|
||||
const float aspect = 0.5; // fixed aspect ratio for the left pane
|
||||
mLeftPane->setSize( (_sender->getSize().height-44) * aspect, _sender->getSize().height-44 );
|
||||
mRightPane->setCoord( mLeftPane->getPosition().left + (_sender->getSize().height-44) * aspect + 4,
|
||||
mRightPane->getPosition().top,
|
||||
_sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15,
|
||||
_sender->getSize().height-44 );
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (_sender == mFilterAll)
|
||||
setFilter(ContainerBase::Filter_All);
|
||||
else if (_sender == mFilterWeapon)
|
||||
setFilter(ContainerBase::Filter_Weapon);
|
||||
else if (_sender == mFilterApparel)
|
||||
setFilter(ContainerBase::Filter_Apparel);
|
||||
else if (_sender == mFilterMagic)
|
||||
setFilter(ContainerBase::Filter_Magic);
|
||||
else if (_sender == mFilterMisc)
|
||||
setFilter(ContainerBase::Filter_Misc);
|
||||
|
||||
mFilterAll->setStateSelected(false);
|
||||
mFilterWeapon->setStateSelected(false);
|
||||
mFilterApparel->setStateSelected(false);
|
||||
mFilterMagic->setStateSelected(false);
|
||||
mFilterMisc->setStateSelected(false);
|
||||
|
||||
static_cast<MyGUI::Button*>(_sender)->setStateSelected(true);
|
||||
}
|
||||
|
||||
void InventoryWindow::onPinToggled()
|
||||
{
|
||||
mWindowManager.setWeaponVisibility(!mPinned);
|
||||
}
|
||||
|
||||
void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWWorld::Ptr ptr = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
|
||||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
{
|
||||
// add item to the player's inventory
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
|
||||
int origCount = ptr.getRefData().getCount();
|
||||
ptr.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
it = invStore.add(ptr);
|
||||
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
ptr = *it;
|
||||
}
|
||||
|
||||
/// \todo scripts
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
|
||||
|
||||
action->execute();
|
||||
|
||||
// this is necessary for books/scrolls: if they are already in the player's inventory,
|
||||
// the "Take" button should not be visible.
|
||||
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
|
||||
// without screwing up future book windows
|
||||
if (mDragAndDrop->mDraggedFrom == this)
|
||||
{
|
||||
mWindowManager.getBookWindow()->setTakeButtonShow(false);
|
||||
mWindowManager.getScrollWindow()->setTakeButtonShow(false);
|
||||
}
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
|
||||
mWindowManager.setDragDrop(false);
|
||||
|
||||
drawItems();
|
||||
|
||||
// update selected weapon icon
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator weaponSlot = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
if (weaponSlot == invStore.end())
|
||||
mWindowManager.unsetSelectedWeapon();
|
||||
else
|
||||
mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems()
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end())
|
||||
{
|
||||
items.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
void InventoryWindow::_unequipItem(MWWorld::Ptr item)
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end() && *it == item)
|
||||
{
|
||||
invStore.equip(slot, invStore.end());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryWindow::updateEncumbranceBar()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
|
||||
float capacity = MWWorld::Class::get(player).getCapacity(player);
|
||||
float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
|
||||
mEncumbranceBar->setProgressRange(capacity);
|
||||
mEncumbranceBar->setProgressPosition(encumbrance);
|
||||
mEncumbranceText->setCaption( boost::lexical_cast<std::string>(int(encumbrance)) + "/" + boost::lexical_cast<std::string>(int(capacity)) );
|
||||
}
|
||||
|
||||
void InventoryWindow::onFrame()
|
||||
{
|
||||
if (!mMainWidget->getVisible())
|
||||
return;
|
||||
|
||||
updateEncumbranceBar();
|
||||
}
|
||||
|
||||
int InventoryWindow::getPlayerGold()
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
it != invStore.end(); ++it)
|
||||
{
|
||||
if (toLower(it->getCellRef().refID) == "gold_001")
|
||||
return it->getRefData().getCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InventoryWindow::startTrade()
|
||||
{
|
||||
mTrading = true;
|
||||
}
|
||||
|
||||
void InventoryWindow::notifyContentChanged()
|
||||
{
|
||||
// update the spell window just in case new enchanted items were added to inventory
|
||||
if (mWindowManager.getSpellWindow())
|
||||
mWindowManager.getSpellWindow()->updateSpells();
|
||||
|
||||
// update selected weapon icon
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator weaponSlot = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
if (weaponSlot == invStore.end())
|
||||
mWindowManager.unsetSelectedWeapon();
|
||||
else
|
||||
mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability
|
||||
}
|
||||
|
||||
void InventoryWindow::pickUpObject (MWWorld::Ptr object)
|
||||
{
|
||||
/// \todo scripts
|
||||
|
||||
// make sure the object is of a type that can be picked up
|
||||
std::string type = object.getTypeName();
|
||||
if ( (type != typeid(ESM::Apparatus).name())
|
||||
&& (type != typeid(ESM::Armor).name())
|
||||
&& (type != typeid(ESM::Book).name())
|
||||
&& (type != typeid(ESM::Clothing).name())
|
||||
&& (type != typeid(ESM::Ingredient).name())
|
||||
&& (type != typeid(ESM::Light).name())
|
||||
&& (type != typeid(ESM::Miscellaneous).name())
|
||||
&& (type != typeid(ESM::Tool).name())
|
||||
&& (type != typeid(ESM::Probe).name())
|
||||
&& (type != typeid(ESM::Repair).name())
|
||||
&& (type != typeid(ESM::Weapon).name())
|
||||
&& (type != typeid(ESM::Potion).name()))
|
||||
return;
|
||||
|
||||
// sound
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound(sound, 1, 1);
|
||||
|
||||
int count = object.getRefData().getCount();
|
||||
|
||||
// add to player inventory
|
||||
// can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr newObject = *MWWorld::Class::get (player).getContainerStore (player).add (object);
|
||||
// remove from world
|
||||
MWBase::Environment::get().getWorld()->deleteObject (object);
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = true;
|
||||
mDragAndDrop->mDraggedCount = count;
|
||||
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(newObject).getInventoryIcon(newObject);
|
||||
MyGUI::ImageBox* baseWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
|
||||
baseWidget->detachFromWidget();
|
||||
baseWidget->attachToWidget(mDragAndDrop->mDragAndDropWidget);
|
||||
baseWidget->setUserData(newObject);
|
||||
mDragAndDrop->mDraggedWidget = baseWidget;
|
||||
ImageBox* image = baseWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
image->setImageTexture(path);
|
||||
image->setNeedMouseFocus(false);
|
||||
|
||||
// text widget that shows item count
|
||||
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
|
||||
text->setTextAlign(MyGUI::Align::Right);
|
||||
text->setNeedMouseFocus(false);
|
||||
text->setTextShadow(true);
|
||||
text->setTextShadowColour(MyGUI::Colour(0,0,0));
|
||||
text->setCaption(getCountString(count));
|
||||
mDragAndDrop->mDraggedFrom = this;
|
||||
}
|
||||
}
|
60
apps/openmw/mwgui/inventorywindow.hpp
Normal file
60
apps/openmw/mwgui/inventorywindow.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef MGUI_Inventory_H
|
||||
#define MGUI_Inventory_H
|
||||
|
||||
#include "container.hpp"
|
||||
#include "window_pinnable_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class InventoryWindow : public ContainerBase, public WindowPinnableBase
|
||||
{
|
||||
public:
|
||||
InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop);
|
||||
|
||||
virtual void open();
|
||||
|
||||
/// start trading, disables item drag&drop
|
||||
void startTrade();
|
||||
|
||||
void onFrame();
|
||||
|
||||
void pickUpObject (MWWorld::Ptr object);
|
||||
|
||||
int getPlayerGold();
|
||||
|
||||
protected:
|
||||
MyGUI::Widget* mAvatar;
|
||||
MyGUI::TextBox* mArmorRating;
|
||||
MyGUI::ProgressBar* mEncumbranceBar;
|
||||
MyGUI::TextBox* mEncumbranceText;
|
||||
|
||||
MyGUI::Widget* mLeftPane;
|
||||
MyGUI::Widget* mRightPane;
|
||||
|
||||
MyGUI::Button* mFilterAll;
|
||||
MyGUI::Button* mFilterWeapon;
|
||||
MyGUI::Button* mFilterApparel;
|
||||
MyGUI::Button* mFilterMagic;
|
||||
MyGUI::Button* mFilterMisc;
|
||||
|
||||
bool mTrading;
|
||||
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
void onFilterChanged(MyGUI::Widget* _sender);
|
||||
void onAvatarClicked(MyGUI::Widget* _sender);
|
||||
void onPinToggled();
|
||||
|
||||
void updateEncumbranceBar();
|
||||
|
||||
virtual bool isTrading() { return mTrading; }
|
||||
virtual bool isInventory() { return true; }
|
||||
virtual std::vector<MWWorld::Ptr> getEquippedItems();
|
||||
virtual void _unequipItem(MWWorld::Ptr item);
|
||||
|
||||
virtual void onReferenceUnavailable() { ; }
|
||||
|
||||
virtual void notifyContentChanged();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // Inventory_H
|
|
@ -131,7 +131,7 @@ void MWGui::JournalWindow::open()
|
|||
book journal;
|
||||
journal.endLine = 0;
|
||||
|
||||
for(std::deque<MWDialogue::StampedJournalEntry>::const_iterator it = MWBase::Environment::get().getJournal()->begin();it!=MWBase::Environment::get().getJournal()->end();it++)
|
||||
for(std::deque<MWDialogue::StampedJournalEntry>::const_iterator it = MWBase::Environment::get().getJournal()->begin();it!=MWBase::Environment::get().getJournal()->end();++it)
|
||||
{
|
||||
std::string a = it->getText(MWBase::Environment::get().getWorld()->getStore());
|
||||
journal = formatText(a,journal,10,17);
|
||||
|
@ -141,7 +141,7 @@ void MWGui::JournalWindow::open()
|
|||
//std::string a = MWBase::Environment::get().getJournal()->begin()->getText(MWBase::Environment::get().getWorld()->getStore());
|
||||
//std::list<std::string> journal = formatText(a,10,20,1);
|
||||
bool left = true;
|
||||
for(std::list<std::string>::iterator it = journal.pages.begin(); it != journal.pages.end();it++)
|
||||
for(std::list<std::string>::iterator it = journal.pages.begin(); it != journal.pages.end();++it)
|
||||
{
|
||||
if(left)
|
||||
{
|
||||
|
|
|
@ -1,332 +0,0 @@
|
|||
#include "layouts.hpp"
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include "window_manager.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
|
||||
HUD::HUD(int width, int height, int fpsLevel)
|
||||
: Layout("openmw_hud_layout.xml")
|
||||
, health(NULL)
|
||||
, magicka(NULL)
|
||||
, stamina(NULL)
|
||||
, weapImage(NULL)
|
||||
, spellImage(NULL)
|
||||
, weapStatus(NULL)
|
||||
, spellStatus(NULL)
|
||||
, effectBox(NULL)
|
||||
, effect1(NULL)
|
||||
, minimap(NULL)
|
||||
, compass(NULL)
|
||||
, crosshair(NULL)
|
||||
, fpsbox(NULL)
|
||||
, fpscounter(NULL)
|
||||
, trianglecounter(NULL)
|
||||
, batchcounter(NULL)
|
||||
, hmsBaseLeft(0)
|
||||
, weapBoxBaseLeft(0)
|
||||
, spellBoxBaseLeft(0)
|
||||
, effectBoxBaseRight(0)
|
||||
, minimapBoxBaseRight(0)
|
||||
{
|
||||
setCoord(0,0, width, height);
|
||||
|
||||
// Energy bars
|
||||
getWidget(health, "Health");
|
||||
getWidget(magicka, "Magicka");
|
||||
getWidget(stamina, "Stamina");
|
||||
hmsBaseLeft = health->getLeft();
|
||||
|
||||
// Item and spell images and status bars
|
||||
getWidget(weapBox, "WeapBox");
|
||||
getWidget(weapImage, "WeapImage");
|
||||
getWidget(weapStatus, "WeapStatus");
|
||||
weapBoxBaseLeft = weapBox->getLeft();
|
||||
|
||||
getWidget(spellBox, "SpellBox");
|
||||
getWidget(spellImage, "SpellImage");
|
||||
getWidget(spellStatus, "SpellStatus");
|
||||
spellBoxBaseLeft = spellBox->getLeft();
|
||||
|
||||
getWidget(effectBox, "EffectBox");
|
||||
getWidget(effect1, "Effect1");
|
||||
effectBoxBaseRight = effectBox->getRight();
|
||||
|
||||
getWidget(minimapBox, "MiniMapBox");
|
||||
minimapBoxBaseRight = minimapBox->getRight();
|
||||
getWidget(minimap, "MiniMap");
|
||||
getWidget(compass, "Compass");
|
||||
|
||||
getWidget(crosshair, "Crosshair");
|
||||
|
||||
setFpsLevel(fpsLevel);
|
||||
|
||||
getWidget(trianglecounter, "TriangleCounter");
|
||||
getWidget(batchcounter, "BatchCounter");
|
||||
|
||||
compass->setImageTexture("textures\\compass.dds");
|
||||
crosshair->setImageTexture("textures\\target.dds");
|
||||
|
||||
// These are just demo values, you should replace these with
|
||||
// real calls from outside the class later.
|
||||
setWeapIcon("icons\\w\\tx_knife_iron.dds");
|
||||
setWeapStatus(90, 100);
|
||||
setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds");
|
||||
setSpellStatus(65, 100);
|
||||
setEffect("icons\\s\\tx_s_chameleon.dds");
|
||||
|
||||
LocalMapBase::init(minimap, this);
|
||||
}
|
||||
|
||||
void HUD::setFpsLevel(int level)
|
||||
{
|
||||
MyGUI::Widget* fps;
|
||||
getWidget(fps, "FPSBoxAdv");
|
||||
fps->setVisible(false);
|
||||
getWidget(fps, "FPSBox");
|
||||
fps->setVisible(false);
|
||||
|
||||
if (level == 2)
|
||||
{
|
||||
getWidget(fpsbox, "FPSBoxAdv");
|
||||
fpsbox->setVisible(true);
|
||||
getWidget(fpscounter, "FPSCounterAdv");
|
||||
}
|
||||
else if (level == 1)
|
||||
{
|
||||
getWidget(fpsbox, "FPSBox");
|
||||
fpsbox->setVisible(true);
|
||||
getWidget(fpscounter, "FPSCounter");
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setFPS(float fps)
|
||||
{
|
||||
fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps));
|
||||
}
|
||||
|
||||
void HUD::setTriangleCount(size_t count)
|
||||
{
|
||||
trianglecounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||
}
|
||||
|
||||
void HUD::setBatchCount(size_t count)
|
||||
{
|
||||
batchcounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||
}
|
||||
|
||||
void HUD::setStats(int h, int hmax, int m, int mmax, int s, int smax)
|
||||
{
|
||||
health->setProgressRange(hmax);
|
||||
health->setProgressPosition(h);
|
||||
magicka->setProgressRange(mmax);
|
||||
magicka->setProgressPosition(m);
|
||||
stamina->setProgressRange(smax);
|
||||
stamina->setProgressPosition(s);
|
||||
}
|
||||
|
||||
void HUD::setWeapIcon(const char *str)
|
||||
{
|
||||
weapImage->setImageTexture(str);
|
||||
}
|
||||
|
||||
void HUD::setSpellIcon(const char *str)
|
||||
{
|
||||
spellImage->setImageTexture(str);
|
||||
}
|
||||
|
||||
void HUD::setWeapStatus(int s, int smax)
|
||||
{
|
||||
weapStatus->setProgressRange(smax);
|
||||
weapStatus->setProgressPosition(s);
|
||||
}
|
||||
|
||||
void HUD::setSpellStatus(int s, int smax)
|
||||
{
|
||||
spellStatus->setProgressRange(smax);
|
||||
spellStatus->setProgressPosition(s);
|
||||
}
|
||||
|
||||
void HUD::setEffect(const char *img)
|
||||
{
|
||||
effect1->setImageTexture(img);
|
||||
}
|
||||
|
||||
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& value)
|
||||
{
|
||||
static const char *ids[] =
|
||||
{
|
||||
"HBar", "MBar", "FBar", 0
|
||||
};
|
||||
|
||||
for (int i=0; ids[i]; ++i)
|
||||
if (ids[i]==id)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
health->setProgressRange (value.getModified());
|
||||
health->setProgressPosition (value.getCurrent());
|
||||
break;
|
||||
case 1:
|
||||
magicka->setProgressRange (value.getModified());
|
||||
magicka->setProgressPosition (value.getCurrent());
|
||||
break;
|
||||
case 2:
|
||||
stamina->setProgressRange (value.getModified());
|
||||
stamina->setProgressPosition (value.getCurrent());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setPlayerDir(const float x, const float y)
|
||||
{
|
||||
if (!minimapBox->getVisible() || (x == mLastPositionX && y == mLastPositionY)) return;
|
||||
|
||||
MyGUI::ISubWidget* main = compass->getSubWidgetMain();
|
||||
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
||||
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
||||
float angle = std::atan2(x,y);
|
||||
rotatingSubskin->setAngle(angle);
|
||||
mLastPositionX = x;
|
||||
mLastPositionY = y;
|
||||
}
|
||||
|
||||
void HUD::setPlayerPos(const float x, const float y)
|
||||
{
|
||||
if (!minimapBox->getVisible() || (x == mLastDirectionX && y == mLastDirectionY)) return;
|
||||
|
||||
MyGUI::IntSize size = minimap->getCanvasSize();
|
||||
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
||||
MyGUI::IntCoord viewsize = minimap->getCoord();
|
||||
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
|
||||
|
||||
minimap->setViewOffset(pos);
|
||||
compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
|
||||
|
||||
mLastDirectionX = x;
|
||||
mLastDirectionY = y;
|
||||
}
|
||||
|
||||
void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible)
|
||||
{
|
||||
int weapDx = 0, spellDx = 0;
|
||||
if (!hmsVisible)
|
||||
spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft;
|
||||
|
||||
if (!weapVisible)
|
||||
spellDx -= spellBoxBaseLeft - weapBoxBaseLeft;
|
||||
|
||||
health->setVisible(hmsVisible);
|
||||
stamina->setVisible(hmsVisible);
|
||||
magicka->setVisible(hmsVisible);
|
||||
weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop());
|
||||
weapBox->setVisible(weapVisible);
|
||||
spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop());
|
||||
spellBox->setVisible(spellVisible);
|
||||
}
|
||||
|
||||
void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible)
|
||||
{
|
||||
// effect box can have variable width -> variable left coordinate
|
||||
int effectsDx = 0;
|
||||
if (!minimapBoxVisible)
|
||||
effectsDx = minimapBoxBaseRight - effectBoxBaseRight;
|
||||
|
||||
minimapBox->setVisible(minimapBoxVisible);
|
||||
effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop());
|
||||
effectBox->setVisible(effectBoxVisible);
|
||||
}
|
||||
|
||||
LocalMapBase::LocalMapBase()
|
||||
: mCurX(0)
|
||||
, mCurY(0)
|
||||
, mInterior(false)
|
||||
, mFogOfWar(true)
|
||||
, mLocalMap(NULL)
|
||||
, mPrefix()
|
||||
, mChanged(true)
|
||||
, mLayout(NULL)
|
||||
, mLastPositionX(0.0f)
|
||||
, mLastPositionY(0.0f)
|
||||
, mLastDirectionX(0.0f)
|
||||
, mLastDirectionY(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout)
|
||||
{
|
||||
mLocalMap = widget;
|
||||
mLayout = layout;
|
||||
}
|
||||
|
||||
void LocalMapBase::setCellPrefix(const std::string& prefix)
|
||||
{
|
||||
mPrefix = prefix;
|
||||
mChanged = true;
|
||||
}
|
||||
|
||||
void LocalMapBase::toggleFogOfWar()
|
||||
{
|
||||
mFogOfWar = !mFogOfWar;
|
||||
applyFogOfWar();
|
||||
}
|
||||
|
||||
void LocalMapBase::applyFogOfWar()
|
||||
{
|
||||
for (int mx=0; mx<3; ++mx)
|
||||
{
|
||||
for (int my=0; my<3; ++my)
|
||||
{
|
||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||
+ boost::lexical_cast<std::string>(my);
|
||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
|
||||
+ boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1)));
|
||||
MyGUI::ImageBox* fog;
|
||||
mLayout->getWidget(fog, name+"_fog");
|
||||
fog->setImageTexture(mFogOfWar ?
|
||||
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
|
||||
: "black.png" )
|
||||
: "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
||||
{
|
||||
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
|
||||
for (int mx=0; mx<3; ++mx)
|
||||
{
|
||||
for (int my=0; my<3; ++my)
|
||||
{
|
||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||
+ boost::lexical_cast<std::string>(my);
|
||||
|
||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
|
||||
+ boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1)));
|
||||
|
||||
MyGUI::ImageBox* box;
|
||||
mLayout->getWidget(box, name);
|
||||
|
||||
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
|
||||
box->setImageTexture(image);
|
||||
else
|
||||
box->setImageTexture("black.png");
|
||||
}
|
||||
}
|
||||
mInterior = interior;
|
||||
mCurX = x;
|
||||
mCurY = y;
|
||||
mChanged = false;
|
||||
applyFogOfWar();
|
||||
}
|
||||
|
|
@ -1,236 +0,0 @@
|
|||
#ifndef MWGUI_LAYOUTS_H
|
||||
#define MWGUI_LAYOUTS_H
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
/*
|
||||
This file contains classes corresponding to window layouts
|
||||
defined in resources/mygui/ *.xml.
|
||||
|
||||
Each class inherites GUI::Layout and loads the XML file, and
|
||||
provides some helper functions to manipulate the elements of the
|
||||
window.
|
||||
|
||||
The windows are never created or destroyed (except at startup and
|
||||
shutdown), they are only hid. You can control visibility with
|
||||
setVisible().
|
||||
*/
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class LocalMapBase
|
||||
{
|
||||
public:
|
||||
LocalMapBase();
|
||||
void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout);
|
||||
|
||||
void setCellPrefix(const std::string& prefix);
|
||||
void setActiveCell(const int x, const int y, bool interior=false);
|
||||
|
||||
void toggleFogOfWar();
|
||||
|
||||
protected:
|
||||
int mCurX, mCurY;
|
||||
bool mInterior;
|
||||
MyGUI::ScrollView* mLocalMap;
|
||||
std::string mPrefix;
|
||||
bool mChanged;
|
||||
bool mFogOfWar;
|
||||
|
||||
void applyFogOfWar();
|
||||
|
||||
OEngine::GUI::Layout* mLayout;
|
||||
|
||||
float mLastPositionX;
|
||||
float mLastPositionY;
|
||||
float mLastDirectionX;
|
||||
float mLastDirectionY;
|
||||
};
|
||||
|
||||
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
||||
{
|
||||
public:
|
||||
HUD(int width, int height, int fpsLevel);
|
||||
void setStats(int h, int hmax, int m, int mmax, int s, int smax);
|
||||
void setWeapIcon(const char *str);
|
||||
void setSpellIcon(const char *str);
|
||||
void setWeapStatus(int s, int smax);
|
||||
void setSpellStatus(int s, int smax);
|
||||
void setEffect(const char *img);
|
||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
||||
void setFPS(float fps);
|
||||
void setTriangleCount(size_t count);
|
||||
void setBatchCount(size_t count);
|
||||
void setPlayerDir(const float x, const float y);
|
||||
void setPlayerPos(const float x, const float y);
|
||||
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
|
||||
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
|
||||
void setFpsLevel(const int level);
|
||||
|
||||
MyGUI::ProgressPtr health, magicka, stamina;
|
||||
MyGUI::Widget *weapBox, *spellBox;
|
||||
MyGUI::ImageBox *weapImage, *spellImage;
|
||||
MyGUI::ProgressPtr weapStatus, spellStatus;
|
||||
MyGUI::Widget *effectBox, *minimapBox;
|
||||
MyGUI::ImageBox* effect1;
|
||||
MyGUI::ScrollView* minimap;
|
||||
MyGUI::ImageBox* compass;
|
||||
MyGUI::ImageBox* crosshair;
|
||||
|
||||
MyGUI::WidgetPtr fpsbox;
|
||||
MyGUI::TextBox* fpscounter;
|
||||
MyGUI::TextBox* trianglecounter;
|
||||
MyGUI::TextBox* batchcounter;
|
||||
|
||||
private:
|
||||
// bottom left elements
|
||||
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
|
||||
// bottom right elements
|
||||
int minimapBoxBaseRight, effectBoxBaseRight;
|
||||
};
|
||||
|
||||
class MainMenu : public OEngine::GUI::Layout
|
||||
{
|
||||
public:
|
||||
MainMenu(int w, int h)
|
||||
: Layout("openmw_mainmenu_layout.xml")
|
||||
{
|
||||
setCoord(0,0,w,h);
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
class InventoryWindow : public OEngine::GUI::Layout
|
||||
{
|
||||
public:
|
||||
enum CategoryMode
|
||||
{
|
||||
CM_All = 0, // All items
|
||||
CM_Weapon = 1, // Only weapons
|
||||
CM_Apparel = 2, // Apparel
|
||||
CM_Magic = 3, // Magic
|
||||
CM_Misc = 4 // Misc
|
||||
};
|
||||
|
||||
InventoryWindow ()
|
||||
: Layout("openmw_inventory_window_layout.xml")
|
||||
, categoryMode(CM_All)
|
||||
|
||||
// color should be fetched from skin
|
||||
, activeColor(0, 0, 1)
|
||||
, inactiveColor(0.7, 0.7, 0.7)
|
||||
{
|
||||
setCoord(0, 200, 600, 400);
|
||||
|
||||
// These are just demo values, you should replace these with
|
||||
// real calls from outside the class later.
|
||||
|
||||
mMainWidget->setCaption("Glass Frostsword");
|
||||
setText("EncumbranceBarT", "176/210");
|
||||
|
||||
MyGUI::ProgressPtr pt;
|
||||
getWidget(pt, "EncumbranceBar");
|
||||
pt->setProgressRange(210);
|
||||
pt->setProgressPosition(176);
|
||||
|
||||
MyGUI::WidgetPtr avatar;
|
||||
getWidget(avatar, "Avatar");
|
||||
|
||||
// Adjust armor rating text to bottom of avatar widget
|
||||
MyGUI::TextBox* armor_rating;
|
||||
getWidget(armor_rating, "ArmorRating");
|
||||
armor_rating->setCaption("Armor: 11");
|
||||
MyGUI::IntCoord coord = armor_rating->getCoord();
|
||||
coord.top = avatar->getCoord().height - 4 - coord.height;
|
||||
armor_rating->setCoord(coord);
|
||||
|
||||
names[0] = "All";
|
||||
names[1] = "Weapon";
|
||||
names[2] = "Apparel";
|
||||
names[3] = "Magic";
|
||||
names[4] = "Misc";
|
||||
|
||||
boost::array<CategoryMode, 5> categories = { {
|
||||
CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc
|
||||
} };
|
||||
|
||||
// Initialize buttons with text and adjust sizes, also mark All as active button
|
||||
int margin = 2;
|
||||
int last_x = 0;
|
||||
for (int i = 0; i < categories.size(); ++i)
|
||||
{
|
||||
CategoryMode mode = categories[i];
|
||||
std::string name = names[mode];
|
||||
name += "Button";
|
||||
setText(name, names[mode]);
|
||||
getWidget(buttons[mode], name);
|
||||
|
||||
MyGUI::ButtonPtr &button_pt = buttons[mode];
|
||||
if (mode == CM_All)
|
||||
button_pt->setTextColour(activeColor);
|
||||
else
|
||||
button_pt->setTextColour(inactiveColor);
|
||||
MyGUI::IntCoord coord = button_pt->getCoord();
|
||||
coord.left = last_x;
|
||||
last_x += coord.width + margin;
|
||||
button_pt->setCoord(coord);
|
||||
|
||||
button_pt->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onCategorySelected);
|
||||
}
|
||||
}
|
||||
|
||||
void setCategory(CategoryMode mode)
|
||||
{
|
||||
MyGUI::ButtonPtr pt = getCategoryButton(categoryMode);
|
||||
pt->setTextColour(inactiveColor);
|
||||
|
||||
pt = getCategoryButton(mode);
|
||||
pt->setTextColour(activeColor);
|
||||
categoryMode = mode;
|
||||
}
|
||||
|
||||
MyGUI::ButtonPtr getCategoryButton(CategoryMode mode)
|
||||
{
|
||||
return buttons[mode];
|
||||
}
|
||||
|
||||
void onCategorySelected(MyGUI::Widget *widget)
|
||||
{
|
||||
boost::array<CategoryMode, 5> categories = { {
|
||||
CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc
|
||||
} };
|
||||
|
||||
for (int i = 0; i < categories.size(); ++i)
|
||||
{
|
||||
CategoryMode mode = categories[i];
|
||||
if (widget == buttons[mode])
|
||||
{
|
||||
setCategory(mode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CategoryMode categoryMode; // Current category filter
|
||||
MyGUI::ButtonPtr buttons[5]; // Button pointers
|
||||
std::string names[5]; // Names of category buttons
|
||||
|
||||
MyGUI::Colour activeColor;
|
||||
MyGUI::Colour inactiveColor;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
#endif
|
|
@ -28,8 +28,11 @@ void MWList::initialiseOverride()
|
|||
void MWList::addItem(const std::string& name)
|
||||
{
|
||||
mItems.push_back(name);
|
||||
}
|
||||
|
||||
redraw();
|
||||
void MWList::addSeparator()
|
||||
{
|
||||
mItems.push_back("");
|
||||
}
|
||||
|
||||
void MWList::adjustSize()
|
||||
|
@ -51,6 +54,8 @@ void MWList::redraw(bool scrollbarShown)
|
|||
mItemHeight = 0;
|
||||
for (std::vector<std::string>::const_iterator it=mItems.begin();
|
||||
it!=mItems.end(); ++it)
|
||||
{
|
||||
if (*it != "")
|
||||
{
|
||||
MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
|
||||
"MW_ListLine", MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24),
|
||||
|
@ -66,8 +71,17 @@ void MWList::redraw(bool scrollbarShown)
|
|||
|
||||
mItemHeight += height + spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
MyGUI::ImageBox* separator = mScrollView->createWidget<MyGUI::ImageBox>("MW_HLine",
|
||||
MyGUI::IntCoord(2, mItemHeight, mScrollView->getWidth()-4, 18),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||
separator->setNeedMouseFocus(false);
|
||||
|
||||
mItemHeight += 18 + spacing;
|
||||
}
|
||||
}
|
||||
mScrollView->setCanvasSize(mClient->getSize().width + (_scrollBarWidth-scrollBarWidth), std::max(mItemHeight, mClient->getSize().height));
|
||||
mScrollView->setViewOffset(MyGUI::IntPoint(0,0));
|
||||
|
||||
if (!scrollbarShown && mItemHeight > mClient->getSize().height)
|
||||
redraw(true);
|
||||
|
@ -93,15 +107,11 @@ void MWList::removeItem(const std::string& name)
|
|||
{
|
||||
assert( std::find(mItems.begin(), mItems.end(), name) != mItems.end() );
|
||||
mItems.erase( std::find(mItems.begin(), mItems.end(), name) );
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void MWList::clear()
|
||||
{
|
||||
mItems.clear();
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void MWList::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
|
|
|
@ -26,15 +26,16 @@ namespace MWGui
|
|||
EventHandle_String eventItemSelected;
|
||||
|
||||
/**
|
||||
* Call after the size of the list changed
|
||||
* Call after the size of the list changed, or items were inserted/removed
|
||||
*/
|
||||
void adjustSize();
|
||||
|
||||
void addItem(const std::string& name);
|
||||
void addSeparator(); ///< add a seperator between the current and the next item.
|
||||
void removeItem(const std::string& name);
|
||||
bool hasItem(const std::string& name);
|
||||
unsigned int getItemCount();
|
||||
std::string getItemNameAt(unsigned int at);
|
||||
std::string getItemNameAt(unsigned int at); ///< \attention if there are separators, this method will return "" at the place where the separator is
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
|
|
16
apps/openmw/mwgui/mainmenu.hpp
Normal file
16
apps/openmw/mwgui/mainmenu.hpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include <openengine/gui/layout.hpp>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class MainMenu : public OEngine::GUI::Layout
|
||||
{
|
||||
public:
|
||||
MainMenu(int w, int h)
|
||||
: Layout("openmw_mainmenu_layout.xml")
|
||||
{
|
||||
setCoord(0,0,w,h);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,27 +1,164 @@
|
|||
#include "map_window.hpp"
|
||||
#include "window_manager.hpp"
|
||||
/*
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
*/
|
||||
using namespace MWGui;
|
||||
|
||||
LocalMapBase::LocalMapBase()
|
||||
: mCurX(0)
|
||||
, mCurY(0)
|
||||
, mInterior(false)
|
||||
, mFogOfWar(true)
|
||||
, mLocalMap(NULL)
|
||||
, mMapDragAndDrop(false)
|
||||
, mPrefix()
|
||||
, mChanged(true)
|
||||
, mLayout(NULL)
|
||||
, mLastPositionX(0.0f)
|
||||
, mLastPositionY(0.0f)
|
||||
, mLastDirectionX(0.0f)
|
||||
, mLastDirectionY(0.0f)
|
||||
, mCompass(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop)
|
||||
{
|
||||
mLocalMap = widget;
|
||||
mLayout = layout;
|
||||
mMapDragAndDrop = mapDragAndDrop;
|
||||
mCompass = compass;
|
||||
|
||||
// create 3x3 map widgets, 512x512 each, holding a 1024x1024 texture each
|
||||
const int widgetSize = 512;
|
||||
for (int mx=0; mx<3; ++mx)
|
||||
{
|
||||
for (int my=0; my<3; ++my)
|
||||
{
|
||||
MyGUI::ImageBox* map = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||
MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize),
|
||||
MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast<std::string>(mx) + "_" + boost::lexical_cast<std::string>(my));
|
||||
|
||||
MyGUI::ImageBox* fog = map->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||
MyGUI::IntCoord(0, 0, widgetSize, widgetSize),
|
||||
MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast<std::string>(mx) + "_" + boost::lexical_cast<std::string>(my) + "_fog");
|
||||
|
||||
if (!mMapDragAndDrop)
|
||||
{
|
||||
map->setNeedMouseFocus(false);
|
||||
fog->setNeedMouseFocus(false);
|
||||
}
|
||||
|
||||
mMapWidgets.push_back(map);
|
||||
mFogWidgets.push_back(fog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalMapBase::setCellPrefix(const std::string& prefix)
|
||||
{
|
||||
mPrefix = prefix;
|
||||
mChanged = true;
|
||||
}
|
||||
|
||||
void LocalMapBase::toggleFogOfWar()
|
||||
{
|
||||
mFogOfWar = !mFogOfWar;
|
||||
applyFogOfWar();
|
||||
}
|
||||
|
||||
void LocalMapBase::applyFogOfWar()
|
||||
{
|
||||
for (int mx=0; mx<3; ++mx)
|
||||
{
|
||||
for (int my=0; my<3; ++my)
|
||||
{
|
||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||
+ boost::lexical_cast<std::string>(my);
|
||||
|
||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
|
||||
+ boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1)));
|
||||
MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx];
|
||||
fog->setImageTexture(mFogOfWar ?
|
||||
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
|
||||
: "black.png" )
|
||||
: "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
||||
{
|
||||
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
|
||||
for (int mx=0; mx<3; ++mx)
|
||||
{
|
||||
for (int my=0; my<3; ++my)
|
||||
{
|
||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
|
||||
+ boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1)));
|
||||
|
||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||
+ boost::lexical_cast<std::string>(my);
|
||||
|
||||
MyGUI::ImageBox* box = mMapWidgets[my + 3*mx];
|
||||
|
||||
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
|
||||
box->setImageTexture(image);
|
||||
else
|
||||
box->setImageTexture("black.png");
|
||||
}
|
||||
}
|
||||
mInterior = interior;
|
||||
mCurX = x;
|
||||
mCurY = y;
|
||||
mChanged = false;
|
||||
applyFogOfWar();
|
||||
|
||||
// set the compass texture again, because MyGUI determines sorting of ImageBox widgets
|
||||
// based on the last setImageTexture call
|
||||
std::string tex = "textures\\compass.dds";
|
||||
mCompass->setImageTexture("");
|
||||
mCompass->setImageTexture(tex);
|
||||
}
|
||||
|
||||
|
||||
void LocalMapBase::setPlayerPos(const float x, const float y)
|
||||
{
|
||||
if (x == mLastPositionX && y == mLastPositionY)
|
||||
return;
|
||||
MyGUI::IntSize size = mLocalMap->getCanvasSize();
|
||||
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
||||
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
|
||||
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
|
||||
mLocalMap->setViewOffset(pos);
|
||||
|
||||
mCompass->setPosition(MyGUI::IntPoint(512+x*512-16, 512+y*512-16));
|
||||
mLastPositionX = x;
|
||||
mLastPositionY = y;
|
||||
}
|
||||
|
||||
void LocalMapBase::setPlayerDir(const float x, const float y)
|
||||
{
|
||||
if (x == mLastDirectionX && y == mLastDirectionY)
|
||||
return;
|
||||
MyGUI::ISubWidget* main = mCompass->getSubWidgetMain();
|
||||
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
||||
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
||||
float angle = std::atan2(x,y);
|
||||
rotatingSubskin->setAngle(angle);
|
||||
|
||||
mLastDirectionX = x;
|
||||
mLastDirectionY = y;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
MapWindow::MapWindow(WindowManager& parWindowManager) :
|
||||
MWGui::WindowPinnableBase("openmw_map_window_layout.xml", parWindowManager),
|
||||
mGlobal(false)
|
||||
{
|
||||
setCoord(500,0,320,300);
|
||||
setText("WorldButton", "World");
|
||||
setImage("Compass", "textures\\compass.dds");
|
||||
|
||||
// Obviously you should override this later on
|
||||
setCellName("No Cell Loaded");
|
||||
|
||||
getWidget(mLocalMap, "LocalMap");
|
||||
getWidget(mGlobalMap, "GlobalMap");
|
||||
|
@ -29,7 +166,7 @@ MapWindow::MapWindow(WindowManager& parWindowManager) :
|
|||
|
||||
getWidget(mButton, "WorldButton");
|
||||
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
||||
mButton->setCaption(mWindowManager.getGameSettingString("sWorld", ""));
|
||||
mButton->setCaptionWithReplacing("#{sWorld}");
|
||||
int width = mButton->getTextSize().width + 24;
|
||||
mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22);
|
||||
|
||||
|
@ -38,40 +175,12 @@ MapWindow::MapWindow(WindowManager& parWindowManager) :
|
|||
eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||
eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||
|
||||
LocalMapBase::init(mLocalMap, this);
|
||||
LocalMapBase::init(mLocalMap, mPlayerArrow, this);
|
||||
}
|
||||
|
||||
void MapWindow::setCellName(const std::string& cellName)
|
||||
{
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName);
|
||||
adjustWindowCaption();
|
||||
}
|
||||
|
||||
void MapWindow::setPlayerPos(const float x, const float y)
|
||||
{
|
||||
if (mGlobal || !mVisible || (x == mLastPositionX && y == mLastPositionY)) return;
|
||||
MyGUI::IntSize size = mLocalMap->getCanvasSize();
|
||||
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
||||
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
|
||||
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
|
||||
mLocalMap->setViewOffset(pos);
|
||||
|
||||
mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
|
||||
mLastPositionX = x;
|
||||
mLastPositionY = y;
|
||||
}
|
||||
|
||||
void MapWindow::setPlayerDir(const float x, const float y)
|
||||
{
|
||||
if (!mVisible || (x == mLastDirectionX && y == mLastDirectionY)) return;
|
||||
MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain();
|
||||
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
||||
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
||||
float angle = std::atan2(x,y);
|
||||
rotatingSubskin->setAngle(angle);
|
||||
|
||||
mLastDirectionX = x;
|
||||
mLastDirectionY = y;
|
||||
setTitle(cellName);
|
||||
}
|
||||
|
||||
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
||||
|
@ -100,8 +209,8 @@ void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
|
|||
mGlobalMap->setVisible(mGlobal);
|
||||
mLocalMap->setVisible(!mGlobal);
|
||||
|
||||
mButton->setCaption( mGlobal ? mWindowManager.getGameSettingString("sWorld", "") :
|
||||
mWindowManager.getGameSettingString("sLocal", ""));
|
||||
mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" :
|
||||
"#{sWorld}");
|
||||
int width = mButton->getTextSize().width + 24;
|
||||
mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22);
|
||||
}
|
||||
|
|
|
@ -1,19 +1,53 @@
|
|||
#ifndef MWGUI_MAPWINDOW_H
|
||||
#define MWGUI_MAPWINDOW_H
|
||||
|
||||
#include "layouts.hpp"
|
||||
#include "window_pinnable_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class LocalMapBase
|
||||
{
|
||||
public:
|
||||
LocalMapBase();
|
||||
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop=false);
|
||||
|
||||
void setCellPrefix(const std::string& prefix);
|
||||
void setActiveCell(const int x, const int y, bool interior=false);
|
||||
void setPlayerDir(const float x, const float y);
|
||||
void setPlayerPos(const float x, const float y);
|
||||
|
||||
void toggleFogOfWar();
|
||||
|
||||
protected:
|
||||
int mCurX, mCurY;
|
||||
bool mInterior;
|
||||
MyGUI::ScrollView* mLocalMap;
|
||||
MyGUI::ImageBox* mCompass;
|
||||
std::string mPrefix;
|
||||
bool mChanged;
|
||||
bool mFogOfWar;
|
||||
|
||||
std::vector<MyGUI::ImageBox*> mMapWidgets;
|
||||
std::vector<MyGUI::ImageBox*> mFogWidgets;
|
||||
|
||||
void applyFogOfWar();
|
||||
|
||||
OEngine::GUI::Layout* mLayout;
|
||||
|
||||
bool mMapDragAndDrop;
|
||||
|
||||
float mLastPositionX;
|
||||
float mLastPositionY;
|
||||
float mLastDirectionX;
|
||||
float mLastDirectionY;
|
||||
};
|
||||
|
||||
class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase
|
||||
{
|
||||
public:
|
||||
MapWindow(WindowManager& parWindowManager);
|
||||
virtual ~MapWindow(){}
|
||||
|
||||
void setPlayerPos(const float x, const float y);
|
||||
void setPlayerDir(const float x, const float y);
|
||||
void setCellName(const std::string& cellName);
|
||||
|
||||
private:
|
||||
|
|
|
@ -15,6 +15,13 @@ void MessageBoxManager::onFrame (float frameDuration)
|
|||
std::vector<MessageBoxManagerTimer>::iterator it;
|
||||
for(it = mTimers.begin(); it != mTimers.end();)
|
||||
{
|
||||
// if this messagebox is already deleted, remove the timer and move on
|
||||
if (std::find(mMessageBoxes.begin(), mMessageBoxes.end(), it->messageBox) == mMessageBoxes.end())
|
||||
{
|
||||
it = mTimers.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
it->current += frameDuration;
|
||||
if(it->current >= it->max)
|
||||
{
|
||||
|
@ -51,7 +58,7 @@ void MessageBoxManager::onFrame (float frameDuration)
|
|||
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
|
||||
delete mInterMessageBoxe;
|
||||
mInterMessageBoxe = NULL;
|
||||
mWindowManager->setNextMode(GM_Game);
|
||||
mWindowManager->removeGuiMode(GM_InterMessageBox);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,13 +86,12 @@ void MessageBoxManager::createMessageBox (const std::string& message)
|
|||
|
||||
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
|
||||
{
|
||||
/// \todo Don't write this kind of error message to cout. Either discard the old message box
|
||||
/// silently or throw an exception.
|
||||
if(mInterMessageBoxe != NULL) {
|
||||
std::cout << "there is a MessageBox already" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "interactive MessageBox: " << message << " - ";
|
||||
std::copy (buttons.begin(), buttons.end(), std::ostream_iterator<std::string> (std::cout, ", "));
|
||||
std::cout << std::endl;
|
||||
|
||||
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
|
||||
|
||||
|
@ -154,7 +160,7 @@ MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::strin
|
|||
getWidget(mMessageWidget, "message");
|
||||
|
||||
mMessageWidget->setOverflowToTheLeft(true);
|
||||
mMessageWidget->addText(cMessage);
|
||||
mMessageWidget->setCaptionWithReplacing(cMessage);
|
||||
|
||||
MyGUI::IntSize size;
|
||||
size.width = mFixedWidth;
|
||||
|
@ -259,11 +265,8 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
|
|||
if(buttonsWidth < fixedWidth)
|
||||
{
|
||||
// on one line
|
||||
std::cout << "on one line" << std::endl;
|
||||
|
||||
if(textSize.width + 2*textPadding < buttonsWidth)
|
||||
{
|
||||
std::cout << "width = buttonsWidth" << std::endl;
|
||||
mainWidgetSize.width = buttonsWidth;
|
||||
}
|
||||
else
|
||||
|
@ -276,13 +279,9 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
|
|||
absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2;
|
||||
absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2;
|
||||
|
||||
std::cout << "width " << mainWidgetSize.width << " height " << mainWidgetSize.height << std::endl;
|
||||
std::cout << "left " << absCoord.left << " top " << absCoord.top << std::endl;
|
||||
|
||||
mMainWidget->setCoord(absCoord);
|
||||
mMainWidget->setSize(mainWidgetSize);
|
||||
|
||||
|
||||
MyGUI::IntCoord messageWidgetCoord;
|
||||
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
|
||||
messageWidgetCoord.top = textPadding;
|
||||
|
@ -312,7 +311,6 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
|
|||
else
|
||||
{
|
||||
// among each other
|
||||
|
||||
if(biggestButtonWidth > textSize.width) {
|
||||
mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
|
||||
}
|
||||
|
@ -321,8 +319,6 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
|
|||
}
|
||||
mainWidgetSize.height = textSize.height + 2*textPadding + textButtonPadding + buttonHeight * buttons.size() + buttonMainPadding;
|
||||
|
||||
std::cout << "biggestButtonWidth " << biggestButtonWidth << " textSize.width " << textSize.width << std::endl;
|
||||
std::cout << "width " << mainWidgetSize.width << " height " << mainWidgetSize.height << std::endl;
|
||||
mMainWidget->setSize(mainWidgetSize);
|
||||
|
||||
MyGUI::IntCoord absCoord;
|
||||
|
@ -377,7 +373,6 @@ void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
|
|||
}
|
||||
index++;
|
||||
}
|
||||
std::cout << "Cant be possible :/" << std::endl;
|
||||
}
|
||||
|
||||
int InteractiveMessageBox::readPressedButton ()
|
||||
|
|
|
@ -5,8 +5,9 @@ namespace MWGui
|
|||
{
|
||||
enum GuiMode
|
||||
{
|
||||
GM_Game, // Game mode, only HUD
|
||||
GM_Settings, // Settings window
|
||||
GM_Inventory, // Inventory mode
|
||||
GM_Container,
|
||||
GM_MainMenu, // Main menu mode
|
||||
|
||||
GM_Console, // Console mode
|
||||
|
@ -14,6 +15,7 @@ namespace MWGui
|
|||
|
||||
GM_Scroll, // Read scroll
|
||||
GM_Book, // Read book
|
||||
GM_Alchemy, // Make potions
|
||||
|
||||
GM_Dialogue, // NPC interaction
|
||||
GM_Barter,
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#include "race.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "components/esm_store/store.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
@ -10,6 +7,12 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace Widgets;
|
||||
|
||||
|
@ -51,7 +54,7 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager)
|
|||
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace);
|
||||
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace);
|
||||
|
||||
setText("HairChoiceT", mWindowManager.getGameSettingString("sRaceMenu3", "Change Hair"));
|
||||
setText("HairChoiceT", mWindowManager.getGameSettingString("sRaceMenu4", "Change Hair"));
|
||||
getWidget(prevButton, "PrevHairButton");
|
||||
getWidget(nextButton, "NextHairButton");
|
||||
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair);
|
||||
|
@ -71,7 +74,6 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager)
|
|||
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked);
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
|
@ -256,6 +258,8 @@ void RaceDialog::updateSkills()
|
|||
skillWidget->setWindowManager(&mWindowManager);
|
||||
skillWidget->setSkillNumber(skillId);
|
||||
skillWidget->setSkillValue(MWSkill::SkillValue(race->data.bonus[i].bonus));
|
||||
ToolTips::createSkillToolTip(skillWidget, skillId);
|
||||
|
||||
|
||||
skillItems.push_back(skillWidget);
|
||||
|
||||
|
@ -289,6 +293,8 @@ void RaceDialog::updateSpellPowers()
|
|||
spellPowerWidget = spellPowerList->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i));
|
||||
spellPowerWidget->setWindowManager(&mWindowManager);
|
||||
spellPowerWidget->setSpellId(spellpower);
|
||||
spellPowerWidget->setUserString("ToolTipType", "Spell");
|
||||
spellPowerWidget->setUserString("Spell", spellpower);
|
||||
|
||||
spellPowerItems.push_back(spellPowerWidget);
|
||||
|
||||
|
|
28
apps/openmw/mwgui/referenceinterface.cpp
Normal file
28
apps/openmw/mwgui/referenceinterface.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "referenceinterface.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
ReferenceInterface::ReferenceInterface()
|
||||
: mCurrentPlayerCell(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void ReferenceInterface::checkReferenceAvailable()
|
||||
{
|
||||
if (mPtr.isEmpty())
|
||||
return;
|
||||
|
||||
MWWorld::Ptr::CellStore* playerCell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell();
|
||||
|
||||
// check if player has changed cell, or count of the reference has become 0
|
||||
if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL)
|
||||
|| mPtr.getRefData().getCount() == 0)
|
||||
onReferenceUnavailable();
|
||||
|
||||
mCurrentPlayerCell = playerCell;
|
||||
}
|
||||
}
|
29
apps/openmw/mwgui/referenceinterface.hpp
Normal file
29
apps/openmw/mwgui/referenceinterface.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef MWGUI_REFERENCEINTERFACE_H
|
||||
#define MWGUI_REFERENCEINTERFACE_H
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
/// \brief this class is intended for GUI interfaces that access an MW-Reference
|
||||
/// for example dialogue window accesses an NPC, or Container window accesses a Container
|
||||
/// these classes have to be automatically closed if the reference becomes unavailable
|
||||
/// make sure that checkReferenceAvailable() is called every frame and that onReferenceUnavailable() has been overridden
|
||||
class ReferenceInterface
|
||||
{
|
||||
public:
|
||||
ReferenceInterface();
|
||||
|
||||
void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable
|
||||
|
||||
protected:
|
||||
virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable
|
||||
|
||||
MWWorld::Ptr mPtr;
|
||||
|
||||
private:
|
||||
MWWorld::Ptr::CellStore* mCurrentPlayerCell;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,12 +1,15 @@
|
|||
#include "review.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "components/esm_store/store.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
@ -27,25 +30,21 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
|
|||
ButtonPtr button;
|
||||
getWidget(nameWidget, "NameText");
|
||||
getWidget(button, "NameButton");
|
||||
button->setCaption(mWindowManager.getGameSettingString("sName", ""));
|
||||
adjustButtonSize(button);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);;
|
||||
|
||||
getWidget(raceWidget, "RaceText");
|
||||
getWidget(button, "RaceButton");
|
||||
button->setCaption(mWindowManager.getGameSettingString("sRace", ""));
|
||||
adjustButtonSize(button);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);;
|
||||
|
||||
getWidget(classWidget, "ClassText");
|
||||
getWidget(button, "ClassButton");
|
||||
button->setCaption(mWindowManager.getGameSettingString("sClass", ""));
|
||||
adjustButtonSize(button);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);;
|
||||
|
||||
getWidget(birthSignWidget, "SignText");
|
||||
getWidget(button, "SignButton");
|
||||
button->setCaption(mWindowManager.getGameSettingString("sBirthSign", ""));
|
||||
adjustButtonSize(button);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);;
|
||||
|
||||
|
@ -78,7 +77,7 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
|
|||
getWidget(skillAreaWidget, "Skills");
|
||||
getWidget(skillClientWidget, "SkillClient");
|
||||
getWidget(skillScrollerWidget, "SkillScroller");
|
||||
|
||||
skillClientWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||
skillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &ReviewDialog::onScrollChangePosition);
|
||||
updateScroller();
|
||||
|
||||
|
@ -92,7 +91,6 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
|
|||
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked);
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
|
@ -142,13 +140,17 @@ void ReviewDialog::setRace(const std::string &raceId_)
|
|||
raceId = raceId_;
|
||||
const ESM::Race *race = mWindowManager.getStore().races.search(raceId);
|
||||
if (race)
|
||||
{
|
||||
ToolTips::createRaceToolTip(raceWidget, race);
|
||||
raceWidget->setCaption(race->name);
|
||||
}
|
||||
}
|
||||
|
||||
void ReviewDialog::setClass(const ESM::Class& class_)
|
||||
{
|
||||
klass = class_;
|
||||
classWidget->setCaption(klass.name);
|
||||
ToolTips::createClassToolTip(classWidget, klass);
|
||||
}
|
||||
|
||||
void ReviewDialog::setBirthSign(const std::string& signId)
|
||||
|
@ -156,22 +158,31 @@ void ReviewDialog::setBirthSign(const std::string& signId)
|
|||
birthSignId = signId;
|
||||
const ESM::BirthSign *sign = mWindowManager.getStore().birthSigns.search(birthSignId);
|
||||
if (sign)
|
||||
{
|
||||
birthSignWidget->setCaption(sign->name);
|
||||
ToolTips::createBirthsignToolTip(birthSignWidget, birthSignId);
|
||||
}
|
||||
}
|
||||
|
||||
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<int>& value)
|
||||
{
|
||||
health->setValue(value.getCurrent(), value.getModified());
|
||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||
health->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||
}
|
||||
|
||||
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<int>& value)
|
||||
{
|
||||
magicka->setValue(value.getCurrent(), value.getModified());
|
||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||
magicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||
}
|
||||
|
||||
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<int>& value)
|
||||
{
|
||||
fatigue->setValue(value.getCurrent(), value.getModified());
|
||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||
fatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||
}
|
||||
|
||||
void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value)
|
||||
|
@ -200,6 +211,7 @@ void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanic
|
|||
widget->setCaption(text);
|
||||
widget->_setWidgetState(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor)
|
||||
|
@ -219,11 +231,15 @@ void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vec
|
|||
if (skillSet.find(skill) == skillSet.end())
|
||||
miscSkills.push_back(skill);
|
||||
}
|
||||
|
||||
updateSkillArea();
|
||||
}
|
||||
|
||||
void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
|
||||
separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||
|
||||
skillWidgets.push_back(separator);
|
||||
|
||||
coord1.top += separator->getHeight();
|
||||
|
@ -233,6 +249,7 @@ void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2
|
|||
void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::TextBox* groupWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default);
|
||||
groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||
groupWidget->setCaption(label);
|
||||
skillWidgets.push_back(groupWidget);
|
||||
|
||||
|
@ -240,17 +257,19 @@ void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, M
|
|||
coord2.top += lineHeight;
|
||||
}
|
||||
|
||||
MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::TextBox* skillNameWidget;
|
||||
MyGUI::TextBox* skillValueWidget;
|
||||
|
||||
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default);
|
||||
skillNameWidget->setCaption(text);
|
||||
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||
|
||||
skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right);
|
||||
skillValueWidget->setCaption(value);
|
||||
skillValueWidget->_setWidgetState(state);
|
||||
skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||
|
||||
skillWidgets.push_back(skillNameWidget);
|
||||
skillWidgets.push_back(skillValueWidget);
|
||||
|
@ -261,12 +280,13 @@ MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::st
|
|||
return skillValueWidget;
|
||||
}
|
||||
|
||||
void ReviewDialog::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::TextBox* skillNameWidget;
|
||||
|
||||
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
|
||||
skillNameWidget->setCaption(text);
|
||||
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||
|
||||
skillWidgets.push_back(skillNameWidget);
|
||||
|
||||
|
@ -302,6 +322,12 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId
|
|||
else if (modified < base)
|
||||
state = "decreased";
|
||||
MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), state, coord1, coord2);
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
ToolTips::createSkillToolTip(skillWidgets[skillWidgets.size()-1-i], skillId);
|
||||
}
|
||||
|
||||
skillWidgetMap[skillId] = widget;
|
||||
}
|
||||
}
|
||||
|
@ -335,6 +361,8 @@ void ReviewDialog::updateScroller()
|
|||
{
|
||||
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
|
||||
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
|
||||
if (clientHeight != 0)
|
||||
skillScrollerWidget->setTrackSize( (skillAreaWidget->getHeight() / float(clientHeight)) * skillScrollerWidget->getLineSize() );
|
||||
}
|
||||
|
||||
// widget controls
|
||||
|
@ -368,3 +396,15 @@ void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender)
|
|||
{
|
||||
eventActivateDialog(BIRTHSIGN_DIALOG);
|
||||
}
|
||||
|
||||
void ReviewDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (skillScrollerWidget->getScrollPosition() - _rel*0.3 < 0)
|
||||
skillScrollerWidget->setScrollPosition(0);
|
||||
else if (skillScrollerWidget->getScrollPosition() - _rel*0.3 > skillScrollerWidget->getScrollRange()-1)
|
||||
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollRange()-1);
|
||||
else
|
||||
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollPosition() - _rel*0.3);
|
||||
|
||||
onScrollChangePosition(skillScrollerWidget, skillScrollerWidget->getScrollPosition());
|
||||
}
|
||||
|
|
|
@ -68,12 +68,14 @@ namespace MWGui
|
|||
void onClassClicked(MyGUI::Widget* _sender);
|
||||
void onBirthSignClicked(MyGUI::Widget* _sender);
|
||||
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
|
||||
private:
|
||||
void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
MyGUI::TextBox* addValueItem(const std::string text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
MyGUI::TextBox* addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void updateScroller();
|
||||
void updateSkillArea();
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
#include "scrollwindow.hpp"
|
||||
|
||||
#include "formatting.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "formatting.hpp"
|
||||
#include "window_manager.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
ScrollWindow::ScrollWindow (WindowManager& parWindowManager) :
|
||||
|
@ -25,7 +26,8 @@ ScrollWindow::ScrollWindow (WindowManager& parWindowManager) :
|
|||
|
||||
void ScrollWindow::open (MWWorld::Ptr scroll)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (scroll, "scroll", 1.0, 1.0);
|
||||
// no 3d sounds because the object could be in a container.
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
||||
|
||||
mScroll = scroll;
|
||||
|
||||
|
@ -41,21 +43,28 @@ void ScrollWindow::open (MWWorld::Ptr scroll)
|
|||
mTextView->setCanvasSize(410, mTextView->getSize().height);
|
||||
|
||||
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
|
||||
|
||||
setTakeButtonShow(true);
|
||||
}
|
||||
|
||||
void ScrollWindow::setTakeButtonShow(bool show)
|
||||
{
|
||||
mTakeButton->setVisible(show);
|
||||
}
|
||||
|
||||
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (mScroll, "scroll", 1.0, 1.0);
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||
mWindowManager.removeGuiMode(GM_Scroll);
|
||||
}
|
||||
|
||||
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (mScroll, "Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
|
||||
|
||||
MWWorld::ActionTake take(mScroll);
|
||||
take.execute();
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||
mWindowManager.removeGuiMode(GM_Scroll);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
ScrollWindow (WindowManager& parWindowManager);
|
||||
|
||||
void open (MWWorld::Ptr scroll);
|
||||
void setTakeButtonShow(bool show);
|
||||
|
||||
protected:
|
||||
void onCloseButtonClicked (MyGUI::Widget* _sender);
|
||||
|
|
349
apps/openmw/mwgui/settingswindow.cpp
Normal file
349
apps/openmw/mwgui/settingswindow.cpp
Normal file
|
@ -0,0 +1,349 @@
|
|||
#include "settingswindow.hpp"
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderSystem.h>
|
||||
#include <OgreString.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "confirmationdialog.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string fpsLevelToStr(int level)
|
||||
{
|
||||
if (level == 0)
|
||||
return "#{sOff}";
|
||||
else if (level == 1)
|
||||
return "Basic";
|
||||
else
|
||||
return "Detailed";
|
||||
}
|
||||
|
||||
std::string textureFilteringToStr(const std::string& val)
|
||||
{
|
||||
if (val == "none")
|
||||
return "None";
|
||||
else if (val == "anisotropic")
|
||||
return "Anisotropic";
|
||||
else if (val == "bilinear")
|
||||
return "Bilinear";
|
||||
else
|
||||
return "Trilinear";
|
||||
}
|
||||
|
||||
void parseResolution (int &x, int &y, const std::string& str)
|
||||
{
|
||||
std::vector<std::string> split;
|
||||
boost::algorithm::split (split, str, boost::is_any_of("x@"));
|
||||
assert (split.size() >= 2);
|
||||
boost::trim(split[0]);
|
||||
boost::trim(split[1]);
|
||||
x = boost::lexical_cast<int> (split[0]);
|
||||
y = boost::lexical_cast<int> (split[1]);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
SettingsWindow::SettingsWindow(WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_settings_window_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mOkButton, "OkButton");
|
||||
getWidget(mResolutionList, "ResolutionList");
|
||||
getWidget(mMenuTransparencySlider, "MenuTransparencySlider");
|
||||
getWidget(mToolTipDelaySlider, "ToolTipDelaySlider");
|
||||
getWidget(mViewDistanceSlider, "ViewDistanceSlider");
|
||||
getWidget(mFullscreenButton, "FullscreenButton");
|
||||
getWidget(mVSyncButton, "VSyncButton");
|
||||
getWidget(mFPSButton, "FPSButton");
|
||||
getWidget(mFOVSlider, "FOVSlider");
|
||||
getWidget(mMasterVolumeSlider, "MasterVolume");
|
||||
getWidget(mVoiceVolumeSlider, "VoiceVolume");
|
||||
getWidget(mEffectsVolumeSlider, "EffectsVolume");
|
||||
getWidget(mFootstepsVolumeSlider, "FootstepsVolume");
|
||||
getWidget(mMusicVolumeSlider, "MusicVolume");
|
||||
getWidget(mAnisotropySlider, "AnisotropySlider");
|
||||
getWidget(mTextureFilteringButton, "TextureFilteringButton");
|
||||
getWidget(mAnisotropyLabel, "AnisotropyLabel");
|
||||
getWidget(mAnisotropyBox, "AnisotropyBox");
|
||||
getWidget(mWaterShaderButton, "WaterShaderButton");
|
||||
getWidget(mReflectObjectsButton, "ReflectObjectsButton");
|
||||
getWidget(mReflectActorsButton, "ReflectActorsButton");
|
||||
getWidget(mReflectTerrainButton, "ReflectTerrainButton");
|
||||
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked);
|
||||
mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mReflectTerrainButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mReflectActorsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mTextureFilteringButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onTextureFilteringToggled);
|
||||
mVSyncButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mFPSButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onFpsToggled);
|
||||
mMenuTransparencySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mFOVSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mToolTipDelaySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
|
||||
mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
|
||||
mMasterVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mVoiceVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mEffectsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mFootstepsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mMusicVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
|
||||
center();
|
||||
|
||||
int okSize = mOkButton->getTextSize().width + 24;
|
||||
mOkButton->setCoord(mMainWidget->getWidth()-16-okSize, mOkButton->getTop(),
|
||||
okSize, mOkButton->getHeight());
|
||||
|
||||
// fill resolution list
|
||||
Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
|
||||
const Ogre::StringVector& videoModes = rs->getConfigOptions()["Video Mode"].possibleValues;
|
||||
for (Ogre::StringVector::const_iterator it=videoModes.begin();
|
||||
it!=videoModes.end(); ++it)
|
||||
{
|
||||
int resX, resY;
|
||||
parseResolution (resX, resY, *it);
|
||||
std::string str = boost::lexical_cast<std::string>(resX) + " x " + boost::lexical_cast<std::string>(resY);
|
||||
|
||||
if (mResolutionList->findItemIndexWith(str) == MyGUI::ITEM_NONE)
|
||||
mResolutionList->addItem(str);
|
||||
}
|
||||
|
||||
// read settings
|
||||
int menu_transparency = (mMenuTransparencySlider->getScrollRange()-1) * Settings::Manager::getFloat("menu transparency", "GUI");
|
||||
mMenuTransparencySlider->setScrollPosition(menu_transparency);
|
||||
int tooltip_delay = (mToolTipDelaySlider->getScrollRange()-1) * Settings::Manager::getFloat("tooltip delay", "GUI");
|
||||
mToolTipDelaySlider->setScrollPosition(tooltip_delay);
|
||||
|
||||
float fovVal = (Settings::Manager::getFloat("field of view", "General")-sFovMin)/(sFovMax-sFovMin);
|
||||
mFOVSlider->setScrollPosition(fovVal * (mFOVSlider->getScrollRange()-1));
|
||||
MyGUI::TextBox* fovText;
|
||||
getWidget(fovText, "FovText");
|
||||
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getFloat("field of view", "General"))) + ")");
|
||||
|
||||
float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0;
|
||||
mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1));
|
||||
std::string tf = Settings::Manager::getString("texture filtering", "General");
|
||||
mTextureFilteringButton->setCaption(textureFilteringToStr(tf));
|
||||
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(Settings::Manager::getInt("anisotropy", "General")) + ")");
|
||||
mAnisotropyBox->setVisible(tf == "anisotropic");
|
||||
|
||||
float val = (Settings::Manager::getFloat("max viewing distance", "Viewing distance")-sViewDistMin)/(sViewDistMax-sViewDistMin);
|
||||
int viewdist = (mViewDistanceSlider->getScrollRange()-1) * val;
|
||||
mViewDistanceSlider->setScrollPosition(viewdist);
|
||||
|
||||
mMasterVolumeSlider->setScrollPosition(Settings::Manager::getFloat("master volume", "Sound") * (mMasterVolumeSlider->getScrollRange()-1));
|
||||
mMusicVolumeSlider->setScrollPosition(Settings::Manager::getFloat("music volume", "Sound") * (mMusicVolumeSlider->getScrollRange()-1));
|
||||
mEffectsVolumeSlider->setScrollPosition(Settings::Manager::getFloat("sfx volume", "Sound") * (mEffectsVolumeSlider->getScrollRange()-1));
|
||||
mFootstepsVolumeSlider->setScrollPosition(Settings::Manager::getFloat("footsteps volume", "Sound") * (mFootstepsVolumeSlider->getScrollRange()-1));
|
||||
mVoiceVolumeSlider->setScrollPosition(Settings::Manager::getFloat("voice volume", "Sound") * (mVoiceVolumeSlider->getScrollRange()-1));
|
||||
|
||||
mWaterShaderButton->setCaptionWithReplacing(Settings::Manager::getBool("shader", "Water") ? "#{sOn}" : "#{sOff}");
|
||||
mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect objects", "Water") ? "#{sOn}" : "#{sOff}");
|
||||
mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}");
|
||||
mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}");
|
||||
|
||||
if (!MWRender::RenderingManager::waterShaderSupported())
|
||||
{
|
||||
mWaterShaderButton->setEnabled(false);
|
||||
mReflectObjectsButton->setEnabled(false);
|
||||
mReflectActorsButton->setEnabled(false);
|
||||
mReflectTerrainButton->setEnabled(false);
|
||||
}
|
||||
|
||||
mFullscreenButton->setCaptionWithReplacing(Settings::Manager::getBool("fullscreen", "Video") ? "#{sOn}" : "#{sOff}");
|
||||
mVSyncButton->setCaptionWithReplacing(Settings::Manager::getBool("vsync", "Video") ? "#{sOn}": "#{sOff}");
|
||||
mFPSButton->setCaptionWithReplacing(fpsLevelToStr(Settings::Manager::getInt("fps", "HUD")));
|
||||
}
|
||||
|
||||
void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
mWindowManager.removeGuiMode(GM_Settings);
|
||||
}
|
||||
|
||||
void SettingsWindow::onResolutionSelected(MyGUI::ListBox* _sender, size_t index)
|
||||
{
|
||||
if (index == MyGUI::ITEM_NONE)
|
||||
return;
|
||||
|
||||
ConfirmationDialog* dialog = mWindowManager.getConfirmationDialog();
|
||||
dialog->open("#{sNotifyMessage67}");
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionAccept);
|
||||
dialog->eventCancelClicked.clear();
|
||||
dialog->eventCancelClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionAccept);
|
||||
}
|
||||
|
||||
void SettingsWindow::onResolutionAccept()
|
||||
{
|
||||
std::string resStr = mResolutionList->getItemNameAt(mResolutionList->getIndexSelected());
|
||||
int resX, resY;
|
||||
parseResolution (resX, resY, resStr);
|
||||
|
||||
Settings::Manager::setInt("resolution x", "Video", resX);
|
||||
Settings::Manager::setInt("resolution y", "Video", resY);
|
||||
|
||||
apply();
|
||||
mResolutionList->setIndexSelected(MyGUI::ITEM_NONE);
|
||||
}
|
||||
|
||||
void SettingsWindow::onResolutionCancel()
|
||||
{
|
||||
mResolutionList->setIndexSelected(MyGUI::ITEM_NONE);
|
||||
}
|
||||
|
||||
void SettingsWindow::onButtonToggled(MyGUI::Widget* _sender)
|
||||
{
|
||||
std::string on = mWindowManager.getGameSettingString("sOn", "On");
|
||||
std::string off = mWindowManager.getGameSettingString("sOff", "On");
|
||||
bool newState;
|
||||
if (_sender->castType<MyGUI::Button>()->getCaption() == on)
|
||||
{
|
||||
_sender->castType<MyGUI::Button>()->setCaption(off);
|
||||
newState = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sender->castType<MyGUI::Button>()->setCaption(on);
|
||||
newState = true;
|
||||
}
|
||||
|
||||
if (_sender == mFullscreenButton)
|
||||
{
|
||||
// check if this resolution is supported in fullscreen
|
||||
bool supported = false;
|
||||
for (unsigned int i=0; i<mResolutionList->getItemCount(); ++i)
|
||||
{
|
||||
std::string resStr = mResolutionList->getItemNameAt(i);
|
||||
int resX, resY;
|
||||
parseResolution (resX, resY, resStr);
|
||||
|
||||
if (resX == Settings::Manager::getInt("resolution x", "Video")
|
||||
&& resY == Settings::Manager::getInt("resolution y", "Video"))
|
||||
supported = true;
|
||||
}
|
||||
|
||||
if (!supported)
|
||||
{
|
||||
std::string msg = "This resolution is not supported in Fullscreen mode. Please select a resolution from the list.";
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(msg, std::vector<std::string>());
|
||||
_sender->castType<MyGUI::Button>()->setCaption(off);
|
||||
}
|
||||
else
|
||||
{
|
||||
Settings::Manager::setBool("fullscreen", "Video", newState);
|
||||
apply();
|
||||
}
|
||||
}
|
||||
else if (_sender == mVSyncButton)
|
||||
{
|
||||
Settings::Manager::setBool("vsync", "Video", newState);
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("VSync will be applied after a restart", std::vector<std::string>());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_sender == mWaterShaderButton)
|
||||
Settings::Manager::setBool("shader", "Water", newState);
|
||||
else if (_sender == mReflectObjectsButton)
|
||||
{
|
||||
Settings::Manager::setBool("reflect misc", "Water", newState);
|
||||
Settings::Manager::setBool("reflect statics", "Water", newState);
|
||||
Settings::Manager::setBool("reflect statics small", "Water", newState);
|
||||
}
|
||||
else if (_sender == mReflectActorsButton)
|
||||
Settings::Manager::setBool("reflect actors", "Water", newState);
|
||||
else if (_sender == mReflectTerrainButton)
|
||||
Settings::Manager::setBool("reflect terrain", "Water", newState);
|
||||
|
||||
apply();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsWindow::onFpsToggled(MyGUI::Widget* _sender)
|
||||
{
|
||||
int newLevel = (Settings::Manager::getInt("fps", "HUD") + 1) % 3;
|
||||
Settings::Manager::setInt("fps", "HUD", newLevel);
|
||||
mFPSButton->setCaptionWithReplacing(fpsLevelToStr(newLevel));
|
||||
apply();
|
||||
}
|
||||
|
||||
void SettingsWindow::onTextureFilteringToggled(MyGUI::Widget* _sender)
|
||||
{
|
||||
std::string current = Settings::Manager::getString("texture filtering", "General");
|
||||
std::string next;
|
||||
if (current == "none")
|
||||
next = "bilinear";
|
||||
else if (current == "bilinear")
|
||||
next = "trilinear";
|
||||
else if (current == "trilinear")
|
||||
next = "anisotropic";
|
||||
else
|
||||
next = "none";
|
||||
|
||||
mTextureFilteringButton->setCaption(textureFilteringToStr(next));
|
||||
mAnisotropyBox->setVisible(next == "anisotropic");
|
||||
|
||||
Settings::Manager::setString("texture filtering", "General", next);
|
||||
apply();
|
||||
}
|
||||
|
||||
void SettingsWindow::onSliderChangePosition(MyGUI::ScrollBar* scroller, size_t pos)
|
||||
{
|
||||
float val = pos / float(scroller->getScrollRange()-1);
|
||||
if (scroller == mMenuTransparencySlider)
|
||||
Settings::Manager::setFloat("menu transparency", "GUI", val);
|
||||
else if (scroller == mToolTipDelaySlider)
|
||||
Settings::Manager::setFloat("tooltip delay", "GUI", val);
|
||||
else if (scroller == mViewDistanceSlider)
|
||||
Settings::Manager::setFloat("max viewing distance", "Viewing distance", (1-val) * sViewDistMin + val * sViewDistMax);
|
||||
else if (scroller == mFOVSlider)
|
||||
{
|
||||
MyGUI::TextBox* fovText;
|
||||
getWidget(fovText, "FovText");
|
||||
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int((1-val) * sFovMin + val * sFovMax)) + ")");
|
||||
Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax);
|
||||
}
|
||||
else if (scroller == mAnisotropySlider)
|
||||
{
|
||||
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")");
|
||||
Settings::Manager::setInt("anisotropy", "General", val * 16);
|
||||
}
|
||||
else if (scroller == mMasterVolumeSlider)
|
||||
Settings::Manager::setFloat("master volume", "Sound", val);
|
||||
else if (scroller == mVoiceVolumeSlider)
|
||||
Settings::Manager::setFloat("voice volume", "Sound", val);
|
||||
else if (scroller == mEffectsVolumeSlider)
|
||||
Settings::Manager::setFloat("sfx volume", "Sound", val);
|
||||
else if (scroller == mFootstepsVolumeSlider)
|
||||
Settings::Manager::setFloat("footsteps volume", "Sound", val);
|
||||
else if (scroller == mMusicVolumeSlider)
|
||||
Settings::Manager::setFloat("music volume", "Sound", val);
|
||||
|
||||
apply();
|
||||
}
|
||||
|
||||
void SettingsWindow::apply()
|
||||
{
|
||||
const Settings::CategorySettingVector changed = Settings::Manager::apply();
|
||||
MWBase::Environment::get().getWorld()->processChangedSettings(changed);
|
||||
MWBase::Environment::get().getSoundManager()->processChangedSettings(changed);
|
||||
MWBase::Environment::get().getWindowManager()->processChangedSettings(changed);
|
||||
MWBase::Environment::get().getInputManager()->processChangedSettings(changed);
|
||||
}
|
||||
}
|
67
apps/openmw/mwgui/settingswindow.hpp
Normal file
67
apps/openmw/mwgui/settingswindow.hpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef MWGUI_SETTINGS_H
|
||||
#define MWGUI_SETTINGS_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class WindowManager;
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class SettingsWindow : public WindowBase
|
||||
{
|
||||
public:
|
||||
SettingsWindow(WindowManager& parWindowManager);
|
||||
|
||||
private:
|
||||
static int const sFovMin = 30;
|
||||
static int const sFovMax = 140;
|
||||
static int const sViewDistMin = 2000;
|
||||
static int const sViewDistMax = 5600;
|
||||
|
||||
protected:
|
||||
MyGUI::Button* mOkButton;
|
||||
|
||||
MyGUI::ScrollBar* mMenuTransparencySlider;
|
||||
MyGUI::ScrollBar* mToolTipDelaySlider;
|
||||
|
||||
// graphics
|
||||
MyGUI::ListBox* mResolutionList;
|
||||
MyGUI::Button* mFullscreenButton;
|
||||
MyGUI::Button* mVSyncButton;
|
||||
MyGUI::Button* mFPSButton;
|
||||
MyGUI::ScrollBar* mViewDistanceSlider;
|
||||
MyGUI::ScrollBar* mFOVSlider;
|
||||
MyGUI::ScrollBar* mAnisotropySlider;
|
||||
MyGUI::Button* mTextureFilteringButton;
|
||||
MyGUI::TextBox* mAnisotropyLabel;
|
||||
MyGUI::Widget* mAnisotropyBox;
|
||||
MyGUI::Button* mWaterShaderButton;
|
||||
MyGUI::Button* mReflectObjectsButton;
|
||||
MyGUI::Button* mReflectActorsButton;
|
||||
MyGUI::Button* mReflectTerrainButton;
|
||||
|
||||
// audio
|
||||
MyGUI::ScrollBar* mMasterVolumeSlider;
|
||||
MyGUI::ScrollBar* mVoiceVolumeSlider;
|
||||
MyGUI::ScrollBar* mEffectsVolumeSlider;
|
||||
MyGUI::ScrollBar* mFootstepsVolumeSlider;
|
||||
MyGUI::ScrollBar* mMusicVolumeSlider;
|
||||
|
||||
void onOkButtonClicked(MyGUI::Widget* _sender);
|
||||
void onFpsToggled(MyGUI::Widget* _sender);
|
||||
void onTextureFilteringToggled(MyGUI::Widget* _sender);
|
||||
void onSliderChangePosition(MyGUI::ScrollBar* scroller, size_t pos);
|
||||
void onButtonToggled(MyGUI::Widget* _sender);
|
||||
void onResolutionSelected(MyGUI::ListBox* _sender, size_t index);
|
||||
void onResolutionAccept();
|
||||
void onResolutionCancel();
|
||||
|
||||
void apply();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
461
apps/openmw/mwgui/spellwindow.cpp
Normal file
461
apps/openmw/mwgui/spellwindow.cpp
Normal file
|
@ -0,0 +1,461 @@
|
|||
#include "spellwindow.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwmechanics/spells.hpp"
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/spellsuccess.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
#include "confirmationdialog.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
bool sortSpells(const std::string& left, const std::string& right)
|
||||
{
|
||||
const ESM::Spell* a = MWBase::Environment::get().getWorld()->getStore().spells.find(left);
|
||||
const ESM::Spell* b = MWBase::Environment::get().getWorld()->getStore().spells.find(right);
|
||||
|
||||
int cmp = a->name.compare(b->name);
|
||||
return cmp < 0;
|
||||
}
|
||||
|
||||
bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right)
|
||||
{
|
||||
int cmp = MWWorld::Class::get(left).getName(left).compare(
|
||||
MWWorld::Class::get(right).getName(right));
|
||||
return cmp < 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
SpellWindow::SpellWindow(WindowManager& parWindowManager)
|
||||
: WindowPinnableBase("openmw_spell_window_layout.xml", parWindowManager)
|
||||
, mHeight(0)
|
||||
, mWidth(0)
|
||||
{
|
||||
getWidget(mSpellView, "SpellView");
|
||||
getWidget(mEffectBox, "EffectsBox");
|
||||
|
||||
setCoord(498, 300, 302, 300);
|
||||
|
||||
updateSpells();
|
||||
|
||||
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SpellWindow::onWindowResize);
|
||||
}
|
||||
|
||||
void SpellWindow::onPinToggled()
|
||||
{
|
||||
mWindowManager.setSpellVisibility(!mPinned);
|
||||
}
|
||||
|
||||
void SpellWindow::open()
|
||||
{
|
||||
updateSpells();
|
||||
}
|
||||
|
||||
void SpellWindow::updateSpells()
|
||||
{
|
||||
const int spellHeight = 18;
|
||||
|
||||
mHeight = 0;
|
||||
while (mSpellView->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(mSpellView->getChildAt(0));
|
||||
|
||||
// retrieve all player spells, divide them into Powers and Spells and sort them
|
||||
std::vector<std::string> spellList;
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.mSpells;
|
||||
|
||||
// the following code switches between selected enchanted item and selected spell (only one of these
|
||||
// can be active at a time)
|
||||
std::string selectedSpell = spells.getSelectedSpell();
|
||||
MWWorld::Ptr selectedItem;
|
||||
if (store.getSelectedEnchantItem() != store.end())
|
||||
{
|
||||
selectedSpell = "";
|
||||
selectedItem = *store.getSelectedEnchantItem();
|
||||
|
||||
bool allowSelectedItem = true;
|
||||
|
||||
// make sure that the item is still in the player inventory, otherwise it can't be selected
|
||||
bool found = false;
|
||||
for (MWWorld::ContainerStoreIterator it(store.begin()); it != store.end(); ++it)
|
||||
{
|
||||
if (*it == selectedItem)
|
||||
found = true;
|
||||
}
|
||||
if (!found)
|
||||
allowSelectedItem = false;
|
||||
|
||||
// if the selected item can be equipped, make sure that it actually is equipped
|
||||
std::pair<std::vector<int>, bool> slots;
|
||||
slots = MWWorld::Class::get(selectedItem).getEquipmentSlots(selectedItem);
|
||||
if (!slots.first.empty())
|
||||
{
|
||||
bool equipped = false;
|
||||
for (int i=0; i < MWWorld::InventoryStore::Slots; ++i)
|
||||
{
|
||||
if (store.getSlot(i) != store.end() && *store.getSlot(i) == selectedItem)
|
||||
{
|
||||
equipped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!equipped)
|
||||
allowSelectedItem = false;
|
||||
}
|
||||
|
||||
if (!allowSelectedItem)
|
||||
{
|
||||
store.setSelectedEnchantItem(store.end());
|
||||
spells.setSelectedSpell("");
|
||||
mWindowManager.unsetSelectedSpell();
|
||||
selectedItem = MWWorld::Ptr();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||
{
|
||||
spellList.push_back(*it);
|
||||
}
|
||||
|
||||
std::vector<std::string> powers;
|
||||
std::vector<std::string>::iterator it = spellList.begin();
|
||||
while (it != spellList.end())
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it);
|
||||
if (spell->data.type == ESM::Spell::ST_Power)
|
||||
{
|
||||
powers.push_back(*it);
|
||||
it = spellList.erase(it);
|
||||
}
|
||||
else if (spell->data.type == ESM::Spell::ST_Ability
|
||||
|| spell->data.type == ESM::Spell::ST_Blight
|
||||
|| spell->data.type == ESM::Spell::ST_Curse
|
||||
|| spell->data.type == ESM::Spell::ST_Disease)
|
||||
{
|
||||
it = spellList.erase(it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
std::sort(powers.begin(), powers.end(), sortSpells);
|
||||
std::sort(spellList.begin(), spellList.end(), sortSpells);
|
||||
|
||||
// retrieve player's enchanted items
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
for (MWWorld::ContainerStoreIterator it(store.begin()); it != store.end(); ++it)
|
||||
{
|
||||
std::string enchantId = MWWorld::Class::get(*it).getEnchantment(*it);
|
||||
if (enchantId != "")
|
||||
{
|
||||
// only add items with "Cast once" or "Cast on use"
|
||||
const ESM::Enchantment* enchant = MWBase::Environment::get().getWorld()->getStore().enchants.find(enchantId);
|
||||
int type = enchant->data.type;
|
||||
if (type != ESM::Enchantment::CastOnce
|
||||
&& type != ESM::Enchantment::WhenUsed)
|
||||
continue;
|
||||
|
||||
items.push_back(*it);
|
||||
}
|
||||
}
|
||||
std::sort(items.begin(), items.end(), sortItems);
|
||||
|
||||
|
||||
int height = estimateHeight(items.size() + powers.size() + spellList.size());
|
||||
bool scrollVisible = height > mSpellView->getHeight();
|
||||
mWidth = mSpellView->getWidth() - (scrollVisible ? 18 : 0);
|
||||
|
||||
// powers
|
||||
addGroup("#{sPowers}", "");
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = powers.begin(); it != powers.end(); ++it)
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it);
|
||||
MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>("SpellText",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
t->setCaption(spell->name);
|
||||
t->setTextAlign(MyGUI::Align::Left);
|
||||
t->setUserString("ToolTipType", "Spell");
|
||||
t->setUserString("Spell", *it);
|
||||
t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
|
||||
t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onSpellSelected);
|
||||
|
||||
if (*it == selectedSpell)
|
||||
t->setStateSelected(true);
|
||||
|
||||
mHeight += spellHeight;
|
||||
}
|
||||
|
||||
// other spells
|
||||
addGroup("#{sSpells}", "#{sCostChance}");
|
||||
for (std::vector<std::string>::const_iterator it = spellList.begin(); it != spellList.end(); ++it)
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it);
|
||||
MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>("SpellText",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
t->setCaption(spell->name);
|
||||
t->setTextAlign(MyGUI::Align::Left);
|
||||
t->setUserString("ToolTipType", "Spell");
|
||||
t->setUserString("Spell", *it);
|
||||
t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
|
||||
t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onSpellSelected);
|
||||
t->setStateSelected(*it == selectedSpell);
|
||||
|
||||
// cost / success chance
|
||||
MyGUI::Button* costChance = mSpellView->createWidget<MyGUI::Button>("SpellText",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
std::string cost = boost::lexical_cast<std::string>(spell->data.cost);
|
||||
std::string chance = boost::lexical_cast<std::string>(int(MWMechanics::getSpellSuccessChance(*it, player)));
|
||||
costChance->setCaption(cost + "/" + chance);
|
||||
costChance->setTextAlign(MyGUI::Align::Right);
|
||||
costChance->setNeedMouseFocus(false);
|
||||
costChance->setStateSelected(*it == selectedSpell);
|
||||
|
||||
|
||||
mHeight += spellHeight;
|
||||
}
|
||||
|
||||
|
||||
// enchanted items
|
||||
addGroup("#{sMagicItem}", "#{sCostCharge}");
|
||||
|
||||
for (std::vector<MWWorld::Ptr>::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
MWWorld::Ptr item = *it;
|
||||
|
||||
const ESM::Enchantment* enchant = MWBase::Environment::get().getWorld()->getStore().enchants.find(MWWorld::Class::get(item).getEnchantment(item));
|
||||
|
||||
// check if the item is currently equipped (will display in a different color)
|
||||
bool equipped = false;
|
||||
for (int i=0; i < MWWorld::InventoryStore::Slots; ++i)
|
||||
{
|
||||
if (store.getSlot(i) != store.end() && *store.getSlot(i) == item)
|
||||
{
|
||||
equipped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>(equipped ? "SpellText" : "SpellTextUnequipped",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
t->setCaption(MWWorld::Class::get(item).getName(item));
|
||||
t->setTextAlign(MyGUI::Align::Left);
|
||||
t->setUserData(item);
|
||||
t->setUserString("ToolTipType", "ItemPtr");
|
||||
t->setUserString("Equipped", equipped ? "true" : "false");
|
||||
t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onEnchantedItemSelected);
|
||||
t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
|
||||
t->setStateSelected(item == selectedItem);
|
||||
|
||||
// cost / charge
|
||||
MyGUI::Button* costCharge = mSpellView->createWidget<MyGUI::Button>(equipped ? "SpellText" : "SpellTextUnequipped",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
|
||||
std::string cost = boost::lexical_cast<std::string>(enchant->data.cost);
|
||||
std::string charge = boost::lexical_cast<std::string>(enchant->data.charge); /// \todo track current charge
|
||||
if (enchant->data.type == ESM::Enchantment::CastOnce)
|
||||
{
|
||||
// this is Morrowind behaviour
|
||||
cost = "100";
|
||||
charge = "100";
|
||||
}
|
||||
|
||||
costCharge->setCaption(cost + "/" + charge);
|
||||
costCharge->setTextAlign(MyGUI::Align::Right);
|
||||
costCharge->setNeedMouseFocus(false);
|
||||
costCharge->setStateSelected(item == selectedItem);
|
||||
|
||||
mHeight += spellHeight;
|
||||
}
|
||||
|
||||
mSpellView->setCanvasSize(mSpellView->getWidth(), std::max(mSpellView->getHeight(), mHeight));
|
||||
}
|
||||
|
||||
void SpellWindow::addGroup(const std::string &label, const std::string& label2)
|
||||
{
|
||||
if (mSpellView->getChildCount() > 0)
|
||||
{
|
||||
MyGUI::ImageBox* separator = mSpellView->createWidget<MyGUI::ImageBox>("MW_HLine",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, 18),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
separator->setNeedMouseFocus(false);
|
||||
mHeight += 18;
|
||||
}
|
||||
|
||||
MyGUI::TextBox* groupWidget = mSpellView->createWidget<MyGUI::TextBox>("SandBrightText",
|
||||
MyGUI::IntCoord(0, mHeight, mWidth, 24),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||
groupWidget->setCaptionWithReplacing(label);
|
||||
groupWidget->setTextAlign(MyGUI::Align::Left);
|
||||
groupWidget->setNeedMouseFocus(false);
|
||||
|
||||
if (label2 != "")
|
||||
{
|
||||
MyGUI::TextBox* groupWidget2 = mSpellView->createWidget<MyGUI::TextBox>("SandBrightText",
|
||||
MyGUI::IntCoord(0, mHeight, mWidth-4, 24),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
groupWidget2->setCaptionWithReplacing(label2);
|
||||
groupWidget2->setTextAlign(MyGUI::Align::Right);
|
||||
groupWidget2->setNeedMouseFocus(false);
|
||||
}
|
||||
|
||||
mHeight += 24;
|
||||
}
|
||||
|
||||
void SpellWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
{
|
||||
updateSpells();
|
||||
}
|
||||
|
||||
void SpellWindow::onEnchantedItemSelected(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||
MWMechanics::Spells& spells = stats.mSpells;
|
||||
MWWorld::Ptr item = *_sender->getUserData<MWWorld::Ptr>();
|
||||
|
||||
// retrieve ContainerStoreIterator to the item
|
||||
MWWorld::ContainerStoreIterator it = store.begin();
|
||||
for (; it != store.end(); ++it)
|
||||
{
|
||||
if (*it == item)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(it != store.end());
|
||||
|
||||
// equip, if it can be equipped and is not already equipped
|
||||
if (_sender->getUserString("Equipped") == "false"
|
||||
&& !MWWorld::Class::get(item).getEquipmentSlots(item).first.empty())
|
||||
{
|
||||
// sound
|
||||
MWBase::Environment::get().getSoundManager()->playSound(MWWorld::Class::get(item).getUpSoundId(item), 1.0, 1.0);
|
||||
|
||||
// Note: can't use Class::use here because enchanted scrolls for example would then open the scroll window instead of equipping
|
||||
|
||||
/// \todo the following code is pretty much copy&paste from ActionEquip, put it in a function?
|
||||
// slots that this item can be equipped in
|
||||
std::pair<std::vector<int>, bool> slots = MWWorld::Class::get(item).getEquipmentSlots(item);
|
||||
|
||||
// equip the item in the first free slot
|
||||
for (std::vector<int>::const_iterator slot=slots.first.begin();
|
||||
slot!=slots.first.end(); ++slot)
|
||||
{
|
||||
// if all slots are occupied, replace the last slot
|
||||
if (slot == --slots.first.end())
|
||||
{
|
||||
store.equip(*slot, it);
|
||||
break;
|
||||
}
|
||||
|
||||
if (store.getSlot(*slot) == store.end())
|
||||
{
|
||||
// slot is not occupied
|
||||
store.equip(*slot, it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/// \todo scripts?
|
||||
|
||||
// since we changed equipping status, update the inventory window
|
||||
mWindowManager.getInventoryWindow()->drawItems();
|
||||
}
|
||||
|
||||
store.setSelectedEnchantItem(it);
|
||||
spells.setSelectedSpell("");
|
||||
mWindowManager.setSelectedEnchantItem(item, 100); /// \todo track charge %
|
||||
|
||||
updateSpells();
|
||||
}
|
||||
|
||||
void SpellWindow::onSpellSelected(MyGUI::Widget* _sender)
|
||||
{
|
||||
std::string spellId = _sender->getUserString("Spell");
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||
MWMechanics::Spells& spells = stats.mSpells;
|
||||
|
||||
if (MyGUI::InputManager::getInstance().isShiftPressed())
|
||||
{
|
||||
// delete spell, if allowed
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
|
||||
if (spell->data.flags & ESM::Spell::F_Always
|
||||
|| spell->data.type == ESM::Spell::ST_Power)
|
||||
{
|
||||
mWindowManager.messageBox("#{sDeleteSpellError}", std::vector<std::string>());
|
||||
}
|
||||
else
|
||||
{
|
||||
// ask for confirmation
|
||||
mSpellToDelete = spellId;
|
||||
ConfirmationDialog* dialog = mWindowManager.getConfirmationDialog();
|
||||
std::string question = mWindowManager.getGameSettingString("sQuestionDeleteSpell", "Delete %s?");
|
||||
question = boost::str(boost::format(question) % spell->name);
|
||||
dialog->open(question);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &SpellWindow::onDeleteSpellAccept);
|
||||
dialog->eventCancelClicked.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spells.setSelectedSpell(spellId);
|
||||
store.setSelectedEnchantItem(store.end());
|
||||
mWindowManager.setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
|
||||
}
|
||||
|
||||
updateSpells();
|
||||
}
|
||||
|
||||
int SpellWindow::estimateHeight(int numSpells) const
|
||||
{
|
||||
int height = 0;
|
||||
height += 24 * 3 + 18 * 2; // group headings
|
||||
height += numSpells * 18;
|
||||
return height;
|
||||
}
|
||||
|
||||
void SpellWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (mSpellView->getViewOffset().top + _rel*0.3 > 0)
|
||||
mSpellView->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||
else
|
||||
mSpellView->setViewOffset(MyGUI::IntPoint(0, mSpellView->getViewOffset().top + _rel*0.3));
|
||||
}
|
||||
|
||||
void SpellWindow::onDeleteSpellAccept()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.mSpells;
|
||||
|
||||
if (spells.getSelectedSpell() == mSpellToDelete)
|
||||
{
|
||||
spells.setSelectedSpell("");
|
||||
mWindowManager.unsetSelectedSpell();
|
||||
}
|
||||
|
||||
spells.remove(mSpellToDelete);
|
||||
|
||||
updateSpells();
|
||||
}
|
||||
}
|
39
apps/openmw/mwgui/spellwindow.hpp
Normal file
39
apps/openmw/mwgui/spellwindow.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef MWGUI_SPELLWINDOW_H
|
||||
#define MWGUI_SPELLWINDOW_H
|
||||
|
||||
#include "window_pinnable_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class SpellWindow : public WindowPinnableBase
|
||||
{
|
||||
public:
|
||||
SpellWindow(WindowManager& parWindowManager);
|
||||
|
||||
void updateSpells();
|
||||
|
||||
protected:
|
||||
MyGUI::ScrollView* mSpellView;
|
||||
MyGUI::Widget* mEffectBox;
|
||||
|
||||
int mHeight;
|
||||
int mWidth;
|
||||
|
||||
std::string mSpellToDelete;
|
||||
|
||||
void addGroup(const std::string& label, const std::string& label2);
|
||||
|
||||
int estimateHeight(int numSpells) const;
|
||||
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
void onEnchantedItemSelected(MyGUI::Widget* _sender);
|
||||
void onSpellSelected(MyGUI::Widget* _sender);
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
void onDeleteSpellAccept();
|
||||
|
||||
virtual void onPinToggled();
|
||||
virtual void open();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,13 +1,20 @@
|
|||
#include "stats_window.hpp"
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include "window_manager.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
|
||||
using namespace MWGui;
|
||||
const int StatsWindow::lineHeight = 18;
|
||||
|
||||
|
@ -24,11 +31,12 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
|
|||
, skillValues()
|
||||
, skillWidgetMap()
|
||||
, factionWidgetMap()
|
||||
, factions()
|
||||
, mFactions()
|
||||
, birthSignId()
|
||||
, reputation(0)
|
||||
, bounty(0)
|
||||
, skillWidgets()
|
||||
, mChanged(true)
|
||||
{
|
||||
setCoord(0,0,498, 342);
|
||||
|
||||
|
@ -42,12 +50,6 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
|
|||
{ "Attrib6", "sAttributeEndurance" },
|
||||
{ "Attrib7", "sAttributePersonality" },
|
||||
{ "Attrib8", "sAttributeLuck" },
|
||||
{ "Health_str", "sHealth" },
|
||||
{ "Magicka_str", "sMagic" },
|
||||
{ "Fatigue_str", "sFatigue" },
|
||||
{ "Level_str", "sLevel" },
|
||||
{ "Race_str", "sRace" },
|
||||
{ "Class_str", "sClass" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -60,6 +62,10 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
|
|||
getWidget(skillAreaWidget, "Skills");
|
||||
getWidget(skillClientWidget, "SkillClient");
|
||||
getWidget(skillScrollerWidget, "SkillScroller");
|
||||
getWidget(mLeftPane, "LeftPane");
|
||||
getWidget(mRightPane, "RightPane");
|
||||
|
||||
skillClientWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
|
||||
skillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &StatsWindow::onScrollChangePosition);
|
||||
updateScroller();
|
||||
|
@ -72,8 +78,6 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
|
|||
|
||||
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget);
|
||||
t->eventWindowChangeCoord += MyGUI::newDelegate(this, &StatsWindow::onWindowResize);
|
||||
|
||||
setupToolTips();
|
||||
}
|
||||
|
||||
void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos)
|
||||
|
@ -91,8 +95,22 @@ void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos)
|
|||
}
|
||||
}
|
||||
|
||||
void StatsWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (skillScrollerWidget->getScrollPosition() - _rel*0.3 < 0)
|
||||
skillScrollerWidget->setScrollPosition(0);
|
||||
else if (skillScrollerWidget->getScrollPosition() - _rel*0.3 > skillScrollerWidget->getScrollRange()-1)
|
||||
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollRange()-1);
|
||||
else
|
||||
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollPosition() - _rel*0.3);
|
||||
|
||||
onScrollChangePosition(skillScrollerWidget, skillScrollerWidget->getScrollPosition());
|
||||
}
|
||||
|
||||
void StatsWindow::onWindowResize(MyGUI::Window* window)
|
||||
{
|
||||
mLeftPane->setCoord( MyGUI::IntCoord(0, 0, 0.44*window->getSize().width, window->getSize().height) );
|
||||
mRightPane->setCoord( MyGUI::IntCoord(0.44*window->getSize().width, 0, 0.56*window->getSize().width, window->getSize().height) );
|
||||
updateScroller();
|
||||
}
|
||||
|
||||
|
@ -153,10 +171,31 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicSta
|
|||
};
|
||||
|
||||
for (int i=0; ids[i]; ++i)
|
||||
{
|
||||
if (ids[i]==id)
|
||||
{
|
||||
std::string id (ids[i]);
|
||||
setBar (id, id + "T", value.getCurrent(), value.getModified());
|
||||
|
||||
// health, magicka, fatigue tooltip
|
||||
MyGUI::Widget* w;
|
||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||
if (i==0)
|
||||
{
|
||||
getWidget(w, "Health");
|
||||
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||
}
|
||||
else if (i==1)
|
||||
{
|
||||
getWidget(w, "Magicka");
|
||||
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||
}
|
||||
else if (i==2)
|
||||
{
|
||||
getWidget(w, "Fatigue");
|
||||
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,16 +255,42 @@ void StatsWindow::configureSkills (const std::vector<int>& major, const std::vec
|
|||
if (skillSet.find(skill) == skillSet.end())
|
||||
miscSkills.push_back(skill);
|
||||
}
|
||||
|
||||
updateSkillArea();
|
||||
}
|
||||
|
||||
void StatsWindow::setFactions (const std::vector<Faction>& factions)
|
||||
void StatsWindow::onFrame ()
|
||||
{
|
||||
this->factions = factions;
|
||||
if (mMainWidget->getVisible())
|
||||
return;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWMechanics::NpcStats PCstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||
|
||||
setFactions(PCstats.mFactionRank);
|
||||
|
||||
setBirthSign(MWBase::Environment::get().getWorld()->getPlayer().getBirthsign());
|
||||
|
||||
if (mChanged)
|
||||
updateSkillArea();
|
||||
}
|
||||
|
||||
void StatsWindow::setFactions (const FactionList& factions)
|
||||
{
|
||||
if (mFactions != factions)
|
||||
{
|
||||
mFactions = factions;
|
||||
mChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void StatsWindow::setBirthSign (const std::string& signId)
|
||||
{
|
||||
if (signId != birthSignId)
|
||||
{
|
||||
birthSignId = signId;
|
||||
mChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
|
@ -233,6 +298,7 @@ void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
|||
MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine",
|
||||
MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||
separator->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
skillWidgets.push_back(separator);
|
||||
|
||||
coord1.top += separator->getHeight();
|
||||
|
@ -245,26 +311,25 @@ void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, My
|
|||
MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||
groupWidget->setCaption(label);
|
||||
groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
skillWidgets.push_back(groupWidget);
|
||||
|
||||
coord1.top += lineHeight;
|
||||
coord2.top += lineHeight;
|
||||
}
|
||||
|
||||
MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string& tooltip, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::TextBox *skillNameWidget, *skillValueWidget;
|
||||
|
||||
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||
skillNameWidget->setCaption(text);
|
||||
skillNameWidget->setUserString("ToolTipType", "Text");
|
||||
skillNameWidget->setUserString("ToolTipText", tooltip);
|
||||
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
|
||||
skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Right | MyGUI::Align::Top);
|
||||
skillValueWidget->setUserString("ToolTipType", "Text");
|
||||
skillValueWidget->setUserString("ToolTipText", tooltip);
|
||||
skillValueWidget->setCaption(value);
|
||||
skillValueWidget->_setWidgetState(state);
|
||||
skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
|
||||
skillWidgets.push_back(skillNameWidget);
|
||||
skillWidgets.push_back(skillValueWidget);
|
||||
|
@ -275,17 +340,20 @@ MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::st
|
|||
return skillValueWidget;
|
||||
}
|
||||
|
||||
void StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::TextBox* skillNameWidget;
|
||||
|
||||
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
|
||||
skillNameWidget->setCaption(text);
|
||||
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
|
||||
skillWidgets.push_back(skillNameWidget);
|
||||
|
||||
coord1.top += lineHeight;
|
||||
coord2.top += lineHeight;
|
||||
|
||||
return skillNameWidget;
|
||||
}
|
||||
|
||||
void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
|
@ -309,26 +377,55 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId,
|
|||
const MWMechanics::Stat<float> &stat = skillValues.find(skillId)->second;
|
||||
float base = stat.getBase();
|
||||
float modified = stat.getModified();
|
||||
int progressPercent = (modified - float(static_cast<int>(modified))) * 100;
|
||||
|
||||
const ESM::Skill* skill = mWindowManager.getStore().skills.search(skillId);
|
||||
assert(skill);
|
||||
|
||||
std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId];
|
||||
|
||||
const ESM::Attribute* attr = mWindowManager.getStore().attributes.search(skill->data.attribute);
|
||||
assert(attr);
|
||||
|
||||
std::string state = "normal";
|
||||
if (modified > base)
|
||||
state = "increased";
|
||||
else if (modified < base)
|
||||
state = "decreased";
|
||||
MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), "",
|
||||
MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId),
|
||||
boost::lexical_cast<std::string>(static_cast<int>(modified)), state, coord1, coord2);
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "SkillToolTip");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillName", "#{"+skillNameId+"}");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillDescription", skill->description);
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillAttribute", "#{sGoverningAttribute}: #{" + attr->name + "}");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ImageTexture_SkillImage", icon);
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillProgressText", boost::lexical_cast<std::string>(progressPercent)+"/100");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Range_SkillProgress", "100");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("RangePosition_SkillProgress", boost::lexical_cast<std::string>(progressPercent));
|
||||
}
|
||||
|
||||
skillWidgetMap[skillId] = widget;
|
||||
}
|
||||
}
|
||||
|
||||
void StatsWindow::updateSkillArea()
|
||||
{
|
||||
mChanged = false;
|
||||
|
||||
for (std::vector<MyGUI::WidgetPtr>::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it)
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(*it);
|
||||
}
|
||||
skillWidgets.clear();
|
||||
|
||||
skillScrollerWidget->setScrollPosition(0);
|
||||
onScrollChangePosition(skillScrollerWidget, 0);
|
||||
clientHeight = 0;
|
||||
|
||||
const int valueSize = 40;
|
||||
MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18);
|
||||
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
|
||||
|
@ -344,19 +441,75 @@ void StatsWindow::updateSkillArea()
|
|||
|
||||
const ESMS::ESMStore &store = mWindowManager.getStore();
|
||||
|
||||
if (!factions.empty())
|
||||
// race tooltip
|
||||
const ESM::Race* playerRace = store.races.find (MWBase::Environment::get().getWorld()->getPlayer().getRace());
|
||||
MyGUI::Widget* raceWidget;
|
||||
getWidget(raceWidget, "RaceText");
|
||||
ToolTips::createRaceToolTip(raceWidget, playerRace);
|
||||
getWidget(raceWidget, "Race_str");
|
||||
ToolTips::createRaceToolTip(raceWidget, playerRace);
|
||||
|
||||
// class tooltip
|
||||
MyGUI::Widget* classWidget;
|
||||
const ESM::Class& playerClass = MWBase::Environment::get().getWorld()->getPlayer().getClass();
|
||||
getWidget(classWidget, "ClassText");
|
||||
ToolTips::createClassToolTip(classWidget, playerClass);
|
||||
getWidget(classWidget, "Class_str");
|
||||
ToolTips::createClassToolTip(classWidget, playerClass);
|
||||
|
||||
if (!mFactions.empty())
|
||||
{
|
||||
// Add a line separator if there are items above
|
||||
if (!skillWidgets.empty())
|
||||
addSeparator(coord1, coord2);
|
||||
|
||||
addGroup(mWindowManager.getGameSettingString("sFaction", "Faction"), coord1, coord2);
|
||||
FactionList::const_iterator end = factions.end();
|
||||
for (FactionList::const_iterator it = factions.begin(); it != end; ++it)
|
||||
FactionList::const_iterator end = mFactions.end();
|
||||
for (FactionList::const_iterator it = mFactions.begin(); it != end; ++it)
|
||||
{
|
||||
const ESM::Faction *faction = store.factions.find(it->first);
|
||||
addItem(faction->name, coord1, coord2);
|
||||
// TODO: Faction rank should be placed in tooltip
|
||||
MyGUI::Widget* w = addItem(faction->name, coord1, coord2);
|
||||
|
||||
std::string text;
|
||||
|
||||
text += std::string("#DDC79E") + faction->name;
|
||||
text += std::string("\n#BF9959") + faction->ranks[it->second];
|
||||
|
||||
if (it->second < 9)
|
||||
{
|
||||
// player doesn't have max rank yet
|
||||
text += std::string("\n\n#DDC79E#{sNextRank} ") + faction->ranks[it->second+1];
|
||||
|
||||
ESM::RankData rankData = faction->data.rankData[it->second+1];
|
||||
const ESM::Attribute* attr1 = mWindowManager.getStore().attributes.search(faction->data.attribute1);
|
||||
const ESM::Attribute* attr2 = mWindowManager.getStore().attributes.search(faction->data.attribute2);
|
||||
assert(attr1 && attr2);
|
||||
|
||||
text += "\n#BF9959#{" + attr1->name + "}: " + boost::lexical_cast<std::string>(rankData.attribute1)
|
||||
+ ", #{" + attr2->name + "}: " + boost::lexical_cast<std::string>(rankData.attribute2);
|
||||
|
||||
text += "\n\n#DDC79E#{sFavoriteSkills}";
|
||||
text += "\n#BF9959";
|
||||
for (int i=0; i<6; ++i)
|
||||
{
|
||||
const ESM::Skill* skill = mWindowManager.getStore().skills.search(faction->data.skillID[i]);
|
||||
assert(skill);
|
||||
text += "#{"+ESM::Skill::sSkillNameIds[faction->data.skillID[i]]+"}";
|
||||
if (i<5)
|
||||
text += ", ";
|
||||
}
|
||||
|
||||
text += "\n";
|
||||
|
||||
if (rankData.skill1 > 0)
|
||||
text += "\n#{sNeedOneSkill} " + boost::lexical_cast<std::string>(rankData.skill1);
|
||||
if (rankData.skill2 > 0)
|
||||
text += "\n#{sNeedTwoSkills} " + boost::lexical_cast<std::string>(rankData.skill2);
|
||||
}
|
||||
|
||||
w->setUserString("ToolTipType", "Layout");
|
||||
w->setUserString("ToolTipLayout", "TextToolTip");
|
||||
w->setUserString("Caption_Text", text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,9 +519,11 @@ void StatsWindow::updateSkillArea()
|
|||
if (!skillWidgets.empty())
|
||||
addSeparator(coord1, coord2);
|
||||
|
||||
addGroup(mWindowManager.getGameSettingString("sSign", "Sign"), coord1, coord2);
|
||||
addGroup(mWindowManager.getGameSettingString("sBirthSign", "Sign"), coord1, coord2);
|
||||
const ESM::BirthSign *sign = store.birthSigns.find(birthSignId);
|
||||
addItem(sign->name, coord1, coord2);
|
||||
MyGUI::Widget* w = addItem(sign->name, coord1, coord2);
|
||||
|
||||
ToolTips::createBirthsignToolTip(w, birthSignId);
|
||||
}
|
||||
|
||||
// Add a line separator if there are items above
|
||||
|
@ -376,12 +531,25 @@ void StatsWindow::updateSkillArea()
|
|||
addSeparator(coord1, coord2);
|
||||
|
||||
addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"),
|
||||
mWindowManager.getGameSettingString("sSkillsMenuReputationHelp", ""),
|
||||
boost::lexical_cast<std::string>(static_cast<int>(reputation)), "normal", coord1, coord2);
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sSkillsMenuReputationHelp}");
|
||||
}
|
||||
|
||||
addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"),
|
||||
mWindowManager.getGameSettingString("sCrimeHelp", ""),
|
||||
boost::lexical_cast<std::string>(static_cast<int>(bounty)), "normal", coord1, coord2);
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sCrimeHelp}");
|
||||
}
|
||||
|
||||
clientHeight = coord1.top;
|
||||
updateScroller();
|
||||
}
|
||||
|
@ -390,104 +558,11 @@ void StatsWindow::updateScroller()
|
|||
{
|
||||
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
|
||||
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
|
||||
if (clientHeight != 0)
|
||||
skillScrollerWidget->setTrackSize( (skillAreaWidget->getHeight() / float(clientHeight)) * skillScrollerWidget->getLineSize() );
|
||||
}
|
||||
|
||||
void StatsWindow::onPinToggled()
|
||||
{
|
||||
mWindowManager.setHMSVisibility(!mPinned);
|
||||
}
|
||||
|
||||
void StatsWindow::setupToolTips()
|
||||
{
|
||||
|
||||
const ESMS::ESMStore &store = mWindowManager.getStore();
|
||||
MyGUI::Widget* widget;
|
||||
|
||||
getWidget(widget, "Attrib1");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeStrength")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sStrDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_strength.dds");
|
||||
getWidget(widget, "AttribVal1");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeStrength")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sStrDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_strength.dds");
|
||||
|
||||
getWidget(widget, "Attrib2");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeIntelligence")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sIntDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_int.dds");
|
||||
getWidget(widget, "AttribVal2");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeIntelligence")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sIntDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_int.dds");
|
||||
|
||||
getWidget(widget, "Attrib3");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeWillpower")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sWilDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_wilpower.dds");
|
||||
getWidget(widget, "AttribVal3");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeWillpower")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sWilDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_wilpower.dds");
|
||||
|
||||
getWidget(widget, "Attrib4");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeAgility")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sAgiDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_agility.dds");
|
||||
getWidget(widget, "AttribVal4");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeAgility")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sAgiDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_agility.dds");
|
||||
|
||||
getWidget(widget, "Attrib5");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeSpeed")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sSpdDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_speed.dds");
|
||||
getWidget(widget, "AttribVal5");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeSpeed")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sSpdDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_speed.dds");
|
||||
|
||||
getWidget(widget, "Attrib6");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeEndurance")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sEndDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_endurance.dds");
|
||||
getWidget(widget, "AttribVal6");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeEndurance")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sEndDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_endurance.dds");
|
||||
|
||||
getWidget(widget, "Attrib7");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributePersonality")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sPerDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_personality.dds");
|
||||
getWidget(widget, "AttribVal7");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributePersonality")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sPerDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_personality.dds");
|
||||
|
||||
getWidget(widget, "Attrib8");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeLuck")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sLucDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_luck.dds");
|
||||
getWidget(widget, "AttribVal8");
|
||||
widget->setUserString("ToolTipType", "ImageCaptionText");
|
||||
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeLuck")->str);
|
||||
widget->setUserString("ToolTipText", store.gameSettings.find ("sLucDesc")->str);
|
||||
widget->setUserString("ToolTipImage", "k\\attribute_luck.dds");
|
||||
}
|
||||
|
|
|
@ -18,13 +18,15 @@ namespace MWGui
|
|||
class StatsWindow : public WindowPinnableBase
|
||||
{
|
||||
public:
|
||||
typedef std::pair<std::string, int> Faction;
|
||||
typedef std::vector<Faction> FactionList;
|
||||
typedef std::map<std::string, int> FactionList;
|
||||
|
||||
typedef std::vector<int> SkillList;
|
||||
|
||||
StatsWindow(WindowManager& parWindowManager);
|
||||
|
||||
/// automatically updates all the data in the stats window, but only if it has changed.
|
||||
void onFrame();
|
||||
|
||||
void setBar(const std::string& name, const std::string& tname, int val, int max);
|
||||
void setPlayerName(const std::string& playerName);
|
||||
|
||||
|
@ -36,8 +38,6 @@ namespace MWGui
|
|||
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
||||
|
||||
void configureSkills (const SkillList& major, const SkillList& minor);
|
||||
void setFactions (const std::vector<Faction>& factions);
|
||||
void setBirthSign (const std::string &signId);
|
||||
void setReputation (int reputation) { this->reputation = reputation; }
|
||||
void setBounty (int bounty) { this->bounty = bounty; }
|
||||
void updateSkillArea();
|
||||
|
@ -46,17 +46,22 @@ namespace MWGui
|
|||
void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
MyGUI::TextBox* addValueItem(const std::string& text, const std::string& tooltip, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
MyGUI::TextBox* addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
MyGUI::Widget* addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void updateScroller();
|
||||
|
||||
void setupToolTips();
|
||||
void setFactions (const FactionList& factions);
|
||||
void setBirthSign (const std::string &signId);
|
||||
|
||||
void onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos);
|
||||
void onWindowResize(MyGUI::Window* window);
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
|
||||
static const int lineHeight;
|
||||
|
||||
MyGUI::Widget* mLeftPane;
|
||||
MyGUI::Widget* mRightPane;
|
||||
|
||||
MyGUI::WidgetPtr skillAreaWidget, skillClientWidget;
|
||||
MyGUI::ScrollBar* skillScrollerWidget;
|
||||
int lastPos, clientHeight;
|
||||
|
@ -65,11 +70,13 @@ namespace MWGui
|
|||
std::map<int, MWMechanics::Stat<float> > skillValues;
|
||||
std::map<int, MyGUI::TextBox*> skillWidgetMap;
|
||||
std::map<std::string, MyGUI::WidgetPtr> factionWidgetMap;
|
||||
FactionList factions; ///< Stores a list of factions and the current rank
|
||||
FactionList mFactions; ///< Stores a list of factions and the current rank
|
||||
std::string birthSignId;
|
||||
int reputation, bounty;
|
||||
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information
|
||||
|
||||
bool mChanged;
|
||||
|
||||
protected:
|
||||
virtual void onPinToggled();
|
||||
};
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace MyGUI;
|
||||
|
||||
|
@ -16,6 +18,13 @@ ToolTips::ToolTips(WindowManager* windowManager) :
|
|||
, mGameMode(true)
|
||||
, mWindowManager(windowManager)
|
||||
, mFullHelp(false)
|
||||
, mEnabled(true)
|
||||
, mFocusToolTipX(0.0)
|
||||
, mFocusToolTipY(0.0)
|
||||
, mDelay(0.0)
|
||||
, mRemainingDelay(0.0)
|
||||
, mLastMouseX(0)
|
||||
, mLastMouseY(0)
|
||||
{
|
||||
getWidget(mDynamicToolTipBox, "DynamicToolTipBox");
|
||||
|
||||
|
@ -25,60 +34,55 @@ ToolTips::ToolTips(WindowManager* windowManager) :
|
|||
// even if the mouse is over the tooltip
|
||||
mDynamicToolTipBox->setNeedMouseFocus(false);
|
||||
mMainWidget->setNeedMouseFocus(false);
|
||||
|
||||
mDelay = Settings::Manager::getFloat("tooltip delay", "GUI");
|
||||
mRemainingDelay = mDelay;
|
||||
}
|
||||
|
||||
void ToolTips::setEnabled(bool enabled)
|
||||
{
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
void ToolTips::onFrame(float frameDuration)
|
||||
{
|
||||
/// \todo Store a MWWorld::Ptr in the widget user data, retrieve it here and construct a tooltip dynamically
|
||||
while (mDynamicToolTipBox->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox->getChildAt(0));
|
||||
}
|
||||
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox);
|
||||
mDynamicToolTipBox = mMainWidget->createWidget<Widget>("HUD_Box",
|
||||
IntCoord(0, 0, mMainWidget->getCoord().width, mMainWidget->getCoord().height),
|
||||
Align::Stretch, "DynamicToolTipBox");
|
||||
// start by hiding everything
|
||||
for (unsigned int i=0; i < mMainWidget->getChildCount(); ++i)
|
||||
{
|
||||
mMainWidget->getChildAt(i)->setVisible(false);
|
||||
}
|
||||
|
||||
const IntSize &viewSize = RenderManager::getInstance().getViewSize();
|
||||
|
||||
if (!mEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mGameMode)
|
||||
{
|
||||
Widget* focus = InputManager::getInstance().getMouseFocusWidget();
|
||||
if (focus == 0)
|
||||
const MyGUI::IntPoint& mousePos = InputManager::getInstance().getMousePosition();
|
||||
|
||||
if (mWindowManager->getWorldMouseOver() && ((mWindowManager->getMode() == GM_Console)
|
||||
|| (mWindowManager->getMode() == GM_Container)
|
||||
|| (mWindowManager->getMode() == GM_Inventory)))
|
||||
{
|
||||
std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle();
|
||||
try
|
||||
{
|
||||
mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
mDynamicToolTipBox->setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
IntSize tooltipSize;
|
||||
|
||||
std::string type = focus->getUserString("ToolTipType");
|
||||
std::string text = focus->getUserString("ToolTipText");
|
||||
|
||||
ToolTipInfo info;
|
||||
if (type == "")
|
||||
{
|
||||
mDynamicToolTipBox->setVisible(false);
|
||||
return;
|
||||
}
|
||||
else if (type == "Text")
|
||||
{
|
||||
info.text = text;
|
||||
}
|
||||
else if (type == "CaptionText")
|
||||
{
|
||||
std::string caption = focus->getUserString("ToolTipCaption");
|
||||
info.caption = caption;
|
||||
info.text = text;
|
||||
}
|
||||
else if (type == "ImageCaptionText")
|
||||
{
|
||||
std::string caption = focus->getUserString("ToolTipCaption");
|
||||
std::string image = focus->getUserString("ToolTipImage");
|
||||
std::string sizeString = focus->getUserString("ToolTipImageSize");
|
||||
|
||||
info.text = text;
|
||||
info.caption = caption;
|
||||
info.icon = image;
|
||||
}
|
||||
tooltipSize = createToolTip(info);
|
||||
MyGUI::IntSize tooltipSize = getToolTipViaPtr(true);
|
||||
|
||||
IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24);
|
||||
|
||||
|
@ -93,7 +97,162 @@ void ToolTips::onFrame(float frameDuration)
|
|||
}
|
||||
|
||||
setCoord(tooltipPosition.left, tooltipPosition.top, tooltipSize.width, tooltipSize.height);
|
||||
mDynamicToolTipBox->setVisible(true);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
const MyGUI::IntPoint& lastPressed = InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left);
|
||||
|
||||
if (mousePos == lastPressed) // mouseclick makes tooltip disappear
|
||||
return;
|
||||
|
||||
if (mousePos.left == mLastMouseX && mousePos.top == mLastMouseY)
|
||||
{
|
||||
mRemainingDelay -= frameDuration;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRemainingDelay = mDelay;
|
||||
}
|
||||
mLastMouseX = mousePos.left;
|
||||
mLastMouseY = mousePos.top;
|
||||
|
||||
if (mRemainingDelay > 0)
|
||||
return;
|
||||
|
||||
Widget* focus = InputManager::getInstance().getMouseFocusWidget();
|
||||
if (focus == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IntSize tooltipSize;
|
||||
|
||||
// try to go 1 level up until there is a widget that has tooltip
|
||||
// this is necessary because some skin elements are actually separate widgets
|
||||
int i=0;
|
||||
while (!focus->isUserString("ToolTipType"))
|
||||
{
|
||||
focus = focus->getParent();
|
||||
if (!focus)
|
||||
return;
|
||||
++i;
|
||||
}
|
||||
|
||||
std::string type = focus->getUserString("ToolTipType");
|
||||
std::string text = focus->getUserString("ToolTipText");
|
||||
|
||||
if (type == "")
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (type == "ItemPtr")
|
||||
{
|
||||
mFocusObject = *focus->getUserData<MWWorld::Ptr>();
|
||||
tooltipSize = getToolTipViaPtr(false);
|
||||
}
|
||||
else if (type == "Spell")
|
||||
{
|
||||
ToolTipInfo info;
|
||||
const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().spells.find(focus->getUserString("Spell"));
|
||||
info.caption = spell->name;
|
||||
Widgets::SpellEffectList effects;
|
||||
std::vector<ESM::ENAMstruct>::const_iterator end = spell->effects.list.end();
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->effects.list.begin(); it != end; ++it)
|
||||
{
|
||||
Widgets::SpellEffectParams params;
|
||||
params.mEffectID = it->effectID;
|
||||
params.mSkill = it->skill;
|
||||
params.mAttribute = it->attribute;
|
||||
params.mDuration = it->duration;
|
||||
params.mMagnMin = it->magnMin;
|
||||
params.mMagnMax = it->magnMax;
|
||||
params.mRange = it->range;
|
||||
params.mIsConstant = (spell->data.type == ESM::Spell::ST_Ability);
|
||||
effects.push_back(params);
|
||||
}
|
||||
info.effects = effects;
|
||||
tooltipSize = createToolTip(info);
|
||||
}
|
||||
else if (type == "Layout")
|
||||
{
|
||||
// tooltip defined in the layout
|
||||
MyGUI::Widget* tooltip;
|
||||
getWidget(tooltip, focus->getUserString("ToolTipLayout"));
|
||||
|
||||
tooltip->setVisible(true);
|
||||
if (!tooltip->isUserString("DontResize"))
|
||||
{
|
||||
tooltip->setCoord(0, 0, 450, 300); // this is the maximum width of the tooltip before it starts word-wrapping
|
||||
|
||||
tooltipSize = MyGUI::IntSize(0, tooltip->getSize().height);
|
||||
}
|
||||
else
|
||||
tooltipSize = tooltip->getSize();
|
||||
|
||||
std::map<std::string, std::string> userStrings = focus->getUserStrings();
|
||||
for (std::map<std::string, std::string>::iterator it = userStrings.begin();
|
||||
it != userStrings.end(); ++it)
|
||||
{
|
||||
if (it->first == "ToolTipType"
|
||||
|| it->first == "ToolTipLayout")
|
||||
continue;
|
||||
|
||||
|
||||
size_t underscorePos = it->first.find("_");
|
||||
std::string propertyKey = it->first.substr(0, underscorePos);
|
||||
std::string widgetName = it->first.substr(underscorePos+1, it->first.size()-(underscorePos+1));
|
||||
|
||||
MyGUI::Widget* w;
|
||||
getWidget(w, widgetName);
|
||||
w->setProperty(propertyKey, it->second);
|
||||
}
|
||||
|
||||
for (unsigned int i=0; i<tooltip->getChildCount(); ++i)
|
||||
{
|
||||
MyGUI::Widget* w = tooltip->getChildAt(i);
|
||||
|
||||
if (w->isUserString("AutoResizeHorizontal"))
|
||||
{
|
||||
MyGUI::TextBox* text = w->castType<MyGUI::TextBox>();
|
||||
tooltipSize.width = std::max(tooltipSize.width, w->getLeft() + text->getTextSize().width + 8);
|
||||
}
|
||||
else if (!tooltip->isUserString("DontResize"))
|
||||
tooltipSize.width = std::max(tooltipSize.width, w->getLeft() + w->getWidth() + 8);
|
||||
|
||||
if (w->isUserString("AutoResizeVertical"))
|
||||
{
|
||||
MyGUI::TextBox* text = w->castType<MyGUI::TextBox>();
|
||||
int height = text->getTextSize().height;
|
||||
if (height > w->getHeight())
|
||||
{
|
||||
tooltipSize += MyGUI::IntSize(0, height - w->getHeight());
|
||||
}
|
||||
if (height < w->getHeight())
|
||||
{
|
||||
tooltipSize -= MyGUI::IntSize(0, w->getHeight() - height);
|
||||
}
|
||||
}
|
||||
}
|
||||
tooltip->setCoord(0, 0, tooltipSize.width, tooltipSize.height);
|
||||
}
|
||||
else
|
||||
throw std::runtime_error ("unknown tooltip type");
|
||||
|
||||
IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24);
|
||||
|
||||
// make the tooltip stay completely in the viewport
|
||||
if ((tooltipPosition.left + tooltipSize.width) > viewSize.width)
|
||||
{
|
||||
tooltipPosition.left = viewSize.width - tooltipSize.width;
|
||||
}
|
||||
if ((tooltipPosition.top + tooltipSize.height) > viewSize.height)
|
||||
{
|
||||
tooltipPosition.top = viewSize.height - tooltipSize.height;
|
||||
}
|
||||
|
||||
setCoord(tooltipPosition.left, tooltipPosition.top, tooltipSize.width, tooltipSize.height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -101,15 +260,13 @@ void ToolTips::onFrame(float frameDuration)
|
|||
{
|
||||
IntSize tooltipSize = getToolTipViaPtr();
|
||||
|
||||
// adjust tooltip size to fit its content, position it above the crosshair
|
||||
/// \todo Slide the tooltip along the bounding box of the focused object (like in Morrowind)
|
||||
setCoord(std::max(0, viewSize.width/2 - (tooltipSize.width)/2),
|
||||
std::max(0, viewSize.height/2 - (tooltipSize.height) - 32),
|
||||
setCoord(viewSize.width/2 - tooltipSize.width/2,
|
||||
std::max(0, int(mFocusToolTipY*viewSize.height - tooltipSize.height)),
|
||||
tooltipSize.width,
|
||||
tooltipSize.height);
|
||||
|
||||
mDynamicToolTipBox->setVisible(true);
|
||||
}
|
||||
else
|
||||
mDynamicToolTipBox->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,7 +285,7 @@ void ToolTips::setFocusObject(const MWWorld::Ptr& focus)
|
|||
mFocusObject = focus;
|
||||
}
|
||||
|
||||
IntSize ToolTips::getToolTipViaPtr ()
|
||||
IntSize ToolTips::getToolTipViaPtr (bool image)
|
||||
{
|
||||
// this the maximum width of the tooltip before it starts word-wrapping
|
||||
setCoord(0, 0, 300, 300);
|
||||
|
@ -145,6 +302,8 @@ IntSize ToolTips::getToolTipViaPtr ()
|
|||
mDynamicToolTipBox->setVisible(true);
|
||||
|
||||
ToolTipInfo info = object.getToolTipInfo(mFocusObject);
|
||||
if (!image)
|
||||
info.icon = "";
|
||||
tooltipSize = createToolTip(info);
|
||||
}
|
||||
|
||||
|
@ -165,8 +324,10 @@ void ToolTips::findImageExtension(std::string& image)
|
|||
}
|
||||
}
|
||||
|
||||
IntSize ToolTips::createToolTip(const ToolTipInfo& info)
|
||||
IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
|
||||
{
|
||||
mDynamicToolTipBox->setVisible(true);
|
||||
|
||||
std::string caption = info.caption;
|
||||
std::string image = info.icon;
|
||||
int imageSize = (image != "") ? 32 : 0;
|
||||
|
@ -221,7 +382,7 @@ IntSize ToolTips::createToolTip(const ToolTipInfo& info)
|
|||
IntSize totalSize = IntSize( std::max(textSize.width, captionSize.width + ((image != "") ? imageCaptionHPadding : 0)),
|
||||
((text != "") ? textSize.height + imageCaptionVPadding : 0) + captionHeight );
|
||||
|
||||
if (info.effects != 0)
|
||||
if (!info.effects.empty())
|
||||
{
|
||||
Widget* effectArea = mDynamicToolTipBox->createWidget<Widget>("",
|
||||
IntCoord(0, totalSize.height, 300, 300-totalSize.height),
|
||||
|
@ -241,7 +402,7 @@ IntSize ToolTips::createToolTip(const ToolTipInfo& info)
|
|||
effectsWidget->setEffectList(info.effects);
|
||||
|
||||
std::vector<MyGUI::WidgetPtr> effectItems;
|
||||
effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, Widgets::MWEffectList::EF_Potion);
|
||||
effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, Widgets::MWEffectList::EF_NoTarget);
|
||||
totalSize.height += coord.top-6;
|
||||
totalSize.width = std::max(totalSize.width, coord.width);
|
||||
}
|
||||
|
@ -257,7 +418,7 @@ IntSize ToolTips::createToolTip(const ToolTipInfo& info)
|
|||
Widgets::MWEffectListPtr enchantWidget = enchantArea->createWidget<Widgets::MWEffectList>
|
||||
("MW_StatName", coord, Align::Default, "ToolTipEnchantWidget");
|
||||
enchantWidget->setWindowManager(mWindowManager);
|
||||
enchantWidget->setEffectList(&enchant->effects);
|
||||
enchantWidget->setEffectList(Widgets::MWEffectList::effectListFromESM(&enchant->effects));
|
||||
|
||||
std::vector<MyGUI::WidgetPtr> enchantEffectItems;
|
||||
int flag = (enchant->data.type == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0;
|
||||
|
@ -275,10 +436,12 @@ IntSize ToolTips::createToolTip(const ToolTipInfo& info)
|
|||
|
||||
TextBox* chargeText = enchantArea->createWidget<TextBox>("SandText", IntCoord(0, 0, 10, 18), Align::Default, "ToolTipEnchantChargeText");
|
||||
chargeText->setCaption(store.gameSettings.search("sCharges")->str);
|
||||
chargeText->setProperty("Static", "true");
|
||||
const int chargeTextWidth = chargeText->getTextSize().width + 5;
|
||||
|
||||
const int chargeAndTextWidth = chargeWidth + chargeTextWidth;
|
||||
|
||||
totalSize.width = std::max(totalSize.width, chargeAndTextWidth);
|
||||
|
||||
chargeText->setCoord((totalSize.width - chargeAndTextWidth)/2, coord.top+6, chargeTextWidth, 18);
|
||||
|
||||
IntCoord chargeCoord;
|
||||
|
@ -350,6 +513,14 @@ std::string ToolTips::getMiscString(const std::string& text, const std::string&
|
|||
return "\n" + prefix + ": " + text;
|
||||
}
|
||||
|
||||
std::string ToolTips::getCountString(const int value)
|
||||
{
|
||||
if (value == 1)
|
||||
return "";
|
||||
else
|
||||
return " (" + boost::lexical_cast<std::string>(value) + ")";
|
||||
}
|
||||
|
||||
void ToolTips::toggleFullHelp()
|
||||
{
|
||||
mFullHelp = !mFullHelp;
|
||||
|
@ -359,3 +530,162 @@ bool ToolTips::getFullHelp() const
|
|||
{
|
||||
return mFullHelp;
|
||||
}
|
||||
|
||||
void ToolTips::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y)
|
||||
{
|
||||
mFocusToolTipX = (min_x + max_x) / 2;
|
||||
mFocusToolTipY = min_y;
|
||||
}
|
||||
|
||||
void ToolTips::createSkillToolTip(MyGUI::Widget* widget, int skillId)
|
||||
{
|
||||
if (skillId == -1)
|
||||
return;
|
||||
|
||||
const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId];
|
||||
const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().skills.search(skillId);
|
||||
assert(skill);
|
||||
const ESM::Attribute* attr = MWBase::Environment::get().getWorld()->getStore().attributes.search(skill->data.attribute);
|
||||
assert(attr);
|
||||
std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId];
|
||||
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip");
|
||||
widget->setUserString("Caption_SkillNoProgressName", "#{"+skillNameId+"}");
|
||||
widget->setUserString("Caption_SkillNoProgressDescription", skill->description);
|
||||
widget->setUserString("Caption_SkillNoProgressAttribute", "#{sGoverningAttribute}: #{" + attr->name + "}");
|
||||
widget->setUserString("ImageTexture_SkillNoProgressImage", icon);
|
||||
widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip");
|
||||
widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip");
|
||||
}
|
||||
|
||||
void ToolTips::createAttributeToolTip(MyGUI::Widget* widget, int attributeId)
|
||||
{
|
||||
if (attributeId == -1)
|
||||
return;
|
||||
|
||||
const ESM::Attribute* attr = MWBase::Environment::get().getWorld()->getStore().attributes.search(attributeId);
|
||||
assert(attr);
|
||||
std::string icon = ESM::Attribute::attributeIcons[attributeId];
|
||||
std::string name = ESM::Attribute::gmstAttributeIds[attributeId];
|
||||
std::string desc = ESM::Attribute::gmstAttributeDescIds[attributeId];
|
||||
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", "#{"+name+"}");
|
||||
widget->setUserString("Caption_AttributeDescription", "#{"+desc+"}");
|
||||
widget->setUserString("ImageTexture_AttributeImage", icon);
|
||||
}
|
||||
|
||||
void ToolTips::createSpecializationToolTip(MyGUI::Widget* widget, const std::string& name, int specId)
|
||||
{
|
||||
widget->setUserString("Caption_CenteredCaption", name);
|
||||
std::string specText;
|
||||
// get all skills of this specialisation
|
||||
std::map<int, ESM::Skill> skills = MWBase::Environment::get().getWorld()->getStore().skills.list;
|
||||
for (std::map<int, ESM::Skill>::const_iterator it = skills.begin();
|
||||
it != skills.end(); ++it)
|
||||
{
|
||||
if (it->second.data.specialization == specId)
|
||||
specText += std::string("\n#{") + ESM::Skill::sSkillNameIds[it->second.index] + "}";
|
||||
}
|
||||
widget->setUserString("Caption_CenteredCaptionText", specText);
|
||||
widget->setUserString("ToolTipLayout", "TextWithCenteredCaptionToolTip");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
}
|
||||
|
||||
void ToolTips::createBirthsignToolTip(MyGUI::Widget* widget, const std::string& birthsignId)
|
||||
{
|
||||
const ESM::BirthSign *sign = MWBase::Environment::get().getWorld()->getStore().birthSigns.find(birthsignId);
|
||||
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "BirthSignToolTip");
|
||||
std::string image = sign->texture;
|
||||
image.replace(image.size()-3, 3, "dds");
|
||||
widget->setUserString("ImageTexture_BirthSignImage", "textures\\" + image);
|
||||
std::string text;
|
||||
|
||||
text += sign->name;
|
||||
text += "\n#BF9959" + sign->description;
|
||||
|
||||
std::vector<std::string> abilities, powers, spells;
|
||||
|
||||
std::vector<std::string>::const_iterator it = sign->powers.list.begin();
|
||||
std::vector<std::string>::const_iterator end = sign->powers.list.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
const std::string &spellId = *it;
|
||||
const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().spells.search(spellId);
|
||||
if (!spell)
|
||||
continue; // Skip spells which cannot be found
|
||||
ESM::Spell::SpellType type = static_cast<ESM::Spell::SpellType>(spell->data.type);
|
||||
if (type != ESM::Spell::ST_Spell && type != ESM::Spell::ST_Ability && type != ESM::Spell::ST_Power)
|
||||
continue; // We only want spell, ability and powers.
|
||||
|
||||
if (type == ESM::Spell::ST_Ability)
|
||||
abilities.push_back(spellId);
|
||||
else if (type == ESM::Spell::ST_Power)
|
||||
powers.push_back(spellId);
|
||||
else if (type == ESM::Spell::ST_Spell)
|
||||
spells.push_back(spellId);
|
||||
}
|
||||
|
||||
struct{ const std::vector<std::string> &spells; std::string label; } categories[3] = {
|
||||
{abilities, "sBirthsignmenu1"},
|
||||
{powers, "sPowers"},
|
||||
{spells, "sBirthsignmenu2"}
|
||||
};
|
||||
|
||||
for (int category = 0; category < 3; ++category)
|
||||
{
|
||||
for (std::vector<std::string>::const_iterator it = categories[category].spells.begin(); it != categories[category].spells.end(); ++it)
|
||||
{
|
||||
if (it == categories[category].spells.begin())
|
||||
{
|
||||
text += std::string("\n#DDC79E") + std::string("#{") + categories[category].label + "}";
|
||||
}
|
||||
|
||||
const std::string &spellId = *it;
|
||||
|
||||
const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().spells.search(spellId);
|
||||
text += "\n#BF9959" + spell->name;
|
||||
}
|
||||
}
|
||||
|
||||
widget->setUserString("Caption_BirthSignText", text);
|
||||
}
|
||||
|
||||
void ToolTips::createRaceToolTip(MyGUI::Widget* widget, const ESM::Race* playerRace)
|
||||
{
|
||||
widget->setUserString("Caption_CenteredCaption", playerRace->name);
|
||||
widget->setUserString("Caption_CenteredCaptionText", playerRace->description);
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "TextWithCenteredCaptionToolTip");
|
||||
}
|
||||
|
||||
void ToolTips::createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playerClass)
|
||||
{
|
||||
if (playerClass.name == "")
|
||||
return;
|
||||
|
||||
int spec = playerClass.data.specialization;
|
||||
std::string specStr;
|
||||
if (spec == 0)
|
||||
specStr = "#{sSpecializationCombat}";
|
||||
else if (spec == 1)
|
||||
specStr = "#{sSpecializationMagic}";
|
||||
else if (spec == 2)
|
||||
specStr = "#{sSpecializationStealth}";
|
||||
|
||||
widget->setUserString("Caption_ClassName", playerClass.name);
|
||||
widget->setUserString("Caption_ClassDescription", playerClass.description);
|
||||
widget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr);
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "ClassToolTip");
|
||||
}
|
||||
|
||||
void ToolTips::setDelay(float delay)
|
||||
{
|
||||
mDelay = delay;
|
||||
mRemainingDelay = mDelay;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <openengine/gui/layout.hpp>
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "widgets.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class WindowManager;
|
||||
|
@ -13,11 +15,6 @@ namespace MWGui
|
|||
struct ToolTipInfo
|
||||
{
|
||||
public:
|
||||
ToolTipInfo() :
|
||||
effects(0)
|
||||
{
|
||||
};
|
||||
|
||||
std::string caption;
|
||||
std::string text;
|
||||
std::string icon;
|
||||
|
@ -26,7 +23,7 @@ namespace MWGui
|
|||
std::string enchant;
|
||||
|
||||
// effects (for potions, ingredients)
|
||||
const ESM::EffectList* effects;
|
||||
Widgets::SpellEffectList effects;
|
||||
};
|
||||
|
||||
class ToolTips : public OEngine::GUI::Layout
|
||||
|
@ -39,10 +36,16 @@ namespace MWGui
|
|||
void enterGameMode();
|
||||
void enterGuiMode();
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
|
||||
bool getFullHelp() const;
|
||||
|
||||
void setDelay(float delay);
|
||||
|
||||
void setFocusObject(const MWWorld::Ptr& focus);
|
||||
void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y);
|
||||
///< set the screen-space position of the tooltip for focused object
|
||||
|
||||
static std::string getValueString(const int value, const std::string& prefix);
|
||||
///< @return "prefix: value" or "" if value is 0
|
||||
|
@ -53,6 +56,18 @@ namespace MWGui
|
|||
static std::string toString(const float value);
|
||||
static std::string toString(const int value);
|
||||
|
||||
static std::string getCountString(const int value);
|
||||
///< @return blank string if count is 1, or else " (value)"
|
||||
|
||||
// these do not create an actual tooltip, but they fill in the data that is required so the tooltip
|
||||
// system knows what to show in case this widget is hovered
|
||||
static void createSkillToolTip(MyGUI::Widget* widget, int skillId);
|
||||
static void createAttributeToolTip(MyGUI::Widget* widget, int attributeId);
|
||||
static void createSpecializationToolTip(MyGUI::Widget* widget, const std::string& name, int specId);
|
||||
static void createBirthsignToolTip(MyGUI::Widget* widget, const std::string& birthsignId);
|
||||
static void createRaceToolTip(MyGUI::Widget* widget, const ESM::Race* playerRace);
|
||||
static void createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playerClass);
|
||||
|
||||
private:
|
||||
MyGUI::Widget* mDynamicToolTipBox;
|
||||
|
||||
|
@ -62,14 +77,25 @@ namespace MWGui
|
|||
|
||||
void findImageExtension(std::string& image);
|
||||
|
||||
MyGUI::IntSize getToolTipViaPtr ();
|
||||
MyGUI::IntSize getToolTipViaPtr (bool image=true);
|
||||
///< @return requested tooltip size
|
||||
|
||||
MyGUI::IntSize createToolTip(const ToolTipInfo& info);
|
||||
///< @return requested tooltip size
|
||||
|
||||
float mFocusToolTipX;
|
||||
float mFocusToolTipY;
|
||||
|
||||
float mDelay;
|
||||
float mRemainingDelay; // remaining time until tooltip will show
|
||||
|
||||
int mLastMouseX;
|
||||
int mLastMouseY;
|
||||
|
||||
bool mGameMode;
|
||||
|
||||
bool mEnabled;
|
||||
|
||||
bool mFullHelp;
|
||||
};
|
||||
}
|
||||
|
|
370
apps/openmw/mwgui/tradewindow.cpp
Normal file
370
apps/openmw/mwgui/tradewindow.cpp
Normal file
|
@ -0,0 +1,370 @@
|
|||
#include "tradewindow.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
TradeWindow::TradeWindow(WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_trade_window_layout.xml", parWindowManager)
|
||||
, ContainerBase(NULL) // no drag&drop
|
||||
, mCurrentBalance(0)
|
||||
{
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
getWidget(mFilterAll, "AllButton");
|
||||
getWidget(mFilterWeapon, "WeaponButton");
|
||||
getWidget(mFilterApparel, "ApparelButton");
|
||||
getWidget(mFilterMagic, "MagicButton");
|
||||
getWidget(mFilterMisc, "MiscButton");
|
||||
|
||||
getWidget(mMaxSaleButton, "MaxSaleButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
getWidget(mOfferButton, "OfferButton");
|
||||
getWidget(mPlayerGold, "PlayerGold");
|
||||
getWidget(mMerchantGold, "MerchantGold");
|
||||
getWidget(mIncreaseButton, "IncreaseButton");
|
||||
getWidget(mDecreaseButton, "DecreaseButton");
|
||||
getWidget(mTotalBalance, "TotalBalance");
|
||||
getWidget(mTotalBalanceLabel, "TotalBalanceLabel");
|
||||
getWidget(mBottomPane, "BottomPane");
|
||||
|
||||
// adjust size of buttons to fit text
|
||||
int curX = 0;
|
||||
mFilterAll->setSize( mFilterAll->getTextSize().width + 24, mFilterAll->getSize().height );
|
||||
curX += mFilterAll->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterWeapon->setPosition(curX, mFilterWeapon->getPosition().top);
|
||||
mFilterWeapon->setSize( mFilterWeapon->getTextSize().width + 24, mFilterWeapon->getSize().height );
|
||||
curX += mFilterWeapon->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterApparel->setPosition(curX, mFilterApparel->getPosition().top);
|
||||
mFilterApparel->setSize( mFilterApparel->getTextSize().width + 24, mFilterApparel->getSize().height );
|
||||
curX += mFilterApparel->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMagic->setPosition(curX, mFilterMagic->getPosition().top);
|
||||
mFilterMagic->setSize( mFilterMagic->getTextSize().width + 24, mFilterMagic->getSize().height );
|
||||
curX += mFilterMagic->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMisc->setPosition(curX, mFilterMisc->getPosition().top);
|
||||
mFilterMisc->setSize( mFilterMisc->getTextSize().width + 24, mFilterMisc->getSize().height );
|
||||
|
||||
mFilterAll->setStateSelected(true);
|
||||
|
||||
mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
mFilterMagic->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
mFilterMisc->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onCancelButtonClicked);
|
||||
mOfferButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onOfferButtonClicked);
|
||||
|
||||
mMaxSaleButton->setSize(MyGUI::IntSize(mMaxSaleButton->getTextSize().width + 24, mMaxSaleButton->getHeight()));
|
||||
|
||||
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
|
||||
mCancelButton->setCoord(mBottomPane->getWidth()-cancelButtonWidth,
|
||||
mCancelButton->getTop(),
|
||||
cancelButtonWidth,
|
||||
mCancelButton->getHeight());
|
||||
|
||||
int offerButtonWidth = mOfferButton->getTextSize().width + 24;
|
||||
mOfferButton->setCoord(mBottomPane->getWidth()-cancelButtonWidth-offerButtonWidth-8,
|
||||
mOfferButton->getTop(),
|
||||
offerButtonWidth,
|
||||
mOfferButton->getHeight());
|
||||
|
||||
setCoord(400, 0, 400, 300);
|
||||
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &TradeWindow::onWindowResize);
|
||||
}
|
||||
|
||||
void TradeWindow::startTrade(MWWorld::Ptr actor)
|
||||
{
|
||||
setTitle(MWWorld::Class::get(actor).getName(actor));
|
||||
|
||||
mCurrentBalance = 0;
|
||||
|
||||
mWindowManager.getInventoryWindow()->startTrade();
|
||||
|
||||
mBoughtItems.clear();
|
||||
|
||||
ContainerBase::openContainer(actor);
|
||||
|
||||
updateLabels();
|
||||
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void TradeWindow::onFilterChanged(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (_sender == mFilterAll)
|
||||
setFilter(ContainerBase::Filter_All);
|
||||
else if (_sender == mFilterWeapon)
|
||||
setFilter(ContainerBase::Filter_Weapon);
|
||||
else if (_sender == mFilterApparel)
|
||||
setFilter(ContainerBase::Filter_Apparel);
|
||||
else if (_sender == mFilterMagic)
|
||||
setFilter(ContainerBase::Filter_Magic);
|
||||
else if (_sender == mFilterMisc)
|
||||
setFilter(ContainerBase::Filter_Misc);
|
||||
|
||||
mFilterAll->setStateSelected(false);
|
||||
mFilterWeapon->setStateSelected(false);
|
||||
mFilterApparel->setStateSelected(false);
|
||||
mFilterMagic->setStateSelected(false);
|
||||
mFilterMisc->setStateSelected(false);
|
||||
|
||||
static_cast<MyGUI::Button*>(_sender)->setStateSelected(true);
|
||||
}
|
||||
|
||||
void TradeWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
{
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void TradeWindow::onOfferButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
// were there any items traded at all?
|
||||
MWWorld::ContainerStore& playerBought = mWindowManager.getInventoryWindow()->getBoughtItems();
|
||||
MWWorld::ContainerStore& merchantBought = getBoughtItems();
|
||||
if (playerBought.begin() == playerBought.end() && merchantBought.begin() == merchantBought.end())
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog11")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the player can afford this
|
||||
if (mCurrentBalance < 0 && mWindowManager.getInventoryWindow()->getPlayerGold() < std::abs(mCurrentBalance))
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog1")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the merchant can afford this
|
||||
int merchantgold;
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>();
|
||||
if (ref->base->npdt52.gold == -10)
|
||||
merchantgold = ref->base->npdt12.gold;
|
||||
else
|
||||
merchantgold = ref->base->npdt52.gold;
|
||||
}
|
||||
else // ESM::Creature
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>();
|
||||
merchantgold = ref->base->data.gold;
|
||||
}
|
||||
if (mCurrentBalance > 0 && merchantgold < mCurrentBalance)
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog2")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
// success! make the item transfer.
|
||||
transferBoughtItems();
|
||||
mWindowManager.getInventoryWindow()->transferBoughtItems();
|
||||
|
||||
// add or remove gold from the player.
|
||||
bool goldFound = false;
|
||||
MWWorld::Ptr gold;
|
||||
MWWorld::ContainerStore& playerStore = mWindowManager.getInventoryWindow()->getContainerStore();
|
||||
for (MWWorld::ContainerStoreIterator it = playerStore.begin();
|
||||
it != playerStore.end(); ++it)
|
||||
{
|
||||
if (MWWorld::Class::get(*it).getName(*it) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
|
||||
{
|
||||
goldFound = true;
|
||||
gold = *it;
|
||||
}
|
||||
}
|
||||
if (goldFound)
|
||||
{
|
||||
gold.getRefData().setCount(gold.getRefData().getCount() + mCurrentBalance);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(mCurrentBalance > 0);
|
||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), "Gold_001");
|
||||
ref.getPtr().getRefData().setCount(mCurrentBalance);
|
||||
playerStore.add(ref.getPtr());
|
||||
}
|
||||
|
||||
std::string sound = "Item Gold Up";
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
mWindowManager.removeGuiMode(GM_Barter);
|
||||
}
|
||||
|
||||
void TradeWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
// i give you back your stuff!
|
||||
returnBoughtItems(mWindowManager.getInventoryWindow()->getContainerStore());
|
||||
// now gimme back my stuff!
|
||||
mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mPtr).getContainerStore(mPtr));
|
||||
|
||||
mWindowManager.removeGuiMode(GM_Barter);
|
||||
}
|
||||
|
||||
void TradeWindow::updateLabels()
|
||||
{
|
||||
mPlayerGold->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sYourGold")->str
|
||||
+ " " + boost::lexical_cast<std::string>(mWindowManager.getInventoryWindow()->getPlayerGold()));
|
||||
|
||||
if (mCurrentBalance > 0)
|
||||
{
|
||||
mTotalBalanceLabel->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTotalSold")->str);
|
||||
mTotalBalance->setCaption(boost::lexical_cast<std::string>(mCurrentBalance));
|
||||
}
|
||||
else
|
||||
{
|
||||
mTotalBalanceLabel->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTotalCost")->str);
|
||||
mTotalBalance->setCaption(boost::lexical_cast<std::string>(-mCurrentBalance));
|
||||
}
|
||||
|
||||
int merchantgold;
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>();
|
||||
if (ref->base->npdt52.gold == -10)
|
||||
merchantgold = ref->base->npdt12.gold;
|
||||
else
|
||||
merchantgold = ref->base->npdt52.gold;
|
||||
}
|
||||
else // ESM::Creature
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>();
|
||||
merchantgold = ref->base->data.gold;
|
||||
}
|
||||
|
||||
mMerchantGold->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sSellerGold")->str
|
||||
+ " " + boost::lexical_cast<std::string>(merchantgold));
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> TradeWindow::getEquippedItems()
|
||||
{
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
|
||||
if (mPtr.getTypeName() == typeid(ESM::Creature).name())
|
||||
{
|
||||
// creatures don't have equipment slots.
|
||||
return items;
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end())
|
||||
{
|
||||
items.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
|
||||
{
|
||||
int services = 0;
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>();
|
||||
if (ref->base->hasAI)
|
||||
services = ref->base->AI.services;
|
||||
}
|
||||
else if (mPtr.getTypeName() == typeid(ESM::Creature).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>();
|
||||
if (ref->base->hasAI)
|
||||
services = ref->base->AI.services;
|
||||
}
|
||||
|
||||
/// \todo what about potions, there doesn't seem to be a flag for them??
|
||||
|
||||
if (item.getTypeName() == typeid(ESM::Weapon).name())
|
||||
return services & ESM::NPC::Weapon;
|
||||
else if (item.getTypeName() == typeid(ESM::Armor).name())
|
||||
return services & ESM::NPC::Armor;
|
||||
else if (item.getTypeName() == typeid(ESM::Clothing).name())
|
||||
return services & ESM::NPC::Clothing;
|
||||
else if (item.getTypeName() == typeid(ESM::Book).name())
|
||||
return services & ESM::NPC::Books;
|
||||
else if (item.getTypeName() == typeid(ESM::Ingredient).name())
|
||||
return services & ESM::NPC::Ingredients;
|
||||
else if (item.getTypeName() == typeid(ESM::Tool).name())
|
||||
return services & ESM::NPC::Picks;
|
||||
else if (item.getTypeName() == typeid(ESM::Probe).name())
|
||||
return services & ESM::NPC::Probes;
|
||||
else if (item.getTypeName() == typeid(ESM::Light).name())
|
||||
return services & ESM::NPC::Lights;
|
||||
else if (item.getTypeName() == typeid(ESM::Apparatus).name())
|
||||
return services & ESM::NPC::Apparatus;
|
||||
else if (item.getTypeName() == typeid(ESM::Repair).name())
|
||||
return services & ESM::NPC::RepairItem;
|
||||
else if (item.getTypeName() == typeid(ESM::Miscellaneous).name())
|
||||
return services & ESM::NPC::Misc;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore()
|
||||
{
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
it != invStore.end(); ++it)
|
||||
{
|
||||
if (!npcAcceptsItem(*it))
|
||||
items.push_back(*it);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
void TradeWindow::sellToNpc(MWWorld::Ptr item, int count)
|
||||
{
|
||||
/// \todo price adjustment depending on merchantile skill
|
||||
|
||||
mCurrentBalance -= MWWorld::Class::get(item).getValue(item) * count;
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void TradeWindow::buyFromNpc(MWWorld::Ptr item, int count)
|
||||
{
|
||||
/// \todo price adjustment depending on merchantile skill
|
||||
|
||||
mCurrentBalance += MWWorld::Class::get(item).getValue(item) * count;
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void TradeWindow::onReferenceUnavailable()
|
||||
{
|
||||
// remove both Trade and Dialogue (since you always trade with the NPC/creature that you have previously talked to)
|
||||
mWindowManager.removeGuiMode(GM_Barter);
|
||||
mWindowManager.removeGuiMode(GM_Dialogue);
|
||||
}
|
||||
}
|
77
apps/openmw/mwgui/tradewindow.hpp
Normal file
77
apps/openmw/mwgui/tradewindow.hpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
#ifndef MWGUI_TRADEWINDOW_H
|
||||
#define MWGUI_TRADEWINDOW_H
|
||||
|
||||
#include "container.hpp"
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MyGUI
|
||||
{
|
||||
class Gui;
|
||||
class Widget;
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class WindowManager;
|
||||
}
|
||||
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class TradeWindow : public ContainerBase, public WindowBase
|
||||
{
|
||||
public:
|
||||
TradeWindow(WindowManager& parWindowManager);
|
||||
|
||||
void startTrade(MWWorld::Ptr actor);
|
||||
|
||||
void sellToNpc(MWWorld::Ptr item, int count); ///< only used for adjusting the gold balance
|
||||
void buyFromNpc(MWWorld::Ptr item, int count); ///< only used for adjusting the gold balance
|
||||
|
||||
bool npcAcceptsItem(MWWorld::Ptr item);
|
||||
|
||||
protected:
|
||||
MyGUI::Button* mFilterAll;
|
||||
MyGUI::Button* mFilterWeapon;
|
||||
MyGUI::Button* mFilterApparel;
|
||||
MyGUI::Button* mFilterMagic;
|
||||
MyGUI::Button* mFilterMisc;
|
||||
|
||||
MyGUI::Button* mIncreaseButton;
|
||||
MyGUI::Button* mDecreaseButton;
|
||||
MyGUI::TextBox* mTotalBalanceLabel;
|
||||
MyGUI::TextBox* mTotalBalance;
|
||||
|
||||
MyGUI::Widget* mBottomPane;
|
||||
|
||||
MyGUI::Button* mMaxSaleButton;
|
||||
MyGUI::Button* mCancelButton;
|
||||
MyGUI::Button* mOfferButton;
|
||||
MyGUI::TextBox* mPlayerGold;
|
||||
MyGUI::TextBox* mMerchantGold;
|
||||
|
||||
int mCurrentBalance;
|
||||
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
void onFilterChanged(MyGUI::Widget* _sender);
|
||||
void onOfferButtonClicked(MyGUI::Widget* _sender);
|
||||
void onCancelButtonClicked(MyGUI::Widget* _sender);
|
||||
|
||||
// don't show items that the NPC has equipped in his trade-window.
|
||||
virtual bool ignoreEquippedItems() { return true; }
|
||||
virtual std::vector<MWWorld::Ptr> getEquippedItems();
|
||||
|
||||
virtual bool isTrading() { return true; }
|
||||
virtual bool isTradeWindow() { return true; }
|
||||
|
||||
virtual std::vector<MWWorld::Ptr> itemsToIgnore();
|
||||
|
||||
void updateLabels();
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -234,8 +234,17 @@ void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI:
|
|||
{
|
||||
effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default);
|
||||
effect->setWindowManager(mWindowManager);
|
||||
effect->setFlags(flags);
|
||||
effect->setSpellEffect(*it);
|
||||
SpellEffectParams params;
|
||||
params.mEffectID = it->effectID;
|
||||
params.mSkill = it->skill;
|
||||
params.mAttribute = it->attribute;
|
||||
params.mDuration = it->duration;
|
||||
params.mMagnMin = it->magnMin;
|
||||
params.mMagnMax = it->magnMax;
|
||||
params.mRange = it->range;
|
||||
params.mIsConstant = (flags & MWEffectList::EF_Constant);
|
||||
params.mNoTarget = (flags & MWEffectList::EF_NoTarget);
|
||||
effect->setSpellEffect(params);
|
||||
effects.push_back(effect);
|
||||
coord.top += effect->getHeight();
|
||||
coord.width = std::max(coord.width, effect->getRequestedWidth());
|
||||
|
@ -274,7 +283,7 @@ MWEffectList::MWEffectList()
|
|||
{
|
||||
}
|
||||
|
||||
void MWEffectList::setEffectList(const ESM::EffectList* list)
|
||||
void MWEffectList::setEffectList(const SpellEffectList& list)
|
||||
{
|
||||
mEffectList = list;
|
||||
updateWidgets();
|
||||
|
@ -283,25 +292,26 @@ void MWEffectList::setEffectList(const ESM::EffectList* list)
|
|||
void MWEffectList::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, bool center, int flags)
|
||||
{
|
||||
// We don't know the width of all the elements beforehand, so we do it in
|
||||
// 2 steps: first, create all widgets and check their width
|
||||
// 2 steps: first, create all widgets and check their width....
|
||||
MWSpellEffectPtr effect = nullptr;
|
||||
std::vector<ESM::ENAMstruct>::const_iterator end = mEffectList->list.end();
|
||||
int maxwidth = coord.width;
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffectList->list.begin(); it != end; ++it)
|
||||
|
||||
for (SpellEffectList::iterator it=mEffectList.begin();
|
||||
it != mEffectList.end(); ++it)
|
||||
{
|
||||
effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default);
|
||||
effect->setWindowManager(mWindowManager);
|
||||
effect->setFlags(flags);
|
||||
it->mIsConstant = (flags & EF_Constant) || it->mIsConstant;
|
||||
it->mNoTarget = (flags & EF_NoTarget) || it->mNoTarget;
|
||||
effect->setSpellEffect(*it);
|
||||
effects.push_back(effect);
|
||||
|
||||
if (effect->getRequestedWidth() > maxwidth)
|
||||
maxwidth = effect->getRequestedWidth();
|
||||
|
||||
coord.top += effect->getHeight();
|
||||
}
|
||||
|
||||
// then adjust the size for all widgets
|
||||
// ... then adjust the size for all widgets
|
||||
for (std::vector<MyGUI::WidgetPtr>::iterator it = effects.begin(); it != effects.end(); ++it)
|
||||
{
|
||||
effect = static_cast<MWSpellEffectPtr>(*it);
|
||||
|
@ -334,6 +344,25 @@ MWEffectList::~MWEffectList()
|
|||
{
|
||||
}
|
||||
|
||||
SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects)
|
||||
{
|
||||
SpellEffectList result;
|
||||
std::vector<ESM::ENAMstruct>::const_iterator end = effects->list.end();
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator it = effects->list.begin(); it != end; ++it)
|
||||
{
|
||||
SpellEffectParams params;
|
||||
params.mEffectID = it->effectID;
|
||||
params.mSkill = it->skill;
|
||||
params.mAttribute = it->attribute;
|
||||
params.mDuration = it->duration;
|
||||
params.mMagnMin = it->magnMin;
|
||||
params.mMagnMax = it->magnMax;
|
||||
params.mRange = it->range;
|
||||
result.push_back(params);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* MWSpellEffect */
|
||||
|
||||
MWSpellEffect::MWSpellEffect()
|
||||
|
@ -341,13 +370,12 @@ MWSpellEffect::MWSpellEffect()
|
|||
, imageWidget(nullptr)
|
||||
, textWidget(nullptr)
|
||||
, mRequestedWidth(0)
|
||||
, mFlags(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MWSpellEffect::setSpellEffect(SpellEffectValue value)
|
||||
void MWSpellEffect::setSpellEffect(const SpellEffectParams& params)
|
||||
{
|
||||
effect = value;
|
||||
mEffectParams = params;
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
|
@ -357,10 +385,10 @@ void MWSpellEffect::updateWidgets()
|
|||
return;
|
||||
|
||||
const ESMS::ESMStore &store = mWindowManager->getStore();
|
||||
const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID);
|
||||
const ESM::MagicEffect *magicEffect = store.magicEffects.search(mEffectParams.mEffectID);
|
||||
if (!magicEffect)
|
||||
return;
|
||||
if (textWidget)
|
||||
{
|
||||
if (magicEffect)
|
||||
{
|
||||
std::string pt = mWindowManager->getGameSettingString("spoint", "");
|
||||
std::string pts = mWindowManager->getGameSettingString("spoints", "");
|
||||
|
@ -368,13 +396,13 @@ void MWSpellEffect::updateWidgets()
|
|||
std::string sec = " " + mWindowManager->getGameSettingString("ssecond", "");
|
||||
std::string secs = " " + mWindowManager->getGameSettingString("sseconds", "");
|
||||
|
||||
std::string effectIDStr = effectIDToString(effect.effectID);
|
||||
std::string effectIDStr = effectIDToString(mEffectParams.mEffectID);
|
||||
std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, "");
|
||||
if (effect.skill >= 0 && effect.skill < ESM::Skill::Length)
|
||||
if (effectInvolvesSkill(effectIDStr) && mEffectParams.mSkill >= 0 && mEffectParams.mSkill < ESM::Skill::Length)
|
||||
{
|
||||
spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], "");
|
||||
spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], "");
|
||||
}
|
||||
if (effect.attribute >= 0 && effect.attribute < 8)
|
||||
if (effectInvolvesAttribute(effectIDStr) && mEffectParams.mAttribute >= 0 && mEffectParams.mAttribute < 8)
|
||||
{
|
||||
static const char *attributes[8] = {
|
||||
"sAttributeStrength",
|
||||
|
@ -386,36 +414,36 @@ void MWSpellEffect::updateWidgets()
|
|||
"sAttributePersonality",
|
||||
"sAttributeLuck"
|
||||
};
|
||||
spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], "");
|
||||
spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], "");
|
||||
}
|
||||
|
||||
if ((effect.magnMin >= 0 || effect.magnMax >= 0) && effectHasMagnitude(effectIDStr))
|
||||
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && effectHasMagnitude(effectIDStr))
|
||||
{
|
||||
if (effect.magnMin == effect.magnMax)
|
||||
spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + " " + ((effect.magnMin == 1) ? pt : pts);
|
||||
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>(effect.magnMin) + to + boost::lexical_cast<std::string>(effect.magnMax) + " " + pts;
|
||||
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax) + " " + pts;
|
||||
}
|
||||
}
|
||||
|
||||
// constant effects have no duration and no target
|
||||
if (!(mFlags & MWEffectList::EF_Constant))
|
||||
if (!mEffectParams.mIsConstant)
|
||||
{
|
||||
if (effect.duration >= 0 && effectHasDuration(effectIDStr))
|
||||
if (mEffectParams.mDuration >= 0 && effectHasDuration(effectIDStr))
|
||||
{
|
||||
spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(effect.duration) + ((effect.duration == 1) ? sec : secs);
|
||||
spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs);
|
||||
}
|
||||
|
||||
// potions have no target
|
||||
if (!(mFlags & MWEffectList::EF_Potion))
|
||||
if (!mEffectParams.mNoTarget)
|
||||
{
|
||||
std::string on = mWindowManager->getGameSettingString("sonword", "");
|
||||
if (effect.range == ESM::RT_Self)
|
||||
if (mEffectParams.mRange == ESM::RT_Self)
|
||||
spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeSelf", "");
|
||||
else if (effect.range == ESM::RT_Touch)
|
||||
else if (mEffectParams.mRange == ESM::RT_Touch)
|
||||
spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTouch", "");
|
||||
else if (effect.range == ESM::RT_Target)
|
||||
else if (mEffectParams.mRange == ESM::RT_Target)
|
||||
spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTarget", "");
|
||||
}
|
||||
}
|
||||
|
@ -423,9 +451,6 @@ void MWSpellEffect::updateWidgets()
|
|||
static_cast<MyGUI::TextBox*>(textWidget)->setCaption(spellLine);
|
||||
mRequestedWidth = textWidget->getTextSize().width + 24;
|
||||
}
|
||||
else
|
||||
static_cast<MyGUI::TextBox*>(textWidget)->setCaption("");
|
||||
}
|
||||
if (imageWidget)
|
||||
{
|
||||
std::string path = std::string("icons\\") + magicEffect->icon;
|
||||
|
@ -677,6 +702,24 @@ bool MWSpellEffect::effectHasMagnitude(const std::string& effect)
|
|||
return (std::find(effectsWithoutMagnitude.begin(), effectsWithoutMagnitude.end(), effect) == effectsWithoutMagnitude.end());
|
||||
}
|
||||
|
||||
bool MWSpellEffect::effectInvolvesAttribute (const std::string& effect)
|
||||
{
|
||||
return (effect == "sEffectRestoreAttribute"
|
||||
|| effect == "sEffectAbsorbAttribute"
|
||||
|| effect == "sEffectDrainAttribute"
|
||||
|| effect == "sEffectFortifyAttribute"
|
||||
|| effect == "sEffectDamageAttribute");
|
||||
}
|
||||
|
||||
bool MWSpellEffect::effectInvolvesSkill (const std::string& effect)
|
||||
{
|
||||
return (effect == "sEffectRestoreSkill"
|
||||
|| effect == "sEffectAbsorbSkill"
|
||||
|| effect == "sEffectDrainSkill"
|
||||
|| effect == "sEffectFortifySkill"
|
||||
|| effect == "sEffectDamageSkill");
|
||||
}
|
||||
|
||||
MWSpellEffect::~MWSpellEffect()
|
||||
{
|
||||
}
|
||||
|
@ -724,7 +767,7 @@ void MWDynamicStat::setValue(int cur, int max_)
|
|||
static_cast<MyGUI::TextBox*>(barTextWidget)->setCaption("");
|
||||
}
|
||||
}
|
||||
void MWDynamicStat::setTitle(const std::string text)
|
||||
void MWDynamicStat::setTitle(const std::string& text)
|
||||
{
|
||||
if (textWidget)
|
||||
static_cast<MyGUI::TextBox*>(textWidget)->setCaption(text);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue