forked from teamnwah/openmw-tes3coop
Post merge
This commit is contained in:
commit
20288de685
175 changed files with 5612 additions and 1886 deletions
|
@ -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);
|
||||
|
@ -52,107 +53,33 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent)
|
|||
|
||||
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()
|
||||
|
@ -164,32 +91,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)
|
||||
|
@ -228,11 +135,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));
|
||||
|
@ -255,217 +170,44 @@ void GraphicsPage::setupOgre()
|
|||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
mAntiAliasingComboBox->clear();
|
||||
mResolutionComboBox->clear();
|
||||
mAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||
mResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mSelectedRenderSystem));
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
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;
|
||||
std::string resolution = mResolutionComboBox->currentText().toStdString();
|
||||
// parse resolution x and y from a string like "800 x 600"
|
||||
size_t xPos = resolution.find("x");
|
||||
int resX = boost::lexical_cast<int>(resolution.substr(0, xPos-1));
|
||||
int resY = boost::lexical_cast<int>(resolution.substr(xPos+2, resolution.size()-(xPos+2)));
|
||||
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 +226,12 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -494,15 +241,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(getAvailableOptions(QString("Video Mode"), mSelectedRenderSystem));
|
||||
}
|
||||
|
|
|
@ -49,33 +49,15 @@ 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);
|
||||
|
||||
void createPages();
|
||||
|
|
|
@ -7,6 +7,28 @@
|
|||
|
||||
MainDialog::MainDialog()
|
||||
{
|
||||
// Create the settings manager and load default settings file
|
||||
const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg";
|
||||
const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg";
|
||||
|
||||
// prefer local
|
||||
if (boost::filesystem::exists(localdefault))
|
||||
mSettings.loadDefault(localdefault);
|
||||
else if (boost::filesystem::exists(globaldefault))
|
||||
mSettings.loadDefault(globaldefault);
|
||||
else
|
||||
throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed.");
|
||||
|
||||
// load user settings if they exist, otherwise just load the default settings as user settings
|
||||
const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg";
|
||||
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);
|
||||
|
||||
|
||||
mIconWidget = new QListWidget;
|
||||
mIconWidget->setObjectName("IconWidget");
|
||||
mIconWidget->setViewMode(QListView::IconMode);
|
||||
|
@ -178,6 +200,11 @@ void MainDialog::closeEvent(QCloseEvent *event)
|
|||
// Now write all config files
|
||||
mDataFilesPage->writeConfig();
|
||||
mGraphicsPage->writeConfig();
|
||||
|
||||
// Save user settings
|
||||
const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg";
|
||||
mSettings.saveUser(settingspath);
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QDialog>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
|
@ -41,6 +42,7 @@ private:
|
|||
DataFilesPage *mDataFilesPage;
|
||||
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
Settings::Manager mSettings;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ add_openmw_dir (mwgui
|
|||
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 itemwidget inventorywindow container hud countdialog tradewindow
|
||||
formatting inventorywindow container hud countdialog tradewindow settingswindow
|
||||
confirmationdialog alchemywindow referenceinterface spellwindow
|
||||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
|
@ -49,7 +50,7 @@ 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 actionopen actionread
|
||||
actionequip timestamp
|
||||
actionequip timestamp actionalchemy
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
|
|
|
@ -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
|
||||
|
@ -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();
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionalchemy.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
@ -140,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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@ namespace MWClass
|
|||
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -81,24 +81,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.insertObjectPhysics(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 =
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -135,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;
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
@ -182,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.
|
||||
|
@ -53,6 +48,10 @@ namespace MWClass
|
|||
|
||||
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"
|
||||
|
@ -155,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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@ namespace MWClass
|
|||
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -110,44 +110,32 @@ 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.insertObjectPhysics(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 =
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -132,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");
|
||||
|
|
|
@ -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"
|
||||
|
@ -154,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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@ namespace MWClass
|
|||
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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,7 +635,7 @@ 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(actor, MWWorld::Class::get (actor).getName (actor));
|
||||
|
||||
|
@ -843,7 +843,7 @@ namespace MWDialogue
|
|||
|
||||
void DialogueManager::goodbyeSelected()
|
||||
{
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game);
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
}
|
||||
|
||||
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.popGuiMode();
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
||||
|
||||
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
|
|
@ -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;
|
||||
|
||||
|
@ -91,7 +92,7 @@ void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
|||
// 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.popGuiMode();
|
||||
}
|
||||
|
||||
void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
|
@ -101,7 +102,7 @@ void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
|||
MWWorld::ActionTake take(mBook);
|
||||
take.execute();
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
||||
|
||||
void BookWindow::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)
|
||||
|
@ -209,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);
|
||||
|
@ -253,7 +305,7 @@ void CharacterCreation::onReviewDialogDone(WindowBase* parWindow)
|
|||
if (mReviewDialog)
|
||||
mWM->removeDialog(mReviewDialog);
|
||||
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
|
||||
void CharacterCreation::onReviewDialogBack()
|
||||
|
@ -261,7 +313,7 @@ void CharacterCreation::onReviewDialogBack()
|
|||
if (mReviewDialog)
|
||||
mWM->removeDialog(mReviewDialog);
|
||||
|
||||
mWM->setGuiMode(GM_Birth);
|
||||
mWM->pushGuiMode(GM_Birth);
|
||||
}
|
||||
|
||||
void CharacterCreation::onReviewActivateDialog(int parDialog)
|
||||
|
@ -270,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);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -304,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +384,8 @@ void CharacterCreation::onPickClassDialogBack()
|
|||
mWM->removeDialog(mPickClassDialog);
|
||||
}
|
||||
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
|
||||
void CharacterCreation::onClassChoice(int _index)
|
||||
|
@ -334,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;
|
||||
|
||||
};
|
||||
|
@ -363,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,7 +452,8 @@ void CharacterCreation::onRaceDialogBack()
|
|||
mWM->removeDialog(mRaceDialog);
|
||||
}
|
||||
|
||||
mWM->setGuiMode(GM_Name);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Name);
|
||||
}
|
||||
|
||||
void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
|
||||
|
@ -398,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,11 +495,14 @@ void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
|
|||
}
|
||||
|
||||
if (mCreationStage >= CSE_BirthSignChosen)
|
||||
mWM->setGuiMode(GM_Review);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Review);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCreationStage = CSE_BirthSignChosen;
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,7 +514,8 @@ void CharacterCreation::onBirthSignDialogBack()
|
|||
mWM->removeDialog(mBirthSignDialog);
|
||||
}
|
||||
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
|
||||
void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
|
||||
|
@ -470,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,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)
|
||||
|
@ -496,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;
|
||||
}
|
||||
|
||||
|
@ -581,7 +669,8 @@ void CharacterCreation::showClassQuestionDialog()
|
|||
|
||||
if (mGenerateClassStep > sGenerateClassSteps.size())
|
||||
{
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -610,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,13 +710,19 @@ void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
|
|||
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -634,7 +730,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
|
||||
|
||||
|
@ -79,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;
|
||||
|
@ -231,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");
|
||||
|
@ -387,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:"));
|
||||
|
@ -451,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()
|
||||
|
@ -461,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();
|
||||
|
@ -499,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;
|
||||
}
|
||||
|
@ -539,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);
|
||||
|
@ -562,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);
|
||||
|
@ -592,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);
|
||||
|
@ -625,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)
|
||||
|
@ -640,6 +687,7 @@ void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow)
|
|||
{
|
||||
description = descDialog->getTextInput();
|
||||
mWindowManager.removeDialog(descDialog);
|
||||
descDialog = 0;
|
||||
}
|
||||
|
||||
void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender)
|
||||
|
@ -665,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
|
||||
|
@ -721,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;
|
||||
|
@ -729,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
|
||||
|
@ -810,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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -819,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
|
||||
|
@ -853,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -119,7 +119,7 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
|
|||
else
|
||||
onContainerClicked(mContainerWidget);
|
||||
}
|
||||
else
|
||||
else if (isTrading())
|
||||
{
|
||||
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
|
||||
int count = object.getRefData().getCount();
|
||||
|
@ -179,6 +179,10 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onSelectedItemImpl(*_sender->getUserData<MWWorld::Ptr>());
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
|
||||
|
@ -260,16 +264,16 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
|
|||
if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
|
||||
{
|
||||
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
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 (mContainer.getTypeName() == typeid(ESM::Container).name())
|
||||
if (mPtr.getTypeName() == typeid(ESM::Container).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mContainer.get<ESM::Container>();
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mPtr.get<ESM::Container>();
|
||||
if (ref->base->flags & ESM::Container::Organic)
|
||||
{
|
||||
// user notification
|
||||
|
@ -284,13 +288,13 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
|
|||
// check that we don't exceed the allowed weight (only for containers, not for inventory)
|
||||
if (!isInventory())
|
||||
{
|
||||
float capacity = MWWorld::Class::get(mContainer).getCapacity(mContainer);
|
||||
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(mContainer).getEncumbrance(mContainer);
|
||||
float curWeight = MWWorld::Class::get(mPtr).getEncumbrance(mPtr);
|
||||
if (curWeight > capacity)
|
||||
{
|
||||
it->getRefData().setCount(0);
|
||||
|
@ -342,8 +346,7 @@ void ContainerBase::setFilter(ContainerBase::Filter filter)
|
|||
|
||||
void ContainerBase::openContainer(MWWorld::Ptr container)
|
||||
{
|
||||
mContainer = container;
|
||||
drawItems();
|
||||
mPtr = container;
|
||||
}
|
||||
|
||||
void ContainerBase::drawItems()
|
||||
|
@ -352,15 +355,12 @@ void ContainerBase::drawItems()
|
|||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0));
|
||||
}
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int maxHeight = mItemView->getSize().height - 58;
|
||||
|
||||
int index = 0;
|
||||
|
||||
|
||||
bool onlyMagic = false;
|
||||
int categories;
|
||||
if (mFilter == Filter_All)
|
||||
|
@ -381,8 +381,10 @@ void ContainerBase::drawItems()
|
|||
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_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
|
||||
|
||||
|
@ -454,7 +456,6 @@ void ContainerBase::drawItems()
|
|||
for (std::vector< std::pair<MWWorld::Ptr, ItemState> >::const_iterator it=items.begin();
|
||||
it != items.end(); ++it)
|
||||
{
|
||||
index++;
|
||||
const MWWorld::Ptr* iter = &((*it).first);
|
||||
|
||||
int displayCount = iter->getRefData().getCount();
|
||||
|
@ -514,6 +515,7 @@ void ContainerBase::drawItems()
|
|||
text->setNeedMouseFocus(false);
|
||||
text->setTextShadow(true);
|
||||
text->setTextShadowColour(MyGUI::Colour(0,0,0));
|
||||
text->setCaption(getCountString(displayCount));
|
||||
|
||||
y += 42;
|
||||
if (y > maxHeight)
|
||||
|
@ -522,13 +524,14 @@ void ContainerBase::drawItems()
|
|||
y = 0;
|
||||
}
|
||||
|
||||
text->setCaption(getCountString(displayCount));
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -551,7 +554,7 @@ void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
|
|||
|
||||
void ContainerBase::addItem(MWWorld::Ptr item, int count)
|
||||
{
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
int origCount = item.getRefData().getCount();
|
||||
|
||||
|
@ -563,7 +566,7 @@ void ContainerBase::addItem(MWWorld::Ptr item, int count)
|
|||
|
||||
void ContainerBase::transferBoughtItems()
|
||||
{
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
|
||||
{
|
||||
|
@ -581,7 +584,7 @@ void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
|
|||
|
||||
MWWorld::ContainerStore& ContainerBase::getContainerStore()
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
return store;
|
||||
}
|
||||
|
||||
|
@ -630,13 +633,14 @@ 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()->setGuiMode(GM_Game);
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -645,7 +649,7 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
|
|||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// transfer everything into the player's inventory
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
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);
|
||||
|
@ -667,6 +671,11 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
|
|||
|
||||
containerStore.clear();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setGuiMode(GM_Game);
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWindow::onReferenceUnavailable()
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
}
|
||||
|
|
|
@ -2,15 +2,14 @@
|
|||
#define MGUI_CONTAINER_H
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
#include "../mwclass/container.hpp"
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "window_base.hpp"
|
||||
#include "referenceinterface.hpp"
|
||||
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
|
@ -43,7 +42,7 @@ namespace MWGui
|
|||
int mDraggedCount;
|
||||
};
|
||||
|
||||
class ContainerBase
|
||||
class ContainerBase : public ReferenceInterface
|
||||
{
|
||||
public:
|
||||
ContainerBase(DragAndDrop* dragAndDrop);
|
||||
|
@ -55,7 +54,9 @@ namespace MWGui
|
|||
Filter_Weapon = 0x02,
|
||||
Filter_Apparel = 0x03,
|
||||
Filter_Magic = 0x04,
|
||||
Filter_Misc = 0x05
|
||||
Filter_Misc = 0x05,
|
||||
|
||||
Filter_Ingredients = 0x06
|
||||
};
|
||||
|
||||
enum ItemState
|
||||
|
@ -87,7 +88,6 @@ namespace MWGui
|
|||
MyGUI::Widget* mSelectedItem;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
MWWorld::Ptr mContainer;
|
||||
|
||||
Filter mFilter;
|
||||
|
||||
|
@ -116,8 +116,12 @@ namespace MWGui
|
|||
|
||||
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
|
||||
|
@ -136,6 +140,8 @@ namespace MWGui
|
|||
void onWindowResize(MyGUI::Window* window);
|
||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
};
|
||||
}
|
||||
#endif // CONTAINER_H
|
||||
|
|
|
@ -17,9 +17,6 @@ namespace MWGui
|
|||
getWidget(mOkButton, "OkButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
|
||||
mOkButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sOk")->str);
|
||||
mCancelButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sCancel")->str);
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked);
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked);
|
||||
mItemEdit->eventEditTextChange += MyGUI::newDelegate(this, &CountDialog::onEditTextChange);
|
||||
|
|
|
@ -112,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();
|
||||
|
@ -133,8 +124,8 @@ void DialogueWindow::onSelectTopic(std::string topic)
|
|||
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.setGuiMode(GM_Barter);
|
||||
mWindowManager.getTradeWindow()->startTrade(mActor);
|
||||
mWindowManager.pushGuiMode(GM_Barter);
|
||||
mWindowManager.getTradeWindow()->startTrade(mPtr);
|
||||
}
|
||||
|
||||
else
|
||||
|
@ -144,9 +135,13 @@ void DialogueWindow::onSelectTopic(std::string topic)
|
|||
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
|
||||
{
|
||||
mEnabled = true;
|
||||
mActor = actor;
|
||||
mPtr = actor;
|
||||
topicsList->setEnabled(true);
|
||||
setTitle(npcName);
|
||||
|
||||
topicsList->clear();
|
||||
history->eraseText(0,history->getTextLength());
|
||||
updateOptions();
|
||||
}
|
||||
|
||||
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
|
||||
|
@ -161,7 +156,7 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
|
|||
if (anyService)
|
||||
topicsList->addSeparator();
|
||||
|
||||
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); it++)
|
||||
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
|
||||
{
|
||||
topicsList->addItem(*it);
|
||||
}
|
||||
|
@ -173,7 +168,6 @@ void DialogueWindow::removeKeyword(std::string keyWord)
|
|||
if(topicsList->hasItem(keyWord))
|
||||
{
|
||||
topicsList->removeItem(keyWord);
|
||||
pTopicsText.erase(keyWord);
|
||||
}
|
||||
topicsList->adjustSize();
|
||||
}
|
||||
|
@ -249,7 +243,6 @@ void DialogueWindow::updateOptions()
|
|||
{
|
||||
//Clear the list of topics
|
||||
topicsList->clear();
|
||||
pTopicsText.clear();
|
||||
history->eraseText(0,history->getTextLength());
|
||||
|
||||
pDispositionBar->setProgressRange(100);
|
||||
|
@ -264,3 +257,8 @@ void DialogueWindow::goodbye()
|
|||
topicsList->setEnabled(false);
|
||||
mEnabled = false;
|
||||
}
|
||||
|
||||
void DialogueWindow::onReferenceUnavailable()
|
||||
{
|
||||
mWindowManager.removeGuiMode(GM_Dialogue);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define MWGUI_DIALOGE_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
#include "referenceinterface.hpp"
|
||||
#include <boost/array.hpp>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
@ -25,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;
|
||||
|
||||
|
@ -60,6 +59,8 @@ namespace MWGui
|
|||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
|
||||
private:
|
||||
void updateOptions();
|
||||
/**
|
||||
|
@ -72,13 +73,10 @@ namespace MWGui
|
|||
|
||||
bool mEnabled;
|
||||
|
||||
MWWorld::Ptr mActor; // actor being talked to
|
||||
|
||||
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
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "container.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
|
@ -41,35 +43,60 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
|
|||
, 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 = health->getLeft();
|
||||
|
||||
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 = effectBox->getRight();
|
||||
effectBoxBaseRight = viewSize.width - effectBox->getRight();
|
||||
effectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
|
||||
|
||||
getWidget(minimapBox, "MiniMapBox");
|
||||
minimapBoxBaseRight = minimapBox->getRight();
|
||||
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);
|
||||
|
@ -77,15 +104,9 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
|
|||
getWidget(trianglecounter, "TriangleCounter");
|
||||
getWidget(batchcounter, "BatchCounter");
|
||||
|
||||
// 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);
|
||||
LocalMapBase::init(minimap, compass, this);
|
||||
|
||||
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
|
||||
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
|
||||
|
@ -94,6 +115,8 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
|
|||
|
||||
void HUD::setFpsLevel(int level)
|
||||
{
|
||||
fpscounter = 0;
|
||||
|
||||
MyGUI::Widget* fps;
|
||||
getWidget(fps, "FPSBoxAdv");
|
||||
fps->setVisible(false);
|
||||
|
@ -116,6 +139,7 @@ void HUD::setFpsLevel(int level)
|
|||
|
||||
void HUD::setFPS(float fps)
|
||||
{
|
||||
if (fpscounter)
|
||||
fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps));
|
||||
}
|
||||
|
||||
|
@ -129,28 +153,6 @@ void HUD::setBatchCount(size_t count)
|
|||
batchcounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -192,35 +194,6 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& v
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -228,7 +201,12 @@ void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellV
|
|||
spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft;
|
||||
|
||||
if (!weapVisible)
|
||||
spellDx -= spellBoxBaseLeft - weapBoxBaseLeft;
|
||||
spellDx += spellBoxBaseLeft - weapBoxBaseLeft;
|
||||
|
||||
mWeaponVisible = weapVisible;
|
||||
mSpellVisible = spellVisible;
|
||||
if (!mWeaponVisible && !mSpellVisible)
|
||||
mWeaponSpellBox->setVisible(false);
|
||||
|
||||
health->setVisible(hmsVisible);
|
||||
stamina->setVisible(hmsVisible);
|
||||
|
@ -241,13 +219,16 @@ void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellV
|
|||
|
||||
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 = minimapBoxBaseRight - effectBoxBaseRight;
|
||||
effectsDx = (viewSize.width - minimapBoxBaseRight) - (viewSize.width - effectBoxBaseRight);
|
||||
|
||||
mMapVisible = minimapBoxVisible;
|
||||
minimapBox->setVisible(minimapBoxVisible);
|
||||
effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop());
|
||||
effectBox->setPosition((viewSize.width - effectBoxBaseRight) - effectBox->getWidth() + effectsDx, effectBox->getTop());
|
||||
effectBox->setVisible(effectBoxVisible);
|
||||
}
|
||||
|
||||
|
@ -286,6 +267,33 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender)
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,6 +301,8 @@ 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);
|
||||
|
@ -312,11 +322,195 @@ void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y)
|
|||
else
|
||||
{
|
||||
MyGUI::PointerManager::getInstance().setPointer("arrow");
|
||||
/// \todo make it possible to pick up objects with the mouse, if inventory or container window is open
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <openengine/gui/layout.hpp>
|
||||
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
@ -12,22 +13,30 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
|
||||
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);
|
||||
|
||||
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;
|
||||
|
@ -36,6 +45,8 @@ namespace MWGui
|
|||
MyGUI::ScrollView* minimap;
|
||||
MyGUI::ImageBox* compass;
|
||||
MyGUI::ImageBox* crosshair;
|
||||
MyGUI::TextBox* mCellNameBox;
|
||||
MyGUI::TextBox* mWeaponSpellBox;
|
||||
|
||||
MyGUI::WidgetPtr fpsbox;
|
||||
MyGUI::TextBox* fpscounter;
|
||||
|
@ -50,8 +61,25 @@ namespace MWGui
|
|||
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,11 +15,14 @@
|
|||
#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
|
||||
{
|
||||
|
@ -91,13 +94,13 @@ namespace MWGui
|
|||
|
||||
mFilterAll->setStateSelected(true);
|
||||
|
||||
setCoord(0, 342, 600, 258);
|
||||
setCoord(0, 342, 498, 258);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
openContainer(player);
|
||||
}
|
||||
|
||||
void InventoryWindow::openInventory()
|
||||
void InventoryWindow::open()
|
||||
{
|
||||
updateEncumbranceBar();
|
||||
|
||||
|
@ -155,7 +158,7 @@ namespace MWGui
|
|||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
{
|
||||
// add item to the player's inventory
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
|
||||
int origCount = ptr.getRefData().getCount();
|
||||
|
@ -187,12 +190,21 @@ namespace MWGui
|
|||
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(mContainer).getInventoryStore(mContainer);
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
|
||||
|
@ -210,7 +222,7 @@ namespace MWGui
|
|||
|
||||
void InventoryWindow::_unequipItem(MWWorld::Ptr item)
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
|
@ -244,7 +256,7 @@ namespace MWGui
|
|||
|
||||
int InventoryWindow::getPlayerGold()
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
it != invStore.end(); ++it)
|
||||
|
@ -259,4 +271,79 @@ namespace MWGui
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,15 @@ namespace MWGui
|
|||
public:
|
||||
InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop);
|
||||
|
||||
void openInventory();
|
||||
virtual void open();
|
||||
|
||||
/// start trading, disables item drag&drop
|
||||
void startTrade();
|
||||
|
||||
void onFrame();
|
||||
|
||||
void pickUpObject (MWWorld::Ptr object);
|
||||
|
||||
int getPlayerGold();
|
||||
|
||||
protected:
|
||||
|
@ -48,6 +50,10 @@ namespace MWGui
|
|||
virtual bool isInventory() { return true; }
|
||||
virtual std::vector<MWWorld::Ptr> getEquippedItems();
|
||||
virtual void _unequipItem(MWWorld::Ptr item);
|
||||
|
||||
virtual void onReferenceUnavailable() { ; }
|
||||
|
||||
virtual void notifyContentChanged();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@ LocalMapBase::LocalMapBase()
|
|||
, mInterior(false)
|
||||
, mFogOfWar(true)
|
||||
, mLocalMap(NULL)
|
||||
, mMapDragAndDrop(false)
|
||||
, mPrefix()
|
||||
, mChanged(true)
|
||||
, mLayout(NULL)
|
||||
|
@ -18,13 +19,41 @@ LocalMapBase::LocalMapBase()
|
|||
, mLastPositionY(0.0f)
|
||||
, mLastDirectionX(0.0f)
|
||||
, mLastDirectionY(0.0f)
|
||||
, mCompass(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout)
|
||||
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)
|
||||
|
@ -47,10 +76,10 @@ void LocalMapBase::applyFogOfWar()
|
|||
{
|
||||
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");
|
||||
MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx];
|
||||
fog->setImageTexture(mFogOfWar ?
|
||||
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
|
||||
: "black.png" )
|
||||
|
@ -66,14 +95,13 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
|||
{
|
||||
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);
|
||||
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);
|
||||
|
@ -86,6 +114,42 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
|||
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;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
@ -102,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);
|
||||
|
||||
|
@ -111,7 +175,7 @@ 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)
|
||||
|
@ -119,33 +183,6 @@ void MapWindow::setCellName(const std::string& cellName)
|
|||
setTitle(cellName);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
||||
{
|
||||
if (_id!=MyGUI::MouseButton::Left) return;
|
||||
|
@ -172,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);
|
||||
}
|
||||
|
|
|
@ -9,10 +9,12 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
LocalMapBase();
|
||||
void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout);
|
||||
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();
|
||||
|
||||
|
@ -20,14 +22,20 @@ namespace MWGui
|
|||
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;
|
||||
|
@ -40,8 +48,6 @@ namespace MWGui
|
|||
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:
|
||||
|
|
|
@ -58,7 +58,7 @@ void MessageBoxManager::onFrame (float frameDuration)
|
|||
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
|
||||
delete mInterMessageBoxe;
|
||||
mInterMessageBoxe = NULL;
|
||||
mWindowManager->setNextMode(GM_Game);
|
||||
mWindowManager->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,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;
|
||||
|
|
|
@ -5,7 +5,7 @@ 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
|
||||
|
@ -15,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);
|
||||
|
@ -255,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);
|
||||
|
||||
|
@ -288,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
|
||||
|
@ -74,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();
|
||||
|
||||
|
@ -137,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)
|
||||
|
@ -151,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)
|
||||
|
@ -195,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)
|
||||
|
@ -214,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();
|
||||
|
@ -228,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);
|
||||
|
||||
|
@ -235,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);
|
||||
|
@ -256,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);
|
||||
|
||||
|
@ -297,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;
|
||||
}
|
||||
}
|
||||
|
@ -330,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
|
||||
|
@ -363,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) :
|
||||
|
@ -55,7 +56,7 @@ void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
|||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
||||
|
||||
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
|
@ -65,5 +66,5 @@ void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
|||
MWWorld::ActionTake take(mScroll);
|
||||
take.execute();
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
||||
|
|
342
apps/openmw/mwgui/settingswindow.cpp
Normal file
342
apps/openmw/mwgui/settingswindow.cpp
Normal file
|
@ -0,0 +1,342 @@
|
|||
#include "settingswindow.hpp"
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderSystem.h>
|
||||
#include <OgreString.h>
|
||||
|
||||
#include <boost/lexical_cast.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";
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
mResolutionList->addItem(*it);
|
||||
}
|
||||
|
||||
// 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.popGuiMode();
|
||||
}
|
||||
|
||||
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());
|
||||
size_t xPos = resStr.find("x");
|
||||
std::string resXStr = resStr.substr(0, xPos-1);
|
||||
Ogre::StringUtil::trim(resXStr);
|
||||
std::string resYStr = resStr.substr(xPos+2, resStr.size()-(xPos+2));
|
||||
Ogre::StringUtil::trim(resYStr);
|
||||
int resX = boost::lexical_cast<int>(resXStr);
|
||||
int resY = boost::lexical_cast<int>(resYStr);
|
||||
|
||||
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);
|
||||
size_t xPos = resStr.find("x");
|
||||
std::string resXStr = resStr.substr(0, xPos-1);
|
||||
Ogre::StringUtil::trim(resXStr);
|
||||
std::string resYStr = resStr.substr(xPos+2, resStr.size()-(xPos+2));
|
||||
Ogre::StringUtil::trim(resYStr);
|
||||
int resX = boost::lexical_cast<int>(resXStr);
|
||||
int resY = boost::lexical_cast<int>(resYStr);
|
||||
|
||||
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
|
||||
|
459
apps/openmw/mwgui/spellwindow.cpp
Normal file
459
apps/openmw/mwgui/spellwindow.cpp
Normal file
|
@ -0,0 +1,459 @@
|
|||
#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)
|
||||
{
|
||||
// abilities are always active and don't show in the spell window.
|
||||
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
|
|
@ -12,6 +12,7 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
|
||||
using namespace MWGui;
|
||||
|
@ -77,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)
|
||||
|
@ -256,6 +255,8 @@ void StatsWindow::configureSkills (const std::vector<int>& major, const std::vec
|
|||
if (skillSet.find(skill) == skillSet.end())
|
||||
miscSkills.push_back(skill);
|
||||
}
|
||||
|
||||
updateSkillArea();
|
||||
}
|
||||
|
||||
void StatsWindow::onFrame ()
|
||||
|
@ -339,7 +340,7 @@ MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::st
|
|||
return skillValueWidget;
|
||||
}
|
||||
|
||||
MyGUI::Widget* 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;
|
||||
|
||||
|
@ -444,32 +445,17 @@ void StatsWindow::updateSkillArea()
|
|||
const ESM::Race* playerRace = store.races.find (MWBase::Environment::get().getWorld()->getPlayer().getRace());
|
||||
MyGUI::Widget* raceWidget;
|
||||
getWidget(raceWidget, "RaceText");
|
||||
raceWidget->setUserString("Caption_CenteredCaption", playerRace->name);
|
||||
raceWidget->setUserString("Caption_CenteredCaptionText", playerRace->description);
|
||||
ToolTips::createRaceToolTip(raceWidget, playerRace);
|
||||
getWidget(raceWidget, "Race_str");
|
||||
raceWidget->setUserString("Caption_CenteredCaption", playerRace->name);
|
||||
raceWidget->setUserString("Caption_CenteredCaptionText", playerRace->description);
|
||||
ToolTips::createRaceToolTip(raceWidget, playerRace);
|
||||
|
||||
// class tooltip
|
||||
MyGUI::Widget* classWidget;
|
||||
const ESM::Class& playerClass = MWBase::Environment::get().getWorld()->getPlayer().getClass();
|
||||
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}";
|
||||
|
||||
getWidget(classWidget, "ClassText");
|
||||
classWidget->setUserString("Caption_ClassName", playerClass.name);
|
||||
classWidget->setUserString("Caption_ClassDescription", playerClass.description);
|
||||
classWidget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr);
|
||||
ToolTips::createClassToolTip(classWidget, playerClass);
|
||||
getWidget(classWidget, "Class_str");
|
||||
classWidget->setUserString("Caption_ClassName", playerClass.name);
|
||||
classWidget->setUserString("Caption_ClassDescription", playerClass.description);
|
||||
classWidget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr);
|
||||
ToolTips::createClassToolTip(classWidget, playerClass);
|
||||
|
||||
if (!mFactions.empty())
|
||||
{
|
||||
|
@ -536,61 +522,8 @@ void StatsWindow::updateSkillArea()
|
|||
addGroup(mWindowManager.getGameSettingString("sBirthSign", "Sign"), coord1, coord2);
|
||||
const ESM::BirthSign *sign = store.birthSigns.find(birthSignId);
|
||||
MyGUI::Widget* w = addItem(sign->name, coord1, coord2);
|
||||
w->setUserString("ToolTipType", "Layout");
|
||||
w->setUserString("ToolTipLayout", "BirthSignToolTip");
|
||||
std::string image = sign->texture;
|
||||
image.replace(image.size()-3, 3, "dds");
|
||||
w->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 = store.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 = store.spells.search(spellId);
|
||||
text += "\n#BF9959" + spell->name;
|
||||
}
|
||||
}
|
||||
|
||||
w->setUserString("Caption_BirthSignText", text);
|
||||
ToolTips::createBirthsignToolTip(w, birthSignId);
|
||||
}
|
||||
|
||||
// Add a line separator if there are items above
|
||||
|
@ -633,116 +566,3 @@ void StatsWindow::onPinToggled()
|
|||
{
|
||||
mWindowManager.setHMSVisibility(!mPinned);
|
||||
}
|
||||
|
||||
void StatsWindow::setupToolTips()
|
||||
{
|
||||
|
||||
const ESMS::ESMStore &store = mWindowManager.getStore();
|
||||
MyGUI::Widget* widget;
|
||||
|
||||
/// \todo move this into the .layout file!
|
||||
|
||||
getWidget(widget, "Attrib1");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeStrength")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sStrDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_strength.dds");
|
||||
getWidget(widget, "AttribVal1");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeStrength")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sStrDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_strength.dds");
|
||||
|
||||
getWidget(widget, "Attrib2");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeIntelligence")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sIntDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_int.dds");
|
||||
getWidget(widget, "AttribVal2");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeIntelligence")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sIntDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_int.dds");
|
||||
|
||||
getWidget(widget, "Attrib3");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeWillpower")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sWilDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_wilpower.dds");
|
||||
getWidget(widget, "AttribVal3");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeWillpower")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sWilDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_wilpower.dds");
|
||||
|
||||
getWidget(widget, "Attrib4");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeAgility")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sAgiDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_agility.dds");
|
||||
getWidget(widget, "AttribVal4");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeAgility")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sAgiDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_agility.dds");
|
||||
|
||||
getWidget(widget, "Attrib5");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeSpeed")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sSpdDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_speed.dds");
|
||||
getWidget(widget, "AttribVal5");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeSpeed")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sSpdDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_speed.dds");
|
||||
|
||||
getWidget(widget, "Attrib6");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeEndurance")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sEndDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_endurance.dds");
|
||||
getWidget(widget, "AttribVal6");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeEndurance")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sEndDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_endurance.dds");
|
||||
|
||||
getWidget(widget, "Attrib7");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributePersonality")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sPerDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_personality.dds");
|
||||
getWidget(widget, "AttribVal7");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributePersonality")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sPerDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_personality.dds");
|
||||
|
||||
getWidget(widget, "Attrib8");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeLuck")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sLucDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_luck.dds");
|
||||
getWidget(widget, "AttribVal8");
|
||||
widget->setUserString("ToolTipType", "Layout");
|
||||
widget->setUserString("ToolTipLayout", "AttributeToolTip");
|
||||
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeLuck")->str);
|
||||
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sLucDesc")->str);
|
||||
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_luck.dds");
|
||||
}
|
||||
|
|
|
@ -47,11 +47,9 @@ namespace MWGui
|
|||
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);
|
||||
MyGUI::Widget* addItem(const std::string text, 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);
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace MyGUI;
|
||||
|
||||
|
@ -19,6 +21,10 @@ ToolTips::ToolTips(WindowManager* windowManager) :
|
|||
, mEnabled(true)
|
||||
, mFocusToolTipX(0.0)
|
||||
, mFocusToolTipY(0.0)
|
||||
, mDelay(0.0)
|
||||
, mRemainingDelay(0.0)
|
||||
, mLastMouseX(0)
|
||||
, mLastMouseY(0)
|
||||
{
|
||||
getWidget(mDynamicToolTipBox, "DynamicToolTipBox");
|
||||
|
||||
|
@ -28,6 +34,9 @@ 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)
|
||||
|
@ -37,10 +46,10 @@ void ToolTips::setEnabled(bool enabled)
|
|||
|
||||
void ToolTips::onFrame(float frameDuration)
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox);
|
||||
mDynamicToolTipBox = mMainWidget->createWidget<Widget>("HUD_Box",
|
||||
IntCoord(0, 0, mMainWidget->getCoord().width, mMainWidget->getCoord().height),
|
||||
Align::Stretch, "DynamicToolTipBox");
|
||||
while (mDynamicToolTipBox->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox->getChildAt(0));
|
||||
}
|
||||
|
||||
// start by hiding everything
|
||||
for (unsigned int i=0; i < mMainWidget->getChildCount(); ++i)
|
||||
|
@ -57,6 +66,60 @@ void ToolTips::onFrame(float frameDuration)
|
|||
|
||||
if (!mGameMode)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MyGUI::IntSize tooltipSize = getToolTipViaPtr(true);
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -65,10 +128,20 @@ void ToolTips::onFrame(float frameDuration)
|
|||
|
||||
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");
|
||||
|
||||
ToolTipInfo info;
|
||||
if (type == "")
|
||||
{
|
||||
return;
|
||||
|
@ -78,6 +151,29 @@ void ToolTips::onFrame(float frameDuration)
|
|||
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
|
||||
|
@ -157,6 +253,7 @@ void ToolTips::onFrame(float frameDuration)
|
|||
|
||||
setCoord(tooltipPosition.left, tooltipPosition.top, tooltipSize.width, tooltipSize.height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mFocusObject.isEmpty())
|
||||
|
@ -285,7 +382,7 @@ IntSize ToolTips::createToolTip(const MWGui::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),
|
||||
|
@ -305,7 +402,7 @@ IntSize ToolTips::createToolTip(const MWGui::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);
|
||||
}
|
||||
|
@ -321,7 +418,7 @@ IntSize ToolTips::createToolTip(const MWGui::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;
|
||||
|
@ -339,7 +436,6 @@ IntSize ToolTips::createToolTip(const MWGui::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;
|
||||
|
@ -440,3 +536,156 @@ void ToolTips::setFocusObjectScreenCoords(float min_x, float min_y, float max_x,
|
|||
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
|
||||
|
@ -44,6 +41,8 @@ namespace MWGui
|
|||
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
|
||||
|
@ -60,6 +59,15 @@ namespace MWGui
|
|||
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;
|
||||
|
||||
|
@ -78,6 +86,12 @@ namespace MWGui
|
|||
float mFocusToolTipX;
|
||||
float mFocusToolTipY;
|
||||
|
||||
float mDelay;
|
||||
float mRemainingDelay; // remaining time until tooltip will show
|
||||
|
||||
int mLastMouseX;
|
||||
int mLastMouseY;
|
||||
|
||||
bool mGameMode;
|
||||
|
||||
bool mEnabled;
|
||||
|
|
|
@ -104,6 +104,8 @@ namespace MWGui
|
|||
ContainerBase::openContainer(actor);
|
||||
|
||||
updateLabels();
|
||||
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void TradeWindow::onFilterChanged(MyGUI::Widget* _sender)
|
||||
|
@ -157,9 +159,9 @@ namespace MWGui
|
|||
|
||||
// check if the merchant can afford this
|
||||
int merchantgold;
|
||||
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>();
|
||||
if (ref->base->npdt52.gold == -10)
|
||||
merchantgold = ref->base->npdt12.gold;
|
||||
else
|
||||
|
@ -167,7 +169,7 @@ namespace MWGui
|
|||
}
|
||||
else // ESM::Creature
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>();
|
||||
merchantgold = ref->base->data.gold;
|
||||
}
|
||||
if (mCurrentBalance > 0 && merchantgold < mCurrentBalance)
|
||||
|
@ -210,7 +212,7 @@ namespace MWGui
|
|||
std::string sound = "Item Gold Up";
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
mWindowManager.setGuiMode(GM_Game);
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
||||
|
||||
void TradeWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
|
@ -218,9 +220,9 @@ namespace MWGui
|
|||
// i give you back your stuff!
|
||||
returnBoughtItems(mWindowManager.getInventoryWindow()->getContainerStore());
|
||||
// now gimme back my stuff!
|
||||
mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mContainer).getContainerStore(mContainer));
|
||||
mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mPtr).getContainerStore(mPtr));
|
||||
|
||||
mWindowManager.setGuiMode(GM_Game);
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
||||
|
||||
void TradeWindow::updateLabels()
|
||||
|
@ -240,9 +242,9 @@ namespace MWGui
|
|||
}
|
||||
|
||||
int merchantgold;
|
||||
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>();
|
||||
if (ref->base->npdt52.gold == -10)
|
||||
merchantgold = ref->base->npdt12.gold;
|
||||
else
|
||||
|
@ -250,7 +252,7 @@ namespace MWGui
|
|||
}
|
||||
else // ESM::Creature
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>();
|
||||
merchantgold = ref->base->data.gold;
|
||||
}
|
||||
|
||||
|
@ -262,13 +264,13 @@ namespace MWGui
|
|||
{
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
|
||||
if (mContainer.getTypeName() == typeid(ESM::Creature).name())
|
||||
if (mPtr.getTypeName() == typeid(ESM::Creature).name())
|
||||
{
|
||||
// creatures don't have equipment slots.
|
||||
return items;
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
|
@ -285,19 +287,21 @@ namespace MWGui
|
|||
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
|
||||
{
|
||||
int services = 0;
|
||||
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>();
|
||||
if (ref->base->hasAI)
|
||||
services = ref->base->AI.services;
|
||||
}
|
||||
else if (mContainer.getTypeName() == typeid(ESM::Creature).name())
|
||||
else if (mPtr.getTypeName() == typeid(ESM::Creature).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
|
||||
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())
|
||||
|
@ -327,7 +331,7 @@ namespace MWGui
|
|||
std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore()
|
||||
{
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
it != invStore.end(); ++it)
|
||||
|
@ -356,4 +360,11 @@ namespace MWGui
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,8 @@ namespace MWGui
|
|||
virtual std::vector<MWWorld::Ptr> itemsToIgnore();
|
||||
|
||||
void updateLabels();
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -21,8 +21,58 @@ namespace MWGui
|
|||
|
||||
namespace Widgets
|
||||
{
|
||||
class MWEffectList;
|
||||
|
||||
void fixTexturePath(std::string &path);
|
||||
|
||||
struct SpellEffectParams
|
||||
{
|
||||
SpellEffectParams()
|
||||
: mMagnMin(-1)
|
||||
, mMagnMax(-1)
|
||||
, mRange(-1)
|
||||
, mDuration(-1)
|
||||
, mSkill(-1)
|
||||
, mAttribute(-1)
|
||||
, mEffectID(-1)
|
||||
, mNoTarget(false)
|
||||
, mIsConstant(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool mNoTarget; // potion effects for example have no target (target is always the player)
|
||||
bool mIsConstant; // constant effect means that duration will not be displayed
|
||||
|
||||
// value of -1 here means the effect is unknown to the player
|
||||
short mEffectID;
|
||||
|
||||
// value of -1 here means there is no skill/attribute
|
||||
signed char mSkill, mAttribute;
|
||||
|
||||
// value of -1 here means the value is unavailable
|
||||
int mMagnMin, mMagnMax, mRange, mDuration;
|
||||
|
||||
bool operator==(const SpellEffectParams& other) const
|
||||
{
|
||||
if (mEffectID != other.mEffectID)
|
||||
return false;
|
||||
|
||||
bool involvesAttribute = (mEffectID == 74 // restore attribute
|
||||
|| mEffectID == 85 // absorb attribute
|
||||
|| mEffectID == 17 // drain attribute
|
||||
|| mEffectID == 79 // fortify attribute
|
||||
|| mEffectID == 22); // damage attribute
|
||||
bool involvesSkill = (mEffectID == 78 // restore skill
|
||||
|| mEffectID == 89 // absorb skill
|
||||
|| mEffectID == 21 // drain skill
|
||||
|| mEffectID == 83 // fortify skill
|
||||
|| mEffectID == 26); // damage skill
|
||||
return ((other.mSkill == mSkill) || !involvesSkill) && ((other.mAttribute == mAttribute) && !involvesAttribute);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<SpellEffectParams> SpellEffectList;
|
||||
|
||||
class MYGUI_EXPORT MWSkill : public Widget
|
||||
{
|
||||
MYGUI_RTTI_DERIVED( MWSkill );
|
||||
|
@ -108,6 +158,9 @@ namespace MWGui
|
|||
};
|
||||
typedef MWAttribute* MWAttributePtr;
|
||||
|
||||
/**
|
||||
* @todo remove this class and use MWEffectList instead
|
||||
*/
|
||||
class MWSpellEffect;
|
||||
class MYGUI_EXPORT MWSpell : public Widget
|
||||
{
|
||||
|
@ -155,12 +208,14 @@ namespace MWGui
|
|||
|
||||
enum EffectFlags
|
||||
{
|
||||
EF_Potion = 0x01, // potions have no target (target is always the player)
|
||||
EF_NoTarget = 0x01, // potions have no target (target is always the player)
|
||||
EF_Constant = 0x02 // constant effect means that duration will not be displayed
|
||||
};
|
||||
|
||||
void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; }
|
||||
void setEffectList(const ESM::EffectList* list);
|
||||
void setEffectList(const SpellEffectList& list);
|
||||
|
||||
static SpellEffectList effectListFromESM(const ESM::EffectList* effects);
|
||||
|
||||
/**
|
||||
* @param vector to store the created effect widgets
|
||||
|
@ -180,7 +235,7 @@ namespace MWGui
|
|||
void updateWidgets();
|
||||
|
||||
WindowManager* mWindowManager;
|
||||
const ESM::EffectList* mEffectList;
|
||||
SpellEffectList mEffectList;
|
||||
};
|
||||
typedef MWEffectList* MWEffectListPtr;
|
||||
|
||||
|
@ -193,14 +248,13 @@ namespace MWGui
|
|||
typedef ESM::ENAMstruct SpellEffectValue;
|
||||
|
||||
void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; }
|
||||
void setSpellEffect(SpellEffectValue value);
|
||||
void setFlags(int flags) { mFlags = flags; }
|
||||
void setSpellEffect(const SpellEffectParams& params);
|
||||
|
||||
std::string effectIDToString(const short effectID);
|
||||
bool effectHasMagnitude (const std::string& effect);
|
||||
bool effectHasDuration (const std::string& effect);
|
||||
|
||||
const SpellEffectValue &getSpellEffect() const { return effect; }
|
||||
bool effectInvolvesAttribute (const std::string& effect);
|
||||
bool effectInvolvesSkill (const std::string& effect);
|
||||
|
||||
int getRequestedWidth() const { return mRequestedWidth; }
|
||||
|
||||
|
@ -214,8 +268,7 @@ namespace MWGui
|
|||
void updateWidgets();
|
||||
|
||||
WindowManager* mWindowManager;
|
||||
SpellEffectValue effect;
|
||||
int mFlags;
|
||||
SpellEffectParams mEffectParams;
|
||||
MyGUI::ImageBox* imageWidget;
|
||||
MyGUI::TextBox* textWidget;
|
||||
int mRequestedWidth;
|
||||
|
@ -229,7 +282,7 @@ namespace MWGui
|
|||
MWDynamicStat();
|
||||
|
||||
void setValue(int value, int max);
|
||||
void setTitle(const std::string text);
|
||||
void setTitle(const std::string& text);
|
||||
|
||||
int getValue() const { return value; }
|
||||
int getMax() const { return max; }
|
||||
|
@ -247,7 +300,6 @@ namespace MWGui
|
|||
MyGUI::TextBox* barTextWidget;
|
||||
};
|
||||
typedef MWDynamicStat* MWDynamicStatPtr;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "window_base.hpp"
|
||||
#include "window_manager.hpp"
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
WindowBase::WindowBase(const std::string& parLayout, WindowManager& parWindowManager)
|
||||
|
@ -13,10 +15,25 @@ void WindowBase::open()
|
|||
{
|
||||
}
|
||||
|
||||
void WindowBase::setVisible(bool visible)
|
||||
{
|
||||
bool wasVisible = mMainWidget->getVisible();
|
||||
mMainWidget->setVisible(visible);
|
||||
|
||||
if (!wasVisible && visible)
|
||||
open();
|
||||
}
|
||||
|
||||
void WindowBase::center()
|
||||
{
|
||||
// Centre dialog
|
||||
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
||||
// MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
// Note by scrawl: The following works more reliably in the case when the window was _just_
|
||||
// resized and MyGUI RenderManager doesn't know about the new size yet
|
||||
MyGUI::IntSize gameWindowSize = MyGUI::IntSize(Settings::Manager::getInt("resolution x", "Video"),
|
||||
Settings::Manager::getInt("resolution y", "Video"));
|
||||
|
||||
MyGUI::IntCoord coord = mMainWidget->getCoord();
|
||||
coord.left = (gameWindowSize.width - coord.width)/2;
|
||||
coord.top = (gameWindowSize.height - coord.height)/2;
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace MWGui
|
|||
typedef MyGUI::delegates::CMultiDelegate1<WindowBase*> EventHandle_WindowBase;
|
||||
|
||||
virtual void open();
|
||||
virtual void setVisible(bool visible); // calls open() if visible is true and was false before
|
||||
void center();
|
||||
|
||||
/** Event : Dialog finished, OK button clicked.\n
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
#include "mainmenu.hpp"
|
||||
#include "countdialog.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
#include "settingswindow.hpp"
|
||||
#include "confirmationdialog.hpp"
|
||||
#include "alchemywindow.hpp"
|
||||
#include "spellwindow.hpp"
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
|
@ -35,7 +39,7 @@
|
|||
using namespace MWGui;
|
||||
|
||||
WindowManager::WindowManager(
|
||||
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath)
|
||||
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath)
|
||||
: mGuiManager(NULL)
|
||||
, hud(NULL)
|
||||
, map(NULL)
|
||||
|
@ -45,11 +49,15 @@ WindowManager::WindowManager(
|
|||
, mMessageBoxManager(NULL)
|
||||
, console(NULL)
|
||||
, mJournal(NULL)
|
||||
, mDialogueWindow(nullptr)
|
||||
, mDialogueWindow(NULL)
|
||||
, mBookWindow(NULL)
|
||||
, mScrollWindow(NULL)
|
||||
, mCountDialog(NULL)
|
||||
, mTradeWindow(NULL)
|
||||
, mSettingsWindow(NULL)
|
||||
, mConfirmationDialog(NULL)
|
||||
, mAlchemyWindow(NULL)
|
||||
, mSpellWindow(NULL)
|
||||
, mCharGen(NULL)
|
||||
, playerClass()
|
||||
, playerName()
|
||||
|
@ -62,9 +70,6 @@ WindowManager::WindowManager(
|
|||
, playerMagicka()
|
||||
, playerFatigue()
|
||||
, gui(NULL)
|
||||
, mode(GM_Game)
|
||||
, nextMode(GM_Game)
|
||||
, needModeChange(false)
|
||||
, garbageDialogs()
|
||||
, shown(GW_ALL)
|
||||
, allowed(newGame ? GW_None : GW_ALL)
|
||||
|
@ -118,6 +123,10 @@ WindowManager::WindowManager(
|
|||
mScrollWindow = new ScrollWindow(*this);
|
||||
mBookWindow = new BookWindow(*this);
|
||||
mCountDialog = new CountDialog(*this);
|
||||
mSettingsWindow = new SettingsWindow(*this);
|
||||
mConfirmationDialog = new ConfirmationDialog(*this);
|
||||
mAlchemyWindow = new AlchemyWindow(*this);
|
||||
mSpellWindow = new SpellWindow(*this);
|
||||
|
||||
// The HUD is always on
|
||||
hud->setVisible(true);
|
||||
|
@ -135,6 +144,9 @@ WindowManager::WindowManager(
|
|||
playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>()));
|
||||
}
|
||||
|
||||
unsetSelectedSpell();
|
||||
unsetSelectedWeapon();
|
||||
|
||||
// Set up visibility
|
||||
updateVisible();
|
||||
}
|
||||
|
@ -158,6 +170,10 @@ WindowManager::~WindowManager()
|
|||
delete mBookWindow;
|
||||
delete mScrollWindow;
|
||||
delete mTradeWindow;
|
||||
delete mSettingsWindow;
|
||||
delete mConfirmationDialog;
|
||||
delete mAlchemyWindow;
|
||||
delete mSpellWindow;
|
||||
|
||||
cleanupGarbage();
|
||||
}
|
||||
|
@ -178,30 +194,11 @@ void WindowManager::cleanupGarbage()
|
|||
void WindowManager::update()
|
||||
{
|
||||
cleanupGarbage();
|
||||
if (needModeChange)
|
||||
{
|
||||
needModeChange = false;
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode(nextMode);
|
||||
nextMode = GM_Game;
|
||||
}
|
||||
if (showFPSLevel > 0)
|
||||
{
|
||||
|
||||
hud->setFPS(mFPS);
|
||||
hud->setTriangleCount(mTriangleCount);
|
||||
hud->setBatchCount(mBatchCount);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::setNextMode(GuiMode newMode)
|
||||
{
|
||||
nextMode = newMode;
|
||||
needModeChange = true;
|
||||
}
|
||||
|
||||
void WindowManager::setGuiMode(GuiMode newMode)
|
||||
{
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode(newMode);
|
||||
}
|
||||
|
||||
void WindowManager::updateVisible()
|
||||
{
|
||||
|
@ -217,22 +214,38 @@ void WindowManager::updateVisible()
|
|||
mScrollWindow->setVisible(false);
|
||||
mBookWindow->setVisible(false);
|
||||
mTradeWindow->setVisible(false);
|
||||
mSettingsWindow->setVisible(false);
|
||||
mAlchemyWindow->setVisible(false);
|
||||
mSpellWindow->setVisible(false);
|
||||
|
||||
// Mouse is visible whenever we're not in game mode
|
||||
MyGUI::PointerManager::getInstance().setVisible(isGuiMode());
|
||||
|
||||
if (mode == GM_Game)
|
||||
bool gameMode = !isGuiMode();
|
||||
|
||||
if (gameMode)
|
||||
mToolTips->enterGameMode();
|
||||
else
|
||||
mToolTips->enterGuiMode();
|
||||
|
||||
switch(mode) {
|
||||
case GM_Game:
|
||||
setMinimapVisibility((allowed & GW_Map) && !map->pinned());
|
||||
setWeaponVisibility((allowed & GW_Inventory) && !mInventoryWindow->pinned());
|
||||
setSpellVisibility((allowed & GW_Magic) && !mSpellWindow->pinned());
|
||||
setHMSVisibility((allowed & GW_Stats) && !mStatsWindow->pinned());
|
||||
|
||||
// If in game mode, don't show anything.
|
||||
break;
|
||||
if (gameMode)
|
||||
return;
|
||||
|
||||
GuiMode mode = mGuiModes.back();
|
||||
|
||||
switch(mode) {
|
||||
case GM_MainMenu:
|
||||
menu->setVisible(true);
|
||||
break;
|
||||
case GM_Settings:
|
||||
mSettingsWindow->setVisible(true);
|
||||
break;
|
||||
case GM_Console:
|
||||
console->enable();
|
||||
break;
|
||||
|
@ -242,6 +255,9 @@ void WindowManager::updateVisible()
|
|||
case GM_Book:
|
||||
mBookWindow->setVisible(true);
|
||||
break;
|
||||
case GM_Alchemy:
|
||||
mAlchemyWindow->setVisible(true);
|
||||
break;
|
||||
case GM_Name:
|
||||
case GM_Race:
|
||||
case GM_Class:
|
||||
|
@ -261,29 +277,24 @@ void WindowManager::updateVisible()
|
|||
int eff = shown & allowed;
|
||||
|
||||
// Show the windows we want
|
||||
map -> setVisible( (eff & GW_Map) != 0 );
|
||||
mStatsWindow -> setVisible( (eff & GW_Stats) != 0 );
|
||||
mInventoryWindow->setVisible(true);
|
||||
mInventoryWindow->openInventory();
|
||||
map -> setVisible(eff & GW_Map);
|
||||
mStatsWindow -> setVisible(eff & GW_Stats);
|
||||
mInventoryWindow->setVisible(eff & GW_Inventory);
|
||||
mSpellWindow->setVisible(eff & GW_Magic);
|
||||
break;
|
||||
}
|
||||
case GM_Container:
|
||||
mContainerWindow->setVisible(true);
|
||||
mInventoryWindow->setVisible(true);
|
||||
mInventoryWindow->openInventory();
|
||||
break;
|
||||
case GM_Dialogue:
|
||||
mDialogueWindow->open();
|
||||
mDialogueWindow->setVisible(true);
|
||||
break;
|
||||
case GM_Barter:
|
||||
mInventoryWindow->setVisible(true);
|
||||
mInventoryWindow->openInventory();
|
||||
mTradeWindow->setVisible(true);
|
||||
break;
|
||||
case GM_InterMessageBox:
|
||||
if(!mMessageBoxManager->isInteractiveMessageBox()) {
|
||||
setGuiMode(GM_Game);
|
||||
}
|
||||
break;
|
||||
case GM_Journal:
|
||||
mJournal->setVisible(true);
|
||||
|
@ -291,9 +302,6 @@ void WindowManager::updateVisible()
|
|||
break;
|
||||
default:
|
||||
// Unsupported mode, switch back to game
|
||||
// Note: The call will eventually end up this method again but
|
||||
// will stop at the check if mode is GM_Game.
|
||||
setGuiMode(GM_Game);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -301,6 +309,7 @@ void WindowManager::updateVisible()
|
|||
void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
|
||||
{
|
||||
mStatsWindow->setValue (id, value);
|
||||
mCharGen->setValue(id, value);
|
||||
|
||||
static const char *ids[] =
|
||||
{
|
||||
|
@ -331,6 +340,7 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int
|
|||
void WindowManager::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
|
||||
{
|
||||
mStatsWindow->setValue(parSkill, value);
|
||||
mCharGen->setValue(parSkill, value);
|
||||
playerSkillValues[parSkill] = value;
|
||||
}
|
||||
|
||||
|
@ -338,6 +348,7 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicS
|
|||
{
|
||||
mStatsWindow->setValue (id, value);
|
||||
hud->setValue (id, value);
|
||||
mCharGen->setValue(id, value);
|
||||
if (id == "HBar")
|
||||
{
|
||||
playerHealth = value;
|
||||
|
@ -390,6 +401,7 @@ void WindowManager::setPlayerClass (const ESM::Class &class_)
|
|||
void WindowManager::configureSkills (const SkillList& major, const SkillList& minor)
|
||||
{
|
||||
mStatsWindow->configureSkills (major, minor);
|
||||
mCharGen->configureSkills(major, minor);
|
||||
playerMajorSkills = major;
|
||||
playerMinorSkills = minor;
|
||||
}
|
||||
|
@ -427,7 +439,7 @@ void WindowManager::messageBox (const std::string& message, const std::vector<st
|
|||
else
|
||||
{
|
||||
mMessageBoxManager->createInteractiveMessageBox(message, buttons);
|
||||
setGuiMode(GM_InterMessageBox);
|
||||
pushGuiMode(GM_InterMessageBox);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,7 +464,7 @@ void WindowManager::onDialogueWindowBye()
|
|||
//removeDialog(dialogueWindow);
|
||||
mDialogueWindow->setVisible(false);
|
||||
}
|
||||
setGuiMode(GM_Game);
|
||||
popGuiMode();
|
||||
}
|
||||
|
||||
void WindowManager::onFrame (float frameDuration)
|
||||
|
@ -469,6 +481,13 @@ void WindowManager::onFrame (float frameDuration)
|
|||
mInventoryWindow->onFrame();
|
||||
|
||||
mStatsWindow->onFrame();
|
||||
|
||||
hud->onFrame(frameDuration);
|
||||
|
||||
mDialogueWindow->checkReferenceAvailable();
|
||||
mTradeWindow->checkReferenceAvailable();
|
||||
mContainerWindow->checkReferenceAvailable();
|
||||
console->checkReferenceAvailable();
|
||||
}
|
||||
|
||||
const ESMS::ESMStore& WindowManager::getStore() const
|
||||
|
@ -493,6 +512,7 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
|
|||
}
|
||||
|
||||
map->setCellName( name );
|
||||
hud->setCellName( name );
|
||||
|
||||
map->setCellPrefix("Cell");
|
||||
hud->setCellPrefix("Cell");
|
||||
|
@ -502,6 +522,7 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
|
|||
else
|
||||
{
|
||||
map->setCellName( cell->cell->name );
|
||||
hud->setCellName( cell->cell->name );
|
||||
map->setCellPrefix( cell->cell->name );
|
||||
hud->setCellPrefix( cell->cell->name );
|
||||
}
|
||||
|
@ -542,14 +563,6 @@ void WindowManager::toggleFogOfWar()
|
|||
hud->toggleFogOfWar();
|
||||
}
|
||||
|
||||
int WindowManager::toggleFps()
|
||||
{
|
||||
showFPSLevel = (showFPSLevel+1)%3;
|
||||
hud->setFpsLevel(showFPSLevel);
|
||||
Settings::Manager::setInt("fps", "HUD", showFPSLevel);
|
||||
return showFPSLevel;
|
||||
}
|
||||
|
||||
void WindowManager::setFocusObject(const MWWorld::Ptr& focus)
|
||||
{
|
||||
mToolTips->setFocusObject(focus);
|
||||
|
@ -572,12 +585,13 @@ bool WindowManager::getFullHelp() const
|
|||
|
||||
void WindowManager::setWeaponVisibility(bool visible)
|
||||
{
|
||||
hud->weapBox->setVisible(visible);
|
||||
hud->setBottomLeftVisibility(hud->health->getVisible(), visible, hud->spellBox->getVisible());
|
||||
}
|
||||
|
||||
void WindowManager::setSpellVisibility(bool visible)
|
||||
{
|
||||
hud->spellBox->setVisible(visible);
|
||||
hud->setBottomLeftVisibility(hud->health->getVisible(), hud->weapBox->getVisible(), visible);
|
||||
hud->setBottomRightVisibility(visible, hud->minimapBox->getVisible());
|
||||
}
|
||||
|
||||
void WindowManager::setMouseVisible(bool visible)
|
||||
|
@ -596,4 +610,125 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r
|
|||
const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.search(_tag);
|
||||
if (setting && setting->type == ESM::VT_String)
|
||||
_result = setting->str;
|
||||
else
|
||||
_result = _tag;
|
||||
}
|
||||
|
||||
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)
|
||||
{
|
||||
hud->setFpsLevel(Settings::Manager::getInt("fps", "HUD"));
|
||||
mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI"));
|
||||
|
||||
bool changeRes = false;
|
||||
for (Settings::CategorySettingVector::const_iterator it = changed.begin();
|
||||
it != changed.end(); ++it)
|
||||
{
|
||||
if (it->first == "Video" && (
|
||||
it->second == "resolution x"
|
||||
|| it->second == "resolution y"))
|
||||
{
|
||||
changeRes = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changeRes)
|
||||
{
|
||||
int x = Settings::Manager::getInt("resolution x", "Video");
|
||||
int y = Settings::Manager::getInt("resolution y", "Video");
|
||||
hud->onResChange(x, y);
|
||||
console->onResChange(x, y);
|
||||
mSettingsWindow->center();
|
||||
mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::pushGuiMode(GuiMode mode)
|
||||
{
|
||||
if (mode==GM_Inventory && allowed==GW_None)
|
||||
return;
|
||||
|
||||
mGuiModes.push_back(mode);
|
||||
|
||||
bool gameMode = !isGuiMode();
|
||||
MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode);
|
||||
|
||||
updateVisible();
|
||||
}
|
||||
|
||||
void WindowManager::popGuiMode()
|
||||
{
|
||||
if (!mGuiModes.empty())
|
||||
mGuiModes.pop_back();
|
||||
|
||||
bool gameMode = !isGuiMode();
|
||||
MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode);
|
||||
|
||||
updateVisible();
|
||||
}
|
||||
|
||||
void WindowManager::removeGuiMode(GuiMode mode)
|
||||
{
|
||||
std::vector<GuiMode>::iterator it = mGuiModes.begin();
|
||||
while (it != mGuiModes.end())
|
||||
{
|
||||
if (*it == mode)
|
||||
it = mGuiModes.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
updateVisible();
|
||||
}
|
||||
|
||||
void WindowManager::setSelectedSpell(const std::string& spellId, int successChancePercent)
|
||||
{
|
||||
hud->setSelectedSpell(spellId, successChancePercent);
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
|
||||
mSpellWindow->setTitle(spell->name);
|
||||
}
|
||||
|
||||
void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
|
||||
{
|
||||
hud->setSelectedEnchantItem(item, chargePercent);
|
||||
mSpellWindow->setTitle(MWWorld::Class::get(item).getName(item));
|
||||
}
|
||||
|
||||
void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
|
||||
{
|
||||
hud->setSelectedWeapon(item, durabilityPercent);
|
||||
mInventoryWindow->setTitle(MWWorld::Class::get(item).getName(item));
|
||||
}
|
||||
|
||||
void WindowManager::unsetSelectedSpell()
|
||||
{
|
||||
hud->unsetSelectedSpell();
|
||||
mSpellWindow->setTitle("#{sNone}");
|
||||
}
|
||||
|
||||
void WindowManager::unsetSelectedWeapon()
|
||||
{
|
||||
hud->unsetSelectedWeapon();
|
||||
mInventoryWindow->setTitle("#{sSkillHandtohand}");
|
||||
}
|
||||
|
||||
void WindowManager::getMousePosition(int &x, int &y)
|
||||
{
|
||||
const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition();
|
||||
x = pos.left;
|
||||
y = pos.top;
|
||||
}
|
||||
|
||||
void WindowManager::getMousePosition(float &x, float &y)
|
||||
{
|
||||
const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition();
|
||||
x = pos.left;
|
||||
y = pos.top;
|
||||
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
x /= viewSize.width;
|
||||
y /= viewSize.height;
|
||||
}
|
||||
|
||||
bool WindowManager::getWorldMouseOver()
|
||||
{
|
||||
return hud->getWorldMouseOver();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "MyGUI_UString.h"
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
#include <openengine/ogre/renderer.hpp>
|
||||
#include <openengine/gui/manager.hpp>
|
||||
|
||||
|
@ -77,6 +78,10 @@ namespace MWGui
|
|||
class MessageBoxManager;
|
||||
class CountDialog;
|
||||
class TradeWindow;
|
||||
class SettingsWindow;
|
||||
class ConfirmationDialog;
|
||||
class AlchemyWindow;
|
||||
class SpellWindow;
|
||||
|
||||
struct ClassPoint
|
||||
{
|
||||
|
@ -93,11 +98,9 @@ namespace MWGui
|
|||
typedef std::vector<Faction> FactionList;
|
||||
typedef std::vector<int> SkillList;
|
||||
|
||||
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath);
|
||||
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath);
|
||||
virtual ~WindowManager();
|
||||
|
||||
void setGuiMode(GuiMode newMode);
|
||||
|
||||
/**
|
||||
* Should be called each frame to update windows/gui elements.
|
||||
* This could mean updating sizes of gui elements or opening
|
||||
|
@ -105,19 +108,24 @@ namespace MWGui
|
|||
*/
|
||||
void update();
|
||||
|
||||
void setMode(GuiMode newMode)
|
||||
{
|
||||
if (newMode==GM_Inventory && allowed==GW_None)
|
||||
return;
|
||||
void pushGuiMode(GuiMode mode);
|
||||
void popGuiMode();
|
||||
void removeGuiMode(GuiMode mode); ///< can be anywhere in the stack
|
||||
|
||||
mode = newMode;
|
||||
GuiMode getMode() const
|
||||
{
|
||||
if (mGuiModes.empty())
|
||||
throw std::runtime_error ("getMode() called, but there is no active mode");
|
||||
return mGuiModes.back();
|
||||
}
|
||||
|
||||
bool isGuiMode() const { return !mGuiModes.empty(); }
|
||||
|
||||
void toggleVisible(GuiWindow wnd)
|
||||
{
|
||||
shown = (shown & wnd) ? (GuiWindow) (shown & ~wnd) : (GuiWindow) (shown | wnd);
|
||||
updateVisible();
|
||||
}
|
||||
void setNextMode(GuiMode newMode);
|
||||
|
||||
GuiMode getMode() const { return mode; }
|
||||
|
||||
bool isGuiMode() const { return getMode() != GM_Game; } // Everything that is not game mode is considered "gui mode"
|
||||
|
||||
// Disallow all inventory mode windows
|
||||
void disallowAll()
|
||||
|
@ -133,13 +141,21 @@ namespace MWGui
|
|||
updateVisible();
|
||||
}
|
||||
|
||||
bool isAllowed(GuiWindow wnd) const
|
||||
{
|
||||
return allowed & wnd;
|
||||
}
|
||||
|
||||
MWGui::DialogueWindow* getDialogueWindow() {return mDialogueWindow;}
|
||||
MWGui::ContainerWindow* getContainerWindow() {return mContainerWindow;}
|
||||
MWGui::InventoryWindow* getInventoryWindow() {return mInventoryWindow;}
|
||||
MWGui::BookWindow* getBookWindow() {return mBookWindow;}
|
||||
MWGui::ScrollWindow* getScrollWindow() {return mScrollWindow;}
|
||||
MWGui::CountDialog* getCountDialog() {return mCountDialog;}
|
||||
MWGui::ConfirmationDialog* getConfirmationDialog() {return mConfirmationDialog;}
|
||||
MWGui::TradeWindow* getTradeWindow() {return mTradeWindow;}
|
||||
MWGui::SpellWindow* getSpellWindow() {return mSpellWindow;}
|
||||
MWGui::Console* getConsole() {return console;}
|
||||
|
||||
MyGUI::Gui* getGui() const { return gui; }
|
||||
|
||||
|
@ -173,15 +189,15 @@ namespace MWGui
|
|||
void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y);
|
||||
|
||||
void setMouseVisible(bool visible);
|
||||
void getMousePosition(int &x, int &y);
|
||||
void getMousePosition(float &x, float &y);
|
||||
void setDragDrop(bool dragDrop);
|
||||
bool getWorldMouseOver();
|
||||
|
||||
void toggleFogOfWar();
|
||||
void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
|
||||
bool getFullHelp() const;
|
||||
|
||||
int toggleFps();
|
||||
///< toggle fps display @return resulting fps level
|
||||
|
||||
void setInteriorMapTexture(const int x, const int y);
|
||||
///< set the index of the map texture that should be used (for interiors)
|
||||
|
||||
|
@ -192,6 +208,12 @@ namespace MWGui
|
|||
void setWeaponVisibility(bool visible);
|
||||
void setSpellVisibility(bool visible);
|
||||
|
||||
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();
|
||||
|
||||
template<typename T>
|
||||
void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr.
|
||||
void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
|
||||
|
@ -201,6 +223,11 @@ namespace MWGui
|
|||
|
||||
void onFrame (float frameDuration);
|
||||
|
||||
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > getPlayerSkillValues() { return playerSkillValues; }
|
||||
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > getPlayerAttributeValues() { return playerAttributes; }
|
||||
SkillList getPlayerMinorSkills() { return playerMinorSkills; }
|
||||
SkillList getPlayerMajorSkills() { return playerMajorSkills; }
|
||||
|
||||
/**
|
||||
* Fetches a GMST string from the store, if there is no setting with the given
|
||||
* ID or it is not a string the default string is returned.
|
||||
|
@ -212,6 +239,8 @@ namespace MWGui
|
|||
|
||||
const ESMS::ESMStore& getStore() const;
|
||||
|
||||
void processChangedSettings(const Settings::CategorySettingVector& changed);
|
||||
|
||||
private:
|
||||
OEngine::GUI::MyGUIManager *mGuiManager;
|
||||
HUD *hud;
|
||||
|
@ -230,6 +259,10 @@ namespace MWGui
|
|||
BookWindow* mBookWindow;
|
||||
CountDialog* mCountDialog;
|
||||
TradeWindow* mTradeWindow;
|
||||
SettingsWindow* mSettingsWindow;
|
||||
ConfirmationDialog* mConfirmationDialog;
|
||||
AlchemyWindow* mAlchemyWindow;
|
||||
SpellWindow* mSpellWindow;
|
||||
|
||||
CharacterCreation* mCharGen;
|
||||
|
||||
|
@ -244,9 +277,7 @@ namespace MWGui
|
|||
|
||||
|
||||
MyGUI::Gui *gui; // Gui
|
||||
GuiMode mode; // Current gui mode
|
||||
GuiMode nextMode; // Next mode to activate in update()
|
||||
bool needModeChange; //Whether a mode change is needed in update() [will use nextMode]
|
||||
std::vector<GuiMode> mGuiModes;
|
||||
|
||||
std::vector<OEngine::GUI::Layout*> garbageDialogs;
|
||||
void cleanupGarbage();
|
||||
|
@ -257,9 +288,6 @@ namespace MWGui
|
|||
the start of the game, when windows are enabled one by one
|
||||
through script commands. You can manipulate this through using
|
||||
allow() and disableAll().
|
||||
|
||||
The setting should also affect visibility of certain HUD
|
||||
elements, but this is not done yet.
|
||||
*/
|
||||
GuiWindow allowed;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace MWGui
|
|||
public:
|
||||
WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager);
|
||||
void setVisible(bool b);
|
||||
bool pinned() { return mPinned; }
|
||||
|
||||
private:
|
||||
void onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName);
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace MWInput
|
|||
A_ToggleWeapon,
|
||||
A_ToggleSpell,
|
||||
|
||||
A_ToggleFps, // Toggle FPS display (this is temporary)
|
||||
A_Settings, // Temporary hotkey
|
||||
|
||||
A_LAST // Marker for the last item
|
||||
};
|
||||
|
@ -92,12 +92,12 @@ namespace MWInput
|
|||
|
||||
|
||||
/* InputImpl Methods */
|
||||
|
||||
void toggleFps()
|
||||
public:
|
||||
void adjustMouseRegion(int width, int height)
|
||||
{
|
||||
windows.toggleFps();
|
||||
input.adjustMouseClippingSize(width, height);
|
||||
}
|
||||
|
||||
private:
|
||||
void toggleSpell()
|
||||
{
|
||||
if (windows.isGuiMode()) return;
|
||||
|
@ -140,6 +140,15 @@ namespace MWInput
|
|||
windows.messageBox ("Screenshot saved", empty);
|
||||
}
|
||||
|
||||
void showSettings()
|
||||
{
|
||||
if (mDragDrop)
|
||||
return;
|
||||
|
||||
if (!windows.isGuiMode() || windows.getMode() != MWGui::GM_Settings)
|
||||
windows.pushGuiMode(MWGui::GM_Settings);
|
||||
}
|
||||
|
||||
/* toggleInventory() is called when the user presses the button to toggle the inventory screen. */
|
||||
void toggleInventory()
|
||||
{
|
||||
|
@ -148,13 +157,13 @@ namespace MWInput
|
|||
if (mDragDrop)
|
||||
return;
|
||||
|
||||
GuiMode mode = windows.getMode();
|
||||
bool gameMode = !windows.isGuiMode();
|
||||
|
||||
// Toggle between game mode and inventory mode
|
||||
if(mode == GM_Game)
|
||||
setGuiMode(GM_Inventory);
|
||||
else if(mode == GM_Inventory)
|
||||
setGuiMode(GM_Game);
|
||||
if(gameMode)
|
||||
windows.pushGuiMode(GM_Inventory);
|
||||
else if(windows.getMode() == GM_Inventory)
|
||||
windows.popGuiMode();
|
||||
|
||||
// .. but don't touch any other mode.
|
||||
}
|
||||
|
@ -167,27 +176,32 @@ namespace MWInput
|
|||
if (mDragDrop)
|
||||
return;
|
||||
|
||||
GuiMode mode = windows.getMode();
|
||||
bool gameMode = !windows.isGuiMode();
|
||||
|
||||
// Switch to console mode no matter what mode we are currently
|
||||
// in, except of course if we are already in console mode
|
||||
if(mode == GM_Console)
|
||||
setGuiMode(GM_Game);
|
||||
else setGuiMode(GM_Console);
|
||||
if (!gameMode)
|
||||
{
|
||||
if (windows.getMode() == GM_Console)
|
||||
windows.popGuiMode();
|
||||
else
|
||||
windows.pushGuiMode(GM_Console);
|
||||
}
|
||||
else
|
||||
windows.pushGuiMode(GM_Console);
|
||||
}
|
||||
|
||||
void toggleJournal()
|
||||
{
|
||||
using namespace MWGui;
|
||||
|
||||
GuiMode mode = windows.getMode();
|
||||
|
||||
// Toggle between game mode and journal mode
|
||||
if(mode == GM_Game)
|
||||
setGuiMode(GM_Journal);
|
||||
else if(mode == GM_Journal)
|
||||
setGuiMode(GM_Game);
|
||||
bool gameMode = !windows.isGuiMode();
|
||||
|
||||
if(gameMode)
|
||||
windows.pushGuiMode(GM_Journal);
|
||||
else if(windows.getMode() == GM_Journal)
|
||||
windows.popGuiMode();
|
||||
// .. but don't touch any other mode.
|
||||
}
|
||||
|
||||
|
@ -259,8 +273,8 @@ namespace MWInput
|
|||
"Draw Weapon");
|
||||
disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this),
|
||||
"Ready hands");
|
||||
disp->funcs.bind(A_ToggleFps, boost::bind(&InputImpl::toggleFps, this),
|
||||
"Toggle FPS display");
|
||||
disp->funcs.bind(A_Settings, boost::bind(&InputImpl::showSettings, this),
|
||||
"Show settings window");
|
||||
// Add the exit listener
|
||||
ogre.getRoot()->addFrameListener(&exit);
|
||||
|
||||
|
@ -282,8 +296,7 @@ namespace MWInput
|
|||
lst->add(guiEvents,Event::EV_ALL);
|
||||
}
|
||||
|
||||
// Start out in game mode
|
||||
setGuiMode(MWGui::GM_Game);
|
||||
changeInputMode(false);
|
||||
|
||||
/**********************************
|
||||
Key binding section
|
||||
|
@ -307,7 +320,7 @@ namespace MWInput
|
|||
disp->bind(A_ToggleWalk, KC_C);
|
||||
disp->bind(A_ToggleWeapon,KC_F);
|
||||
disp->bind(A_ToggleSpell,KC_R);
|
||||
disp->bind(A_ToggleFps, KC_F10);
|
||||
disp->bind(A_Settings, KC_F2);
|
||||
|
||||
// Key bindings for polled keys
|
||||
// NOTE: These keys are constantly being polled. Only add keys that must be checked each frame.
|
||||
|
@ -348,6 +361,7 @@ namespace MWInput
|
|||
windows.update();
|
||||
|
||||
// Disable movement in Gui mode
|
||||
|
||||
if (windows.isGuiMode()) return;
|
||||
|
||||
// Configure player movement according to keyboard input. Actual movement will
|
||||
|
@ -388,14 +402,10 @@ namespace MWInput
|
|||
|
||||
// Switch between gui modes. Besides controlling the Gui windows
|
||||
// this also makes sure input is directed to the right place
|
||||
void setGuiMode(MWGui::GuiMode mode)
|
||||
void changeInputMode(bool guiMode)
|
||||
{
|
||||
// Tell the GUI what to show (this also takes care of the mouse
|
||||
// pointer)
|
||||
windows.setMode(mode);
|
||||
|
||||
// Are we in GUI mode now?
|
||||
if(windows.isGuiMode())
|
||||
if(guiMode)
|
||||
{
|
||||
// Disable mouse look
|
||||
mouse->setCamera(NULL);
|
||||
|
@ -431,11 +441,6 @@ namespace MWInput
|
|||
delete impl;
|
||||
}
|
||||
|
||||
void MWInputManager::setGuiMode(MWGui::GuiMode mode)
|
||||
{
|
||||
impl->setGuiMode(mode);
|
||||
}
|
||||
|
||||
void MWInputManager::update()
|
||||
{
|
||||
impl->update();
|
||||
|
@ -445,4 +450,25 @@ namespace MWInput
|
|||
{
|
||||
impl->setDragDrop(dragDrop);
|
||||
}
|
||||
|
||||
void MWInputManager::changeInputMode(bool guiMode)
|
||||
{
|
||||
impl->changeInputMode(guiMode);
|
||||
}
|
||||
|
||||
void MWInputManager::processChangedSettings(const Settings::CategorySettingVector& changed)
|
||||
{
|
||||
bool changeRes = false;
|
||||
for (Settings::CategorySettingVector::const_iterator it = changed.begin();
|
||||
it != changed.end(); ++it)
|
||||
{
|
||||
if (it->first == "Video" && (
|
||||
it->second == "resolution x"
|
||||
|| it->second == "resolution y"))
|
||||
changeRes = true;
|
||||
}
|
||||
|
||||
if (changeRes)
|
||||
impl->adjustMouseRegion(Settings::Manager::getInt("resolution x", "Video"), Settings::Manager::getInt("resolution y", "Video"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "../mwgui/mode.hpp"
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
namespace OEngine
|
||||
{
|
||||
namespace Render
|
||||
|
@ -50,9 +52,11 @@ namespace MWInput
|
|||
|
||||
void update();
|
||||
|
||||
void setDragDrop(bool dragDrop);
|
||||
void changeInputMode(bool guiMode);
|
||||
|
||||
void setGuiMode(MWGui::GuiMode mode);
|
||||
void processChangedSettings(const Settings::CategorySettingVector& changed);
|
||||
|
||||
void setDragDrop(bool dragDrop);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -71,7 +71,10 @@ namespace MWMechanics
|
|||
|
||||
void Actors::removeActor (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
mActors.erase (ptr);
|
||||
std::set<MWWorld::Ptr>::iterator iter = mActors.find (ptr);
|
||||
|
||||
if (iter!=mActors.end())
|
||||
mActors.erase (iter);
|
||||
}
|
||||
|
||||
void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace MWMechanics
|
|||
|
||||
void removeActor (const MWWorld::Ptr& ptr);
|
||||
///< Deregister an actor for stats management
|
||||
///
|
||||
/// \note Ignored, if \a ptr is not a registered actor.
|
||||
|
||||
void dropActors (const MWWorld::Ptr::CellStore *cellStore);
|
||||
///< Deregister all actors in the given cell.
|
||||
|
|
|
@ -30,6 +30,15 @@ namespace MWMechanics
|
|||
for (int i=0; i<27; ++i)
|
||||
npcStats.mSkill[i].setBase (player->npdt52.skills[i]);
|
||||
|
||||
creatureStats.mAttributes[0].setBase (player->npdt52.strength);
|
||||
creatureStats.mAttributes[1].setBase (player->npdt52.intelligence);
|
||||
creatureStats.mAttributes[2].setBase (player->npdt52.willpower);
|
||||
creatureStats.mAttributes[3].setBase (player->npdt52.agility);
|
||||
creatureStats.mAttributes[4].setBase (player->npdt52.speed);
|
||||
creatureStats.mAttributes[5].setBase (player->npdt52.endurance);
|
||||
creatureStats.mAttributes[6].setBase (player->npdt52.personality);
|
||||
creatureStats.mAttributes[7].setBase (player->npdt52.luck);
|
||||
|
||||
// race
|
||||
if (mRaceSelected)
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace MWMechanics
|
|||
|
||||
void Spells::add (const std::string& spellId)
|
||||
{
|
||||
if (std::find (mSpells.begin(), mSpells.end(), spellId)!=mSpells.end())
|
||||
if (std::find (mSpells.begin(), mSpells.end(), spellId)==mSpells.end())
|
||||
mSpells.push_back (spellId);
|
||||
}
|
||||
|
||||
|
|
99
apps/openmw/mwmechanics/spellsuccess.hpp
Normal file
99
apps/openmw/mwmechanics/spellsuccess.hpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
#ifndef MWMECHANICS_SPELLSUCCESS_H
|
||||
#define MWMECHANICS_SPELLSUCCESS_H
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
||||
#include "npcstats.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
inline int spellSchoolToSkill(int school)
|
||||
{
|
||||
std::map<int, int> schoolSkillMap; // maps spell school to skill id
|
||||
schoolSkillMap[0] = 11; // alteration
|
||||
schoolSkillMap[1] = 13; // conjuration
|
||||
schoolSkillMap[3] = 12; // illusion
|
||||
schoolSkillMap[2] = 10; // destruction
|
||||
schoolSkillMap[4] = 14; // mysticism
|
||||
schoolSkillMap[5] = 15; // restoration
|
||||
assert(schoolSkillMap.find(school) != schoolSkillMap.end());
|
||||
return schoolSkillMap[school];
|
||||
}
|
||||
|
||||
inline int getSpellSchool(const std::string& spellId, const MWWorld::Ptr& actor)
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
|
||||
NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor);
|
||||
|
||||
// determine the spell's school
|
||||
// this is always the school where the player's respective skill is the least advanced
|
||||
// out of all the magic effects' schools
|
||||
const std::vector<ESM::ENAMstruct>& effects = spell->effects.list;
|
||||
int school = -1;
|
||||
int skillLevel = -1;
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator it = effects.begin();
|
||||
it != effects.end(); ++it)
|
||||
{
|
||||
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(it->effectID);
|
||||
int _school = effect->data.school;
|
||||
int _skillLevel = stats.mSkill[spellSchoolToSkill(_school)].getModified();
|
||||
|
||||
if (school == -1)
|
||||
{
|
||||
school = _school;
|
||||
skillLevel = _skillLevel;
|
||||
}
|
||||
else if (_skillLevel < skillLevel)
|
||||
{
|
||||
school = _school;
|
||||
skillLevel = _skillLevel;
|
||||
}
|
||||
}
|
||||
|
||||
return school;
|
||||
}
|
||||
|
||||
|
||||
// UESP wiki / Morrowind/Spells:
|
||||
// Chance of success is (Spell's skill * 2 + Willpower / 5 + Luck / 10 - Spell cost - Sound magnitude) * (Current fatigue + Maximum Fatigue * 1.5) / Maximum fatigue * 2
|
||||
/**
|
||||
* @param spellId ID of spell
|
||||
* @param actor calculate spell success chance for this actor (depends on actor's skills)
|
||||
* @attention actor has to be an NPC and not a creature!
|
||||
* @return success chance from 0 to 100 (in percent)
|
||||
*/
|
||||
inline float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor)
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
|
||||
|
||||
if (spell->data.flags & ESM::Spell::F_Always // spells with this flag always succeed (usually birthsign spells)
|
||||
|| spell->data.type == ESM::Spell::ST_Power) // powers always succeed, but can be cast only once per day
|
||||
return 100.0;
|
||||
|
||||
NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor);
|
||||
CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor);
|
||||
|
||||
int skillLevel = stats.mSkill[getSpellSchool(spellId, actor)].getModified();
|
||||
|
||||
// Sound magic effect (reduces spell casting chance)
|
||||
int soundMagnitude = creatureStats.mMagicEffects.get (MWMechanics::EffectKey (48)).mMagnitude;
|
||||
|
||||
int willpower = creatureStats.mAttributes[ESM::Attribute::Willpower].getModified();
|
||||
int luck = creatureStats.mAttributes[ESM::Attribute::Luck].getModified();
|
||||
int currentFatigue = creatureStats.mDynamic[2].getCurrent();
|
||||
int maxFatigue = creatureStats.mDynamic[2].getModified();
|
||||
int spellCost = spell->data.cost;
|
||||
|
||||
// There we go, all needed variables are there, lets go
|
||||
float chance = (float(skillLevel * 2) + float(willpower)/5.0 + float(luck)/ 10.0 - spellCost - soundMagnitude) * (float(currentFatigue + maxFatigue * 1.5)) / float(maxFatigue * 2.0);
|
||||
|
||||
chance = std::max(0.0f, std::min(100.0f, chance)); // clamp to 0 .. 100
|
||||
|
||||
return chance;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -26,6 +26,21 @@ void Compositors::setEnabled (const bool enabled)
|
|||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
void Compositors::recreate()
|
||||
{
|
||||
Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport);
|
||||
|
||||
CompositorMap temp = mCompositors;
|
||||
mCompositors.clear();
|
||||
|
||||
for (CompositorMap::iterator it=temp.begin();
|
||||
it != temp.end(); ++it)
|
||||
{
|
||||
addCompositor(it->first, it->second.second);
|
||||
setCompositorEnabled(it->first, mEnabled && it->second.first);
|
||||
}
|
||||
}
|
||||
|
||||
void Compositors::addCompositor (const std::string& name, const int priority)
|
||||
{
|
||||
int id = 0;
|
||||
|
@ -47,3 +62,10 @@ void Compositors::setCompositorEnabled (const std::string& name, const bool enab
|
|||
mCompositors[name].first = enabled;
|
||||
Ogre::CompositorManager::getSingleton().setCompositorEnabled (mViewport, name, enabled && mEnabled);
|
||||
}
|
||||
|
||||
void Compositors::removeAll()
|
||||
{
|
||||
Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport);
|
||||
|
||||
mCompositors.clear();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@ namespace MWRender
|
|||
*/
|
||||
void setEnabled (const bool enabled);
|
||||
|
||||
void setViewport(Ogre::Viewport* vp) { mViewport = vp; }
|
||||
|
||||
/// recreate compositors (call this after viewport size changes)
|
||||
void recreate();
|
||||
|
||||
bool toggle() { setEnabled(!mEnabled); return mEnabled; }
|
||||
|
||||
/**
|
||||
|
@ -39,6 +44,8 @@ namespace MWRender
|
|||
*/
|
||||
void addCompositor (const std::string& name, const int priority);
|
||||
|
||||
void removeAll ();
|
||||
|
||||
protected:
|
||||
/// maps compositor name to its "enabled" state
|
||||
CompositorMap mCompositors;
|
||||
|
|
|
@ -68,7 +68,7 @@ ManualObject *Debugging::createPathgridLines(const ESM::Pathgrid *pathgrid)
|
|||
result->begin(PATHGRID_LINE_MATERIAL, RenderOperation::OT_LINE_LIST);
|
||||
for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid->edges.begin();
|
||||
it != pathgrid->edges.end();
|
||||
it++)
|
||||
++it)
|
||||
{
|
||||
const ESM::Pathgrid::Edge &edge = *it;
|
||||
const ESM::Pathgrid::Point &p1 = pathgrid->points[edge.v0], &p2 = pathgrid->points[edge.v1];
|
||||
|
@ -197,7 +197,7 @@ void Debugging::togglePathgrid()
|
|||
|
||||
// add path grid meshes to already loaded cells
|
||||
mPathGridRoot = mMwRoot->createChildSceneNode();
|
||||
for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++)
|
||||
for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); ++it)
|
||||
{
|
||||
enableCellPathgrid(*it);
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ void Debugging::togglePathgrid()
|
|||
else
|
||||
{
|
||||
// remove path grid meshes from already loaded cells
|
||||
for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++)
|
||||
for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); ++it)
|
||||
{
|
||||
disableCellPathgrid(*it);
|
||||
}
|
||||
|
|
|
@ -307,28 +307,53 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
|
|||
|
||||
// convert from world coordinates to texture UV coordinates
|
||||
float u,v;
|
||||
std::string texName;
|
||||
std::string texBaseName;
|
||||
if (!mInterior)
|
||||
{
|
||||
u = std::abs((pos.x - (sSize*x))/sSize);
|
||||
v = 1-std::abs((pos.y + (sSize*y))/sSize);
|
||||
texName = "Cell_"+coordStr(x,y);
|
||||
texBaseName = "Cell_";
|
||||
}
|
||||
else
|
||||
{
|
||||
u = (pos.x - min.x - sSize*x)/sSize;
|
||||
v = (pos.y - min.y - sSize*y)/sSize;
|
||||
|
||||
texName = mInteriorName + "_" + coordStr(x,y);
|
||||
texBaseName = mInteriorName + "_";
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v);
|
||||
MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, -playerdirection.z);
|
||||
|
||||
// explore radius (squared)
|
||||
const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution;
|
||||
const float sqrExploreRadius = (mInterior ? 0.01 : 0.09) * sFogOfWarResolution*sFogOfWarResolution;
|
||||
const float exploreRadius = (mInterior ? 0.1 : 0.3) * sFogOfWarResolution; // explore radius from 0 to sFogOfWarResolution
|
||||
const float exploreRadiusUV = exploreRadius / sFogOfWarResolution; // explore radius from 0 to 1 (UV space)
|
||||
|
||||
int intExtMult = mInterior ? 1 : -1; // interior and exterior have reversed Y coordinates (interior: top to bottom)
|
||||
|
||||
// change the affected fog of war textures (in a 3x3 grid around the player)
|
||||
for (int mx = -1; mx<2; ++mx)
|
||||
{
|
||||
for (int my = -1; my<2; ++my)
|
||||
{
|
||||
|
||||
// is this texture affected at all?
|
||||
bool affected = false;
|
||||
if (mx == 0 && my == 0) // the player is always in the center of the 3x3 grid
|
||||
affected = true;
|
||||
else
|
||||
{
|
||||
bool affectsX = (mx > 0)? (u + exploreRadiusUV > 1) : (u - exploreRadiusUV < 0);
|
||||
bool affectsY = (my > 0)? (v + exploreRadiusUV > 1) : (v - exploreRadiusUV < 0);
|
||||
affected = (affectsX && (my == 0)) || (affectsY && mx == 0) || (affectsX && affectsY);
|
||||
}
|
||||
|
||||
if (!affected)
|
||||
continue;
|
||||
|
||||
std::string texName = texBaseName + coordStr(x+mx,y+my*intExtMult);
|
||||
|
||||
// get the appropriate fog of war texture
|
||||
TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog");
|
||||
if (!tex.isNull())
|
||||
{
|
||||
|
@ -339,7 +364,11 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
|
|||
{
|
||||
for (int texU = 0; texU<sFogOfWarResolution; ++texU)
|
||||
{
|
||||
float sqrDist = Math::Sqr(texU - u*sFogOfWarResolution) + Math::Sqr(texV - v*sFogOfWarResolution);
|
||||
// fix into range of 0 ... sFogOfWarResolution
|
||||
int _texU = texU * (float(sFogOfWarResolution+1) / float(sFogOfWarResolution));
|
||||
int _texV = texV * (float(sFogOfWarResolution+1) / float(sFogOfWarResolution));
|
||||
|
||||
float sqrDist = Math::Sqr((_texU + mx*sFogOfWarResolution) - u*sFogOfWarResolution) + Math::Sqr((_texV + my*sFogOfWarResolution) - v*sFogOfWarResolution);
|
||||
uint32 clr = mBuffers[texName][i];
|
||||
uint8 alpha = (clr >> 24);
|
||||
alpha = std::min( alpha, (uint8) (std::max(0.f, std::min(1.f, (sqrDist/sqrExploreRadius)))*255) );
|
||||
|
@ -354,3 +383,5 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
|
|||
tex->getBuffer()->unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -528,7 +528,7 @@ void NpcAnimation::insertFootPart(int type, const std::string &mesh){
|
|||
|
||||
|
||||
}
|
||||
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix){
|
||||
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> NpcAnimation::insertFreePart(const std::string &mesh, const std::string& suffix){
|
||||
|
||||
std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix;
|
||||
NIFLoader::load(meshNumbered);
|
||||
|
|
|
@ -84,7 +84,7 @@ private:
|
|||
NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv);
|
||||
virtual ~NpcAnimation();
|
||||
Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename);
|
||||
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> insertFreePart(const std::string &mesh, const std::string suffix);
|
||||
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> insertFreePart(const std::string &mesh, const std::string& suffix);
|
||||
void insertFootPart(int type, const std::string &mesh);
|
||||
virtual void runAnimation(float timepassed);
|
||||
void updateParts();
|
||||
|
|
|
@ -39,7 +39,8 @@ struct LightInfo
|
|||
|
||||
LightInfo() :
|
||||
flickerVariation(0), resetTime(0.5),
|
||||
flickerSlowVariation(0), time(0), interior(true)
|
||||
flickerSlowVariation(0), time(0), interior(true),
|
||||
type(LT_Normal), radius(1.0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -68,7 +69,7 @@ class Objects{
|
|||
///< Remove all movable objects from \a node.
|
||||
|
||||
public:
|
||||
Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer) {}
|
||||
Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer), mIsStatic(false) {}
|
||||
~Objects(){}
|
||||
void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
|
||||
void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);
|
||||
|
|
|
@ -6,4 +6,22 @@ namespace MWRender
|
|||
Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node)
|
||||
: mCamera (camera), mNode (node)
|
||||
{}
|
||||
|
||||
void Player::setRot(float x, float y, float z)
|
||||
{
|
||||
Ogre::SceneNode *sceneNode = mNode;
|
||||
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
|
||||
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
|
||||
|
||||
// we are only interested in X and Y rotation
|
||||
|
||||
// Rotate around X axis
|
||||
Ogre::Quaternion xr(Ogre::Radian(x), Ogre::Vector3::UNIT_X);
|
||||
|
||||
// Rotate around Y axis
|
||||
Ogre::Quaternion yr(Ogre::Radian(-z), Ogre::Vector3::UNIT_Y);
|
||||
|
||||
pitchNode->setOrientation(xr);
|
||||
yawNode->setOrientation(yr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ namespace MWRender
|
|||
|
||||
Ogre::Camera *getCamera() { return mCamera; }
|
||||
|
||||
/// Set where the player is looking at. Uses Morrowind (euler) angles
|
||||
void setRot(float x, float y, float z);
|
||||
|
||||
std::string getHandle() const { return mNode->getName(); }
|
||||
Ogre::SceneNode* getNode() {return mNode;}
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include <components/esm/loadstat.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
@ -21,6 +22,9 @@
|
|||
#include "water.hpp"
|
||||
#include "compositors.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp" // FIXME
|
||||
#include "../mwinput/inputmanager.hpp" // FIXME
|
||||
|
||||
using namespace MWRender;
|
||||
using namespace Ogre;
|
||||
|
||||
|
@ -30,6 +34,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
|||
:mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0)
|
||||
{
|
||||
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
|
||||
mRendering.setWindowEventListener(this);
|
||||
|
||||
mCompositors = new Compositors(mRendering.getViewport());
|
||||
|
||||
|
@ -62,25 +67,13 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
|||
|
||||
// disable unsupported effects
|
||||
const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
|
||||
if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects"))
|
||||
if (!waterShaderSupported())
|
||||
Settings::Manager::setBool("shader", "Water", false);
|
||||
if ( !(caps->isShaderProfileSupported("fp40") || caps->isShaderProfileSupported("ps_4_0"))
|
||||
|| !Settings::Manager::getBool("shaders", "Objects"))
|
||||
Settings::Manager::setBool("enabled", "Shadows", false);
|
||||
|
||||
// note that the order is important here
|
||||
if (useMRT())
|
||||
{
|
||||
mCompositors->addCompositor("gbuffer", 0);
|
||||
mCompositors->setCompositorEnabled("gbuffer", true);
|
||||
mCompositors->addCompositor("Underwater", 1);
|
||||
mCompositors->addCompositor("gbufferFinalizer", 2);
|
||||
mCompositors->setCompositorEnabled("gbufferFinalizer", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCompositors->addCompositor("UnderwaterNoMRT", 0);
|
||||
}
|
||||
applyCompositors();
|
||||
|
||||
// Turn the entire scene (represented by the 'root' node) -90
|
||||
// degrees around the x axis. This makes Z go upwards, and Y go into
|
||||
|
@ -104,7 +97,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
|||
|
||||
mTerrainManager = new TerrainManager(mRendering.getScene(), this);
|
||||
|
||||
//mSkyManager = 0;
|
||||
mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera());
|
||||
|
||||
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
|
||||
|
@ -114,17 +106,24 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
|||
|
||||
mDebugging = new Debugging(mMwRoot, engine);
|
||||
mLocalMap = new MWRender::LocalMap(&mRendering, this);
|
||||
|
||||
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
|
||||
}
|
||||
|
||||
RenderingManager::~RenderingManager ()
|
||||
{
|
||||
mRendering.removeWindowEventListener(this);
|
||||
|
||||
delete mPlayer;
|
||||
delete mSkyManager;
|
||||
delete mDebugging;
|
||||
delete mShaderHelper;
|
||||
delete mShadows;
|
||||
delete mTerrainManager;
|
||||
delete mLocalMap;
|
||||
delete mOcclusionQuery;
|
||||
delete mCompositors;
|
||||
delete mWater;
|
||||
}
|
||||
|
||||
MWRender::SkyManager* RenderingManager::getSkyManager()
|
||||
|
@ -563,4 +562,119 @@ Compositors* RenderingManager::getCompositors()
|
|||
return mCompositors;
|
||||
}
|
||||
|
||||
void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings)
|
||||
{
|
||||
bool changeRes = false;
|
||||
for (Settings::CategorySettingVector::const_iterator it=settings.begin();
|
||||
it != settings.end(); ++it)
|
||||
{
|
||||
if (it->second == "menu transparency" && it->first == "GUI")
|
||||
{
|
||||
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
|
||||
}
|
||||
else if (it->second == "max viewing distance" && it->first == "Viewing distance")
|
||||
{
|
||||
if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior())
|
||||
configureFog(*MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell());
|
||||
}
|
||||
else if (it->first == "Video" && (
|
||||
it->second == "resolution x"
|
||||
|| it->second == "resolution y"
|
||||
|| it->second == "fullscreen"))
|
||||
changeRes = true;
|
||||
else if (it->second == "field of view" && it->first == "General")
|
||||
mRendering.setFov(Settings::Manager::getFloat("field of view", "General"));
|
||||
else if ((it->second == "texture filtering" && it->first == "General")
|
||||
|| (it->second == "anisotropy" && it->first == "General"))
|
||||
{
|
||||
TextureFilterOptions tfo;
|
||||
std::string filter = Settings::Manager::getString("texture filtering", "General");
|
||||
if (filter == "anisotropic") tfo = TFO_ANISOTROPIC;
|
||||
else if (filter == "trilinear") tfo = TFO_TRILINEAR;
|
||||
else if (filter == "bilinear") tfo = TFO_BILINEAR;
|
||||
else if (filter == "none") tfo = TFO_NONE;
|
||||
|
||||
MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
|
||||
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
|
||||
}
|
||||
else if (it->second == "shader" && it->first == "Water")
|
||||
{
|
||||
applyCompositors();
|
||||
mShaderHelper->applyShaders();
|
||||
}
|
||||
}
|
||||
|
||||
if (changeRes)
|
||||
{
|
||||
unsigned int x = Settings::Manager::getInt("resolution x", "Video");
|
||||
unsigned int y = Settings::Manager::getInt("resolution y", "Video");
|
||||
|
||||
if (x != mRendering.getWindow()->getWidth() || y != mRendering.getWindow()->getHeight())
|
||||
{
|
||||
mRendering.getWindow()->resize(x, y);
|
||||
}
|
||||
mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y);
|
||||
}
|
||||
|
||||
if (mWater)
|
||||
mWater->processChangedSettings(settings);
|
||||
}
|
||||
|
||||
void RenderingManager::setMenuTransparency(float val)
|
||||
{
|
||||
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().getByName("transparent.png");
|
||||
std::vector<Ogre::uint32> buffer;
|
||||
buffer.resize(1);
|
||||
buffer[0] = (int(255*val) << 24);
|
||||
memcpy(tex->getBuffer()->lock(Ogre::HardwareBuffer::HBL_DISCARD), &buffer[0], 1*4);
|
||||
tex->getBuffer()->unlock();
|
||||
}
|
||||
|
||||
void RenderingManager::windowResized(Ogre::RenderWindow* rw)
|
||||
{
|
||||
Settings::Manager::setInt("resolution x", "Video", rw->getWidth());
|
||||
Settings::Manager::setInt("resolution y", "Video", rw->getHeight());
|
||||
|
||||
|
||||
mRendering.adjustViewport();
|
||||
mCompositors->recreate();
|
||||
mWater->assignTextures();
|
||||
|
||||
const Settings::CategorySettingVector& changed = Settings::Manager::apply();
|
||||
MWBase::Environment::get().getInputManager()->processChangedSettings(changed); //FIXME
|
||||
MWBase::Environment::get().getWindowManager()->processChangedSettings(changed); // FIXME
|
||||
}
|
||||
|
||||
void RenderingManager::windowClosed(Ogre::RenderWindow* rw)
|
||||
{
|
||||
}
|
||||
|
||||
bool RenderingManager::waterShaderSupported()
|
||||
{
|
||||
const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
|
||||
if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderingManager::applyCompositors()
|
||||
{
|
||||
mCompositors->removeAll();
|
||||
if (useMRT())
|
||||
{
|
||||
mCompositors->addCompositor("gbuffer", 0);
|
||||
mCompositors->setCompositorEnabled("gbuffer", true);
|
||||
mCompositors->addCompositor("Underwater", 1);
|
||||
mCompositors->addCompositor("gbufferFinalizer", 2);
|
||||
mCompositors->setCompositorEnabled("gbufferFinalizer", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCompositors->addCompositor("UnderwaterNoMRT", 0);
|
||||
}
|
||||
|
||||
if (mWater)
|
||||
mWater->assignTextures();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -8,11 +8,15 @@
|
|||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include <OgreWindowEventUtilities.h>
|
||||
|
||||
#include <utility>
|
||||
#include <openengine/ogre/renderer.hpp>
|
||||
#include <openengine/ogre/fader.hpp>
|
||||
#include <openengine/bullet/physic.hpp>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
@ -49,7 +53,7 @@ namespace MWRender
|
|||
class Water;
|
||||
class Compositors;
|
||||
|
||||
class RenderingManager: private RenderingInterface {
|
||||
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener {
|
||||
|
||||
private:
|
||||
|
||||
|
@ -157,10 +161,24 @@ class RenderingManager: private RenderingInterface {
|
|||
///< transform the specified bounding box (in world coordinates) into screen coordinates.
|
||||
/// @return packed vector4 (min_x, min_y, max_x, max_y)
|
||||
|
||||
void processChangedSettings(const Settings::CategorySettingVector& settings);
|
||||
|
||||
Ogre::Viewport* getViewport() { return mRendering.getViewport(); }
|
||||
|
||||
static bool waterShaderSupported();
|
||||
|
||||
protected:
|
||||
virtual void windowResized(Ogre::RenderWindow* rw);
|
||||
virtual void windowClosed(Ogre::RenderWindow* rw);
|
||||
|
||||
private:
|
||||
|
||||
void setAmbientMode();
|
||||
|
||||
void setMenuTransparency(float val);
|
||||
|
||||
void applyCompositors();
|
||||
|
||||
bool mSunEnabled;
|
||||
|
||||
SkyManager* mSkyManager;
|
||||
|
|
|
@ -374,7 +374,7 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
|
|||
, mSunGlare(NULL)
|
||||
, mMasser(NULL)
|
||||
, mSecunda(NULL)
|
||||
, mViewport(NULL)
|
||||
, mCamera(pCamera)
|
||||
, mRootNode(NULL)
|
||||
, mSceneMgr(NULL)
|
||||
, mAtmosphereDay(NULL)
|
||||
|
@ -399,9 +399,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
|
|||
, mSecundaEnabled(true)
|
||||
, mCreated(false)
|
||||
{
|
||||
mViewport = pCamera->getViewport();
|
||||
mSceneMgr = pMwRoot->getCreator();
|
||||
mRootNode = pCamera->getParentSceneNode()->createChildSceneNode();
|
||||
mRootNode = mCamera->getParentSceneNode()->createChildSceneNode();
|
||||
mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates
|
||||
mRootNode->setInheritOrientation(false);
|
||||
}
|
||||
|
@ -741,7 +740,7 @@ void SkyManager::update(float duration)
|
|||
// on how directly the player is looking at the sun
|
||||
Vector3 sun = mSunGlare->getPosition();
|
||||
sun = Vector3(sun.x, sun.z, -sun.y);
|
||||
Vector3 cam = mViewport->getCamera()->getRealDirection();
|
||||
Vector3 cam = mCamera->getRealDirection();
|
||||
const Degree angle = sun.angleBetween( cam );
|
||||
float val = 1- (angle.valueDegrees() / 180.f);
|
||||
val = (val*val*val*val)*2;
|
||||
|
|
|
@ -185,7 +185,7 @@ namespace MWRender
|
|||
Moon* mMasser;
|
||||
Moon* mSecunda;
|
||||
|
||||
Ogre::Viewport* mViewport;
|
||||
Ogre::Camera* mCamera;
|
||||
Ogre::SceneNode* mRootNode;
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
|
||||
|
|
|
@ -22,30 +22,30 @@ namespace MWRender
|
|||
TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) :
|
||||
mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend)
|
||||
{
|
||||
|
||||
mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
|
||||
TerrainMaterialGeneratorPtr matGen;
|
||||
TerrainMaterialGeneratorB* matGenP = new TerrainMaterialGeneratorB();
|
||||
matGen.bind(matGenP);
|
||||
mTerrainGlobals.setDefaultMaterialGenerator(matGen);
|
||||
mTerrainGlobals->setDefaultMaterialGenerator(matGen);
|
||||
|
||||
TerrainMaterialGenerator::Profile* const activeProfile =
|
||||
mTerrainGlobals.getDefaultMaterialGenerator()
|
||||
mTerrainGlobals->getDefaultMaterialGenerator()
|
||||
->getActiveProfile();
|
||||
mActiveProfile = static_cast<TerrainMaterialGeneratorB::SM2Profile*>(activeProfile);
|
||||
|
||||
//The pixel error should be as high as possible without it being noticed
|
||||
//as it governs how fast mesh quality decreases.
|
||||
mTerrainGlobals.setMaxPixelError(8);
|
||||
mTerrainGlobals->setMaxPixelError(8);
|
||||
|
||||
mTerrainGlobals.setLayerBlendMapSize(32);
|
||||
mTerrainGlobals.setDefaultGlobalColourMapSize(65);
|
||||
mTerrainGlobals->setLayerBlendMapSize(32);
|
||||
mTerrainGlobals->setDefaultGlobalColourMapSize(65);
|
||||
|
||||
//10 (default) didn't seem to be quite enough
|
||||
mTerrainGlobals.setSkirtSize(128);
|
||||
mTerrainGlobals->setSkirtSize(128);
|
||||
|
||||
//due to the sudden flick between composite and non composite textures,
|
||||
//this seemed the distance where it wasn't too noticeable
|
||||
mTerrainGlobals.setCompositeMapDistance(mWorldSize*2);
|
||||
mTerrainGlobals->setCompositeMapDistance(mWorldSize*2);
|
||||
|
||||
mActiveProfile->setLightmapEnabled(false);
|
||||
mActiveProfile->setLayerSpecularMappingEnabled(false);
|
||||
|
@ -86,20 +86,21 @@ namespace MWRender
|
|||
|
||||
TerrainManager::~TerrainManager()
|
||||
{
|
||||
OGRE_DELETE mTerrainGlobals;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
void TerrainManager::setDiffuse(const ColourValue& diffuse)
|
||||
{
|
||||
mTerrainGlobals.setCompositeMapDiffuse(diffuse);
|
||||
mTerrainGlobals->setCompositeMapDiffuse(diffuse);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
void TerrainManager::setAmbient(const ColourValue& ambient)
|
||||
{
|
||||
mTerrainGlobals.setCompositeMapAmbient(ambient);
|
||||
mTerrainGlobals->setCompositeMapAmbient(ambient);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace MWRender{
|
|||
void cellAdded(MWWorld::Ptr::CellStore* store);
|
||||
void cellRemoved(MWWorld::Ptr::CellStore* store);
|
||||
private:
|
||||
Ogre::TerrainGlobalOptions mTerrainGlobals;
|
||||
Ogre::TerrainGlobalOptions* mTerrainGlobals;
|
||||
Ogre::TerrainGroup mTerrainGroup;
|
||||
|
||||
RenderingManager* mRendering;
|
||||
|
|
|
@ -167,7 +167,7 @@ namespace Ogre
|
|||
class ShaderHelper : public TerrainAlloc
|
||||
{
|
||||
public:
|
||||
ShaderHelper() {}
|
||||
ShaderHelper() : mShadowSamplerStartHi(0), mShadowSamplerStartLo(0) {}
|
||||
virtual ~ShaderHelper() {}
|
||||
virtual HighLevelGpuProgramPtr generateVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
||||
virtual HighLevelGpuProgramPtr generateFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "water.hpp"
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "sky.hpp"
|
||||
#include "renderingmanager.hpp"
|
||||
#include "compositors.hpp"
|
||||
|
@ -10,7 +10,7 @@ namespace MWRender
|
|||
{
|
||||
|
||||
Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) :
|
||||
mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()),
|
||||
mCamera (camera), mSceneManager (camera->getSceneManager()),
|
||||
mIsUnderwater(false), mVisibilityFlags(0),
|
||||
mReflectionTarget(0), mActive(1), mToggled(1),
|
||||
mReflectionRenderActive(false), mRendering(rend)
|
||||
|
@ -30,13 +30,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
|
|||
mWater->setRenderQueueGroup(RQG_Water);
|
||||
mWater->setCastShadows(false);
|
||||
|
||||
mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water")
|
||||
+ RV_Statics * Settings::Manager::getBool("reflect statics", "Water")
|
||||
+ RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water")
|
||||
+ RV_Actors * Settings::Manager::getBool("reflect actors", "Water")
|
||||
+ RV_Misc * Settings::Manager::getBool("reflect misc", "Water")
|
||||
+ RV_Sky;
|
||||
|
||||
mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
|
||||
mWaterNode->setPosition(0, mTop, 0);
|
||||
|
||||
|
@ -48,30 +41,9 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
|
|||
}
|
||||
mWaterNode->attachObject(mWater);
|
||||
|
||||
// Create rendertarget for reflection
|
||||
int rttsize = Settings::Manager::getInt("rtt size", "Water");
|
||||
applyRTT();
|
||||
applyVisibilityMask();
|
||||
|
||||
TexturePtr tex;
|
||||
if (Settings::Manager::getBool("shader", "Water"))
|
||||
{
|
||||
tex = TextureManager::getSingleton().createManual("WaterReflection",
|
||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_FLOAT16_RGBA, TU_RENDERTARGET);
|
||||
|
||||
RenderTarget* rtt = tex->getBuffer()->getRenderTarget();
|
||||
Viewport* vp = rtt->addViewport(mReflectionCamera);
|
||||
vp->setOverlaysEnabled(false);
|
||||
vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f));
|
||||
vp->setShadowsEnabled(false);
|
||||
vp->setVisibilityMask( mVisibilityFlags );
|
||||
// use fallback techniques without shadows and without mrt (currently not implemented for sky and terrain)
|
||||
//vp->setMaterialScheme("Fallback");
|
||||
rtt->addListener(this);
|
||||
rtt->setActive(true);
|
||||
|
||||
mReflectionTarget = rtt;
|
||||
}
|
||||
|
||||
mCompositorName = RenderingManager::useMRT() ? "Underwater" : "UnderwaterNoMRT";
|
||||
|
||||
createMaterial();
|
||||
mWater->setMaterial(mMaterial);
|
||||
|
@ -80,6 +52,8 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
|
|||
|
||||
mSceneManager->addRenderQueueListener(this);
|
||||
|
||||
assignTextures();
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// ---------------------------------- reflection debug overlay ----------------------------------
|
||||
|
@ -140,6 +114,9 @@ Water::~Water()
|
|||
{
|
||||
MeshManager::getSingleton().remove("water");
|
||||
|
||||
if (mReflectionTarget)
|
||||
mReflectionTexture->getBuffer()->getRenderTarget()->removeListener(this);
|
||||
|
||||
mWaterNode->detachObject(mWater);
|
||||
mSceneManager->destroyEntity(mWater);
|
||||
mSceneManager->destroySceneNode(mWaterNode);
|
||||
|
@ -248,8 +225,16 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt)
|
|||
}
|
||||
|
||||
void Water::createMaterial()
|
||||
{
|
||||
if (mReflectionTarget == 0)
|
||||
{
|
||||
mMaterial = MaterialManager::getSingleton().getByName("Water_Fallback");
|
||||
}
|
||||
else
|
||||
{
|
||||
mMaterial = MaterialManager::getSingleton().getByName("Water");
|
||||
mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTexture(mReflectionTexture);
|
||||
}
|
||||
|
||||
// these have to be set in code
|
||||
std::string textureNames[32];
|
||||
|
@ -257,15 +242,20 @@ void Water::createMaterial()
|
|||
{
|
||||
textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds";
|
||||
}
|
||||
mMaterial->getTechnique(1)->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2);
|
||||
|
||||
// use technique without shaders if reflection is disabled
|
||||
Ogre::Technique* tech;
|
||||
if (mReflectionTarget == 0)
|
||||
mMaterial->removeTechnique(0);
|
||||
tech = mMaterial->getTechnique(0);
|
||||
else
|
||||
tech = mMaterial->getTechnique(1);
|
||||
|
||||
tech->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2);
|
||||
}
|
||||
|
||||
void Water::assignTextures()
|
||||
{
|
||||
if (Settings::Manager::getBool("shader", "Water"))
|
||||
{
|
||||
CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor("gbuffer");
|
||||
CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mRendering->getViewport())->getCompositor("gbuffer");
|
||||
|
||||
TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0);
|
||||
TextureUnitState* tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("refractionMap");
|
||||
|
@ -315,4 +305,84 @@ void Water::update()
|
|||
{
|
||||
}
|
||||
|
||||
void Water::applyRTT()
|
||||
{
|
||||
if (mReflectionTarget)
|
||||
{
|
||||
TextureManager::getSingleton().remove("WaterReflection");
|
||||
mReflectionTarget = 0;
|
||||
}
|
||||
|
||||
// Create rendertarget for reflection
|
||||
int rttsize = Settings::Manager::getInt("rtt size", "Water");
|
||||
|
||||
if (Settings::Manager::getBool("shader", "Water"))
|
||||
{
|
||||
mReflectionTexture = TextureManager::getSingleton().createManual("WaterReflection",
|
||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_FLOAT16_RGBA, TU_RENDERTARGET);
|
||||
|
||||
RenderTarget* rtt = mReflectionTexture->getBuffer()->getRenderTarget();
|
||||
Viewport* vp = rtt->addViewport(mReflectionCamera);
|
||||
vp->setOverlaysEnabled(false);
|
||||
vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f));
|
||||
vp->setShadowsEnabled(false);
|
||||
// use fallback techniques without shadows and without mrt (currently not implemented for sky and terrain)
|
||||
//vp->setMaterialScheme("Fallback");
|
||||
rtt->addListener(this);
|
||||
rtt->setActive(true);
|
||||
|
||||
mReflectionTarget = rtt;
|
||||
}
|
||||
|
||||
mCompositorName = RenderingManager::useMRT() ? "Underwater" : "UnderwaterNoMRT";
|
||||
}
|
||||
|
||||
void Water::applyVisibilityMask()
|
||||
{
|
||||
mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water")
|
||||
+ RV_Statics * Settings::Manager::getBool("reflect statics", "Water")
|
||||
+ RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water")
|
||||
+ RV_Actors * Settings::Manager::getBool("reflect actors", "Water")
|
||||
+ RV_Misc * Settings::Manager::getBool("reflect misc", "Water")
|
||||
+ RV_Sky;
|
||||
|
||||
if (mReflectionTarget)
|
||||
{
|
||||
mReflectionTexture->getBuffer()->getRenderTarget()->getViewport(0)->setVisibilityMask(mVisibilityFlags);
|
||||
}
|
||||
}
|
||||
|
||||
void Water::processChangedSettings(const Settings::CategorySettingVector& settings)
|
||||
{
|
||||
bool applyRT = false;
|
||||
bool applyVisMask = false;
|
||||
for (Settings::CategorySettingVector::const_iterator it=settings.begin();
|
||||
it != settings.end(); ++it)
|
||||
{
|
||||
if ( it->first == "Water" && (
|
||||
it->second == "shader"
|
||||
|| it->second == "rtt size"))
|
||||
applyRT = true;
|
||||
|
||||
if ( it->first == "Water" && (
|
||||
it->second == "reflect actors"
|
||||
|| it->second == "reflect terrain"
|
||||
|| it->second == "reflect misc"
|
||||
|| it->second == "reflect small statics"
|
||||
|| it->second == "reflect statics"))
|
||||
applyVisMask = true;
|
||||
}
|
||||
|
||||
if(applyRT)
|
||||
{
|
||||
applyRTT();
|
||||
applyVisibilityMask();
|
||||
createMaterial();
|
||||
mWater->setMaterial(mMaterial);
|
||||
assignTextures();
|
||||
}
|
||||
if (applyVisMask)
|
||||
applyVisibilityMask();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
|
||||
#include <Ogre.h>
|
||||
#include <components/esm/loadcell.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "renderconst.hpp"
|
||||
|
||||
|
||||
namespace MWRender {
|
||||
|
||||
class SkyManager;
|
||||
|
@ -17,7 +19,6 @@ namespace MWRender {
|
|||
static const int CELL_SIZE = 8192;
|
||||
Ogre::Camera *mCamera;
|
||||
Ogre::SceneManager *mSceneManager;
|
||||
Ogre::Viewport *mViewport;
|
||||
|
||||
Ogre::Plane mWaterPlane;
|
||||
Ogre::SceneNode *mWaterNode;
|
||||
|
@ -39,6 +40,9 @@ namespace MWRender {
|
|||
void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation);
|
||||
void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation);
|
||||
|
||||
void applyRTT();
|
||||
void applyVisibilityMask();
|
||||
|
||||
void updateVisible();
|
||||
|
||||
RenderingManager* mRendering;
|
||||
|
@ -51,6 +55,7 @@ namespace MWRender {
|
|||
|
||||
Ogre::Camera* mReflectionCamera;
|
||||
|
||||
Ogre::TexturePtr mReflectionTexture;
|
||||
Ogre::RenderTarget* mReflectionTarget;
|
||||
|
||||
bool mUnderwaterEffect;
|
||||
|
@ -65,8 +70,12 @@ namespace MWRender {
|
|||
void toggle();
|
||||
void update();
|
||||
|
||||
void assignTextures();
|
||||
|
||||
void setViewportBackground(const Ogre::ColourValue& bg);
|
||||
|
||||
void processChangedSettings(const Settings::CategorySettingVector& settings);
|
||||
|
||||
void checkUnderwater(float y);
|
||||
void changeCell(const ESM::Cell* cell);
|
||||
void setHeight(const float height);
|
||||
|
|
|
@ -146,4 +146,5 @@ op 0x200014f: ForceGreeting
|
|||
op 0x2000150: ForceGreeting, explicit reference
|
||||
op 0x2000151: ToggleFullHelp
|
||||
op 0x2000152: Goodbye
|
||||
op 0x2000153: DontSaveObject (left unimplemented)
|
||||
opcodes 0x2000154-0x3ffffff unused
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace MWScript
|
|||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode(mDialogue);
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(mDialogue);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -194,6 +194,17 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
class OpDontSaveObject : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
// We are ignoring the DontSaveObject statement for now. Probably not worth
|
||||
/// bothering with. The incompatibility we are creating should be marginal at most.
|
||||
}
|
||||
};
|
||||
|
||||
const int opcodeXBox = 0x200000c;
|
||||
const int opcodeOnActivate = 0x200000d;
|
||||
const int opcodeActivate = 0x2000075;
|
||||
|
@ -208,6 +219,7 @@ namespace MWScript
|
|||
const int opcodeFadeTo = 0x200013e;
|
||||
const int opcodeToggleWater = 0x2000144;
|
||||
const int opcodeTogglePathgrid = 0x2000146;
|
||||
const int opcodeDontSaveObject = 0x2000153;
|
||||
|
||||
void registerExtensions (Compiler::Extensions& extensions)
|
||||
{
|
||||
|
@ -229,6 +241,7 @@ namespace MWScript
|
|||
extensions.registerInstruction ("twa", "", opcodeToggleWater);
|
||||
extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid);
|
||||
extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid);
|
||||
extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
|
||||
}
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
|
@ -247,6 +260,7 @@ namespace MWScript
|
|||
interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo);
|
||||
interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid);
|
||||
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater);
|
||||
interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace MWSound
|
|||
public:
|
||||
virtual ~Sound_Output() { }
|
||||
|
||||
bool isInitialized() { return mInitialized; }
|
||||
bool isInitialized() const { return mInitialized; }
|
||||
|
||||
friend class OpenAL_Output;
|
||||
friend class SoundManager;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <OgreRoot.h>
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
|
@ -53,6 +52,8 @@ namespace MWSound
|
|||
, mMasterVolume(1.0f)
|
||||
, mSFXVolume(1.0f)
|
||||
, mMusicVolume(1.0f)
|
||||
, mFootstepsVolume(1.0f)
|
||||
, mVoiceVolume(1.0f)
|
||||
{
|
||||
if(!useSound)
|
||||
return;
|
||||
|
@ -63,6 +64,10 @@ namespace MWSound
|
|||
mSFXVolume = std::min(std::max(mSFXVolume, 0.0f), 1.0f);
|
||||
mMusicVolume = Settings::Manager::getFloat("music volume", "Sound");
|
||||
mMusicVolume = std::min(std::max(mMusicVolume, 0.0f), 1.0f);
|
||||
mVoiceVolume = Settings::Manager::getFloat("voice volume", "Sound");
|
||||
mVoiceVolume = std::min(std::max(mVoiceVolume, 0.0f), 1.0f);
|
||||
mFootstepsVolume = Settings::Manager::getFloat("footsteps volume", "Sound");
|
||||
mFootstepsVolume = std::min(std::max(mFootstepsVolume, 0.0f), 1.0f);
|
||||
|
||||
std::cout << "Sound output: " << SOUND_OUT << std::endl;
|
||||
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
|
||||
|
@ -210,7 +215,7 @@ namespace MWSound
|
|||
try
|
||||
{
|
||||
// The range values are not tested
|
||||
float basevol = mMasterVolume * mSFXVolume;
|
||||
float basevol = mMasterVolume * mVoiceVolume;
|
||||
std::string filePath = "Sound/"+filename;
|
||||
const ESM::Position &pos = ptr.getCellRef().pos;
|
||||
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
|
||||
|
@ -234,7 +239,7 @@ namespace MWSound
|
|||
return;
|
||||
try
|
||||
{
|
||||
float basevol = mMasterVolume * mSFXVolume;
|
||||
float basevol = mMasterVolume * mVoiceVolume;
|
||||
std::string filePath = "Sound/"+filename;
|
||||
|
||||
SoundPtr sound = mOutput->playSound(filePath, basevol, 1.0f, Play_Normal);
|
||||
|
@ -527,6 +532,39 @@ namespace MWSound
|
|||
}
|
||||
|
||||
|
||||
void SoundManager::processChangedSettings(const Settings::CategorySettingVector& settings)
|
||||
{
|
||||
mMasterVolume = Settings::Manager::getFloat("master volume", "Sound");
|
||||
mMusicVolume = Settings::Manager::getFloat("music volume", "Sound");
|
||||
mSFXVolume = Settings::Manager::getFloat("sfx volume", "Sound");
|
||||
mFootstepsVolume = Settings::Manager::getFloat("footsteps volume", "Sound");
|
||||
mVoiceVolume = Settings::Manager::getFloat("voice volume", "Sound");
|
||||
|
||||
SoundMap::iterator snditer = mActiveSounds.begin();
|
||||
while(snditer != mActiveSounds.end())
|
||||
{
|
||||
if(snditer->second.second != "_say_sound")
|
||||
{
|
||||
float basevol = mMasterVolume * mSFXVolume;
|
||||
float min, max;
|
||||
lookup(snditer->second.second, basevol, min, max);
|
||||
snditer->first->mBaseVolume = basevol;
|
||||
}
|
||||
else
|
||||
{
|
||||
float basevol = mMasterVolume * mVoiceVolume;
|
||||
snditer->first->mBaseVolume = basevol;
|
||||
}
|
||||
snditer->first->update();
|
||||
snditer++;
|
||||
}
|
||||
if(mMusic)
|
||||
{
|
||||
mMusic->mBaseVolume = mMasterVolume * mMusicVolume;
|
||||
mMusic->update();
|
||||
}
|
||||
}
|
||||
|
||||
// Default readAll implementation, for decoders that can't do anything
|
||||
// better
|
||||
void Sound_Decoder::readAll(std::vector<char> &output)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue