mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:53:51 +00:00
Merge branch 'master'
This commit is contained in:
commit
f675d8d039
277 changed files with 17149 additions and 2947 deletions
|
@ -15,7 +15,7 @@ include (OpenMWMacros)
|
|||
# Version
|
||||
|
||||
set (OPENMW_VERSION_MAJOR 0)
|
||||
set (OPENMW_VERSION_MINOR 14)
|
||||
set (OPENMW_VERSION_MINOR 15)
|
||||
set (OPENMW_VERSION_RELEASE 0)
|
||||
|
||||
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||
|
@ -103,6 +103,7 @@ set(OENGINE_OGRE
|
|||
${LIBDIR}/openengine/ogre/mouselook.cpp
|
||||
${LIBDIR}/openengine/ogre/fader.cpp
|
||||
${LIBDIR}/openengine/ogre/imagerotate.cpp
|
||||
${LIBDIR}/openengine/ogre/atlas.cpp
|
||||
)
|
||||
set(OENGINE_GUI
|
||||
${LIBDIR}/openengine/gui/events.cpp
|
||||
|
@ -122,6 +123,10 @@ set(OENGINE_BULLET
|
|||
${LIBDIR}/openengine/bullet/physic.hpp
|
||||
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
|
||||
${LIBDIR}/openengine/bullet/BulletShapeLoader.h
|
||||
${LIBDIR}/openengine/bullet/pmove.cpp
|
||||
${LIBDIR}/openengine/bullet/pmove.h
|
||||
${LIBDIR}/openengine/bullet/trace.cpp
|
||||
${LIBDIR}/openengine/bullet/trace.h
|
||||
|
||||
)
|
||||
|
||||
|
|
10
Daedric Font License.txt
Normal file
10
Daedric Font License.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
Dongle's Oblivion Daedric font set
|
||||
http://www.uesp.net/wiki/Lore:Daedric_Alphabet#Daedric_Font
|
||||
|
||||
---------------------------------------------------
|
||||
|
||||
This was done entirely as a personal project. Bethesda Softworks graciously granted me the permission for it. I am not connected with them in any way.
|
||||
You may freely use these fonts to create anything you'd like. You may re-distribute the fonts freely, over the Internet, or by any other means. Always keep the .zip file intact, and this read me included.
|
||||
Please do not modify and redistribute the fonts without my permission.
|
||||
You may NOT sell any of these fonts under any circumstances. This includes putting them on compilation font CDs for sale, putting them in a "members only" pay-area of a website, or any other means of financial gain connected in ANY way with the redistribution of any of these fonts.
|
||||
You have my permission to create and sell any artwork made with these fonts, however you may need to contact Bethesda Softworks before doing so.
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
|
|||
add_openmw_dir (mwrender
|
||||
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
|
||||
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows shaderhelper
|
||||
compositors
|
||||
)
|
||||
|
||||
add_openmw_dir (mwinput
|
||||
|
@ -23,9 +24,11 @@ add_openmw_dir (mwinput
|
|||
)
|
||||
|
||||
add_openmw_dir (mwgui
|
||||
layouts text_input widgets race class birth review window_manager console dialogue
|
||||
text_input widgets race class birth review window_manager console dialogue
|
||||
dialogue_history window_base stats_window messagebox journalwindow charactercreation
|
||||
map_window window_pinnable_base cursorreplace
|
||||
map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
|
||||
formatting inventorywindow container hud countdialog tradewindow settingswindow
|
||||
confirmationdialog alchemywindow referenceinterface spellwindow
|
||||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
|
@ -46,7 +49,8 @@ add_openmw_dir (mwsound
|
|||
add_openmw_dir (mwworld
|
||||
refdata world physicssystem scene globals class action nullaction actionteleport
|
||||
containerstore actiontalk actiontake manualref player cellfunctors
|
||||
cells localscripts customdata weather inventorystore ptr
|
||||
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
||||
actionequip timestamp actionalchemy
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
|
@ -56,6 +60,7 @@ add_openmw_dir (mwclass
|
|||
|
||||
add_openmw_dir (mwmechanics
|
||||
mechanicsmanager stat creaturestats magiceffects movement actors drawstate spells
|
||||
activespells
|
||||
)
|
||||
|
||||
add_openmw_dir (mwbase
|
||||
|
|
|
@ -74,47 +74,6 @@ void OMW::Engine::executeLocalScripts()
|
|||
localScripts.setIgnore (MWWorld::Ptr());
|
||||
}
|
||||
|
||||
void OMW::Engine::updateFocusReport (float duration)
|
||||
{
|
||||
|
||||
if ((mFocusTDiff += duration)>0.25)
|
||||
{
|
||||
mFocusTDiff = 0;
|
||||
|
||||
std::string name;
|
||||
|
||||
std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle();
|
||||
|
||||
if (!handle.empty())
|
||||
{
|
||||
// the faced handle is not updated immediately, so on a cell change it might
|
||||
// point to an object that doesn't exist anymore
|
||||
// therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case
|
||||
try
|
||||
{
|
||||
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle);
|
||||
|
||||
if (!ptr.isEmpty()){
|
||||
name = MWWorld::Class::get (ptr).getName (ptr);
|
||||
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{}
|
||||
}
|
||||
|
||||
if (name!=mFocusName)
|
||||
{
|
||||
mFocusName = name;
|
||||
|
||||
if (mFocusName.empty())
|
||||
std::cout << "Unfocus" << std::endl;
|
||||
else
|
||||
std::cout << "Focus: " << name << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OMW::Engine::setAnimationVerbose(bool animverbose){
|
||||
if(animverbose){
|
||||
NifOgre::NIFLoader::getSingletonPtr()->setOutputAnimFiles(true);
|
||||
|
@ -135,14 +94,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
|||
if (mUseSound)
|
||||
MWBase::Environment::get().getSoundManager()->update (evt.timeSinceLastFrame);
|
||||
|
||||
// update GUI
|
||||
Ogre::RenderWindow* window = mOgre->getWindow();
|
||||
MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(),
|
||||
window->getTriangleCount(),
|
||||
window->getBatchCount());
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->onFrame(mEnvironment.getFrameDuration());
|
||||
|
||||
// global scripts
|
||||
MWBase::Environment::get().getScriptManager()->getGlobalScripts().run();
|
||||
|
||||
|
@ -154,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);
|
||||
|
||||
|
@ -165,17 +116,21 @@ 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
|
||||
MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame);
|
||||
|
||||
// report focus object (for debugging)
|
||||
if (mReportFocus)
|
||||
updateFocusReport (mEnvironment.getFrameDuration());
|
||||
// update GUI
|
||||
Ogre::RenderWindow* window = mOgre->getWindow();
|
||||
MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(),
|
||||
window->getTriangleCount(),
|
||||
window->getBatchCount());
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->onFrame(evt.timeSinceLastFrame);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
@ -193,8 +148,6 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
|||
, mNewGame (false)
|
||||
, mUseSound (true)
|
||||
, mCompileAll (false)
|
||||
, mReportFocus (false)
|
||||
, mFocusTDiff (0)
|
||||
, mScriptContext (0)
|
||||
, mFSStrict (false)
|
||||
, mCfgMgr(configurationManager)
|
||||
|
@ -205,13 +158,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
|||
|
||||
OMW::Engine::~Engine()
|
||||
{
|
||||
delete MWBase::Environment::get().getInputManager();
|
||||
delete MWBase::Environment::get().getSoundManager();
|
||||
delete MWBase::Environment::get().getMechanicsManager();
|
||||
delete MWBase::Environment::get().getDialogueManager();
|
||||
delete MWBase::Environment::get().getJournal();
|
||||
delete MWBase::Environment::get().getScriptManager();
|
||||
delete MWBase::Environment::get().getWorld();
|
||||
mEnvironment.cleanup();
|
||||
delete mScriptContext;
|
||||
delete mOgre;
|
||||
}
|
||||
|
@ -247,6 +194,12 @@ void OMW::Engine::addResourcesDirectory (const boost::filesystem::path& path)
|
|||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
|
||||
}
|
||||
|
||||
void OMW::Engine::addZipResource (const boost::filesystem::path& path)
|
||||
{
|
||||
mOgre->getRoot()->addResourceLocation (path.string(), "Zip",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false);
|
||||
}
|
||||
|
||||
void OMW::Engine::enableFSStrict(bool fsStrict)
|
||||
{
|
||||
mFSStrict = fsStrict;
|
||||
|
@ -305,31 +258,16 @@ void OMW::Engine::setNewGame(bool newGame)
|
|||
mNewGame = newGame;
|
||||
}
|
||||
|
||||
void OMW::Engine::setReportFocus (bool report)
|
||||
{
|
||||
mReportFocus = report;
|
||||
}
|
||||
|
||||
// Initialise and enter main loop.
|
||||
|
||||
void OMW::Engine::go()
|
||||
{
|
||||
mFocusTDiff = 0;
|
||||
assert (!mCellName.empty());
|
||||
assert (!mMaster.empty());
|
||||
assert (!mOgre);
|
||||
|
||||
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";
|
||||
|
@ -340,6 +278,8 @@ void OMW::Engine::go()
|
|||
settings.loadDefault(localdefault);
|
||||
else if (boost::filesystem::exists(globaldefault))
|
||||
settings.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";
|
||||
|
@ -359,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.
|
||||
|
@ -373,9 +323,17 @@ void OMW::Engine::go()
|
|||
addResourcesDirectory(mResDir / "water");
|
||||
addResourcesDirectory(mResDir / "gbuffer");
|
||||
addResourcesDirectory(mResDir / "shadows");
|
||||
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();
|
||||
|
||||
|
@ -463,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();
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace OMW
|
|||
/// \brief Main engine class, that brings together all the components of OpenMW
|
||||
class Engine : private Ogre::FrameListener
|
||||
{
|
||||
MWBase::Environment mEnvironment;
|
||||
std::string mEncoding;
|
||||
Files::PathContainer mDataDirs;
|
||||
boost::filesystem::path mResDir;
|
||||
|
@ -74,12 +75,9 @@ namespace OMW
|
|||
bool mNewGame;
|
||||
bool mUseSound;
|
||||
bool mCompileAll;
|
||||
bool mReportFocus;
|
||||
float mFocusTDiff;
|
||||
std::string mFocusName;
|
||||
std::map<std::string,std::string> mFallbackMap;
|
||||
|
||||
MWBase::Environment mEnvironment;
|
||||
Compiler::Extensions mExtensions;
|
||||
Compiler::Context *mScriptContext;
|
||||
|
||||
|
@ -93,16 +91,16 @@ namespace OMW
|
|||
|
||||
/// add resources directory
|
||||
/// \note This function works recursively.
|
||||
|
||||
void addResourcesDirectory (const boost::filesystem::path& path);
|
||||
|
||||
/// add a .zip resource
|
||||
void addZipResource (const boost::filesystem::path& path);
|
||||
|
||||
/// Load all BSA files in data directory.
|
||||
void loadBSA();
|
||||
|
||||
void executeLocalScripts();
|
||||
|
||||
void updateFocusReport (float duration);
|
||||
|
||||
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
|
||||
|
||||
public:
|
||||
|
@ -145,9 +143,6 @@ namespace OMW
|
|||
/// Start as a new game.
|
||||
void setNewGame(bool newGame);
|
||||
|
||||
/// Write name of focussed object to cout
|
||||
void setReportFocus (bool report);
|
||||
|
||||
/// Initialise and enter main loop.
|
||||
void go();
|
||||
|
||||
|
|
|
@ -155,9 +155,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
|
||||
"\n\twin1252 - Western European (Latin) alphabet, used by default")
|
||||
|
||||
("report-focus", bpo::value<bool>()->implicit_value(true)
|
||||
->default_value(false), "write name of focussed object to cout")
|
||||
|
||||
("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "")
|
||||
->multitoken()->composing(), "fallback values")
|
||||
|
||||
|
@ -265,7 +262,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
engine.setSoundUsage(!variables["nosound"].as<bool>());
|
||||
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
||||
engine.setCompileAll(variables["script-all"].as<bool>());
|
||||
engine.setReportFocus(variables["report-focus"].as<bool>());
|
||||
engine.setAnimationVerbose(variables["anim-verbose"].as<bool>());
|
||||
engine.setFallbackValues(variables["fallback"].as<FallbackMap>().mMap);
|
||||
|
||||
|
|
|
@ -3,6 +3,19 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
|
||||
#include "../mwscript/scriptmanager.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwdialogue/dialoguemanager.hpp"
|
||||
#include "../mwdialogue/journal.hpp"
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
|
||||
MWBase::Environment *MWBase::Environment::sThis = 0;
|
||||
|
||||
MWBase::Environment::Environment()
|
||||
|
@ -15,6 +28,7 @@ MWBase::Environment::Environment()
|
|||
|
||||
MWBase::Environment::~Environment()
|
||||
{
|
||||
cleanup();
|
||||
sThis = 0;
|
||||
}
|
||||
|
||||
|
@ -116,6 +130,30 @@ float MWBase::Environment::getFrameDuration() const
|
|||
return mFrameDuration;
|
||||
}
|
||||
|
||||
void MWBase::Environment::cleanup()
|
||||
{
|
||||
delete mInputManager;
|
||||
mInputManager = 0;
|
||||
|
||||
delete mSoundManager;
|
||||
mSoundManager = 0;
|
||||
|
||||
delete mMechanicsManager;
|
||||
mMechanicsManager = 0;
|
||||
|
||||
delete mDialogueManager;
|
||||
mDialogueManager = 0;
|
||||
|
||||
delete mJournal;
|
||||
mJournal = 0;
|
||||
|
||||
delete mScriptManager;
|
||||
mScriptManager = 0;
|
||||
|
||||
delete mWorld;
|
||||
mWorld = 0;
|
||||
}
|
||||
|
||||
const MWBase::Environment& MWBase::Environment::get()
|
||||
{
|
||||
assert (sThis);
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace MWBase
|
|||
///
|
||||
/// This class allows each mw-subsystem to access any others subsystem's top-level manager class.
|
||||
///
|
||||
/// \attention Environment does not take ownership of the manager class instances it is handed over in
|
||||
/// \attention Environment takes ownership of the manager class instances it is handed over in
|
||||
/// the set* functions.
|
||||
class Environment
|
||||
{
|
||||
|
@ -108,6 +108,9 @@ namespace MWBase
|
|||
|
||||
float getFrameDuration() const;
|
||||
|
||||
void cleanup();
|
||||
///< Delete all mw*-subsystems.
|
||||
|
||||
static const Environment& get();
|
||||
///< Return instance of this class.
|
||||
};
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
|
||||
#include "activator.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include <components/esm/loadacti.hpp>
|
||||
|
||||
#include <components/esm_store/cell_store.hpp>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
@ -63,4 +64,28 @@ namespace MWClass
|
|||
|
||||
registerClass (typeid (ESM::Activator).name(), instance);
|
||||
}
|
||||
|
||||
bool Activator::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Activator, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Activator>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Activator::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Activator, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Activator>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
|
||||
std::string text;
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@ namespace MWClass
|
|||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
/// can return an empty string.
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
|
|
|
@ -9,9 +9,14 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionalchemy.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
namespace MWClass
|
||||
|
@ -95,4 +100,51 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Apparatus Down");
|
||||
}
|
||||
|
||||
std::string Apparatus::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Apparatus>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Apparatus::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Apparatus>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Apparatus::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Apparatus>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
text += "\n" + store.gameSettings.search("sQuality")->str + ": " + MWGui::ToolTips::toString(ref->base->data.quality);
|
||||
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);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Apparatus::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionAlchemy());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,12 @@ namespace MWClass
|
|||
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
static void registerSelf();
|
||||
|
||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
|
||||
|
@ -35,6 +41,13 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
|
@ -16,6 +17,8 @@
|
|||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
namespace MWClass
|
||||
|
@ -138,8 +141,7 @@ namespace MWClass
|
|||
case ESM::Armor::Boots: typeGmst = "iBootsWeight"; break;
|
||||
case ESM::Armor::LGauntlet:
|
||||
case ESM::Armor::RGauntlet: typeGmst = "iGauntletWeight"; break;
|
||||
/// \todo how to determine if shield light, medium or heavy?
|
||||
// case ESM::Armor::Shield:
|
||||
case ESM::Armor::Shield: typeGmst = "iShieldWeight"; break;
|
||||
case ESM::Armor::LBracer:
|
||||
case ESM::Armor::RBracer: typeGmst = "iGauntletWeight"; break;
|
||||
}
|
||||
|
@ -196,4 +198,78 @@ namespace MWClass
|
|||
else
|
||||
return std::string("Item Armor Heavy Down");
|
||||
}
|
||||
|
||||
std::string Armor::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Armor>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Armor::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Armor>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Armor::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Armor>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
std::string text;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
// get armor type string (light/medium/heavy)
|
||||
int armorType = getEquipmentSkill(ptr);
|
||||
std::string typeText;
|
||||
if (armorType == ESM::Skill::LightArmor)
|
||||
typeText = store.gameSettings.search("sLight")->str;
|
||||
else if (armorType == ESM::Skill::MediumArmor)
|
||||
typeText = store.gameSettings.search("sMedium")->str;
|
||||
else
|
||||
typeText = store.gameSettings.search("sHeavy")->str;
|
||||
|
||||
text += "\n" + store.gameSettings.search("sArmorRating")->str + ": " + MWGui::ToolTips::toString(ref->base->data.armor);
|
||||
|
||||
/// \todo store the current armor health somewhere
|
||||
text += "\n" + store.gameSettings.search("sCondition")->str + ": " + MWGui::ToolTips::toString(ref->base->data.health);
|
||||
|
||||
text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight) + " (" + typeText + ")";
|
||||
text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.enchant = ref->base->enchant;
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string Armor::getEnchantment (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Armor>();
|
||||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,12 @@ namespace MWClass
|
|||
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
|
||||
/// no such skill.
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||
|
||||
|
@ -49,6 +55,17 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,13 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionread.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
namespace MWClass
|
||||
|
@ -57,12 +60,8 @@ namespace MWClass
|
|||
boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr,
|
||||
const MWWorld::Ptr& actor) const
|
||||
{
|
||||
// TODO implement reading
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action> (
|
||||
new MWWorld::ActionTake (ptr));
|
||||
new MWWorld::ActionRead (ptr));
|
||||
}
|
||||
|
||||
std::string Book::getScript (const MWWorld::Ptr& ptr) const
|
||||
|
@ -97,4 +96,62 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Book Down");
|
||||
}
|
||||
|
||||
std::string Book::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Book>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Book::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Book>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Book::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Book>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
|
||||
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);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.enchant = ref->base->enchant;
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string Book::getEnchantment (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Book>();
|
||||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,12 @@ namespace MWClass
|
|||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||
|
||||
|
@ -35,6 +41,15 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
|
@ -161,4 +166,63 @@ namespace MWClass
|
|||
}
|
||||
return std::string("Item Clothes Down");
|
||||
}
|
||||
|
||||
std::string Clothing::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Clothing>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Clothing::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Clothing>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Clothing::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Clothing>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
|
||||
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);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.enchant = ref->base->enchant;
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string Clothing::getEnchantment (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Clothing>();
|
||||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,12 @@ namespace MWClass
|
|||
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
|
||||
/// no such skill.
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||
|
||||
|
@ -43,6 +49,16 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,13 @@
|
|||
#include "../mwworld/nullaction.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/customdata.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
#include "../mwworld/actionopen.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
|
@ -82,6 +87,7 @@ namespace MWClass
|
|||
const std::string lockedSound = "LockedChest";
|
||||
const std::string trapActivationSound = "Disarm Trap Fail";
|
||||
|
||||
|
||||
if (ptr.getCellRef().lockLevel>0)
|
||||
{
|
||||
// TODO check for key
|
||||
|
@ -95,7 +101,8 @@ namespace MWClass
|
|||
if(ptr.getCellRef().trap.empty())
|
||||
{
|
||||
// Not trapped, Inventory GUI goes here
|
||||
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||
//return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionOpen(ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -138,4 +145,51 @@ namespace MWClass
|
|||
|
||||
registerClass (typeid (ESM::Container).name(), instance);
|
||||
}
|
||||
|
||||
bool Container::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Container>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Container::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Container>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
if (ref->ref.lockLevel > 0)
|
||||
text += "\n" + store.gameSettings.search("sLockLevel")->str + ": " + MWGui::ToolTips::toString(ref->ref.lockLevel);
|
||||
if (ref->ref.trap != "")
|
||||
text += "\n" + store.gameSettings.search("sTrapped")->str;
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
float Container::getCapacity (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Container>();
|
||||
|
||||
return ref->base->weight;
|
||||
}
|
||||
|
||||
float Container::getEncumbrance (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return getContainerStore (ptr).getWeight();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,26 @@ namespace MWClass
|
|||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const;
|
||||
///< Return container store
|
||||
|
||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
||||
///< Return total weight that fits into the object. Throws an exception, if the object can't
|
||||
/// hold other objects.
|
||||
|
||||
virtual float getEncumbrance (const MWWorld::Ptr& ptr) const;
|
||||
///< Returns total weight of objects inside this object (including modifications from magic
|
||||
/// effects). Throws an exception, if the object can't hold other objects.
|
||||
|
||||
static void registerSelf();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include "../mwmechanics/magiceffects.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
|
@ -13,6 +14,8 @@
|
|||
#include "../mwworld/customdata.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
|
@ -54,8 +57,6 @@ namespace MWClass
|
|||
|
||||
data->mCreatureStats.mLevel = ref->base->data.level;
|
||||
|
||||
// \todo add initial container content
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
}
|
||||
|
@ -80,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.insertActorPhysics(ptr, "meshes\\" + model);
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::enable (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
|
||||
}
|
||||
|
||||
void Creature::disable (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->removeActor (ptr);
|
||||
}
|
||||
|
||||
std::string Creature::getName (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
|
||||
|
@ -141,4 +133,49 @@ namespace MWClass
|
|||
|
||||
registerClass (typeid (ESM::Creature).name(), instance);
|
||||
}
|
||||
|
||||
bool Creature::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
/// \todo We don't want tooltips for Creatures in combat mode.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Creature::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Creature>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
|
||||
std::string text;
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
float Creature::getCapacity (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
return stats.mAttributes[0].getModified()*5;
|
||||
}
|
||||
|
||||
float Creature::getEncumbrance (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
float weight = getContainerStore (ptr).getWeight();
|
||||
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
|
||||
weight -= stats.mMagicEffects.get (MWMechanics::EffectKey (8)).mMagnitude; // feather
|
||||
|
||||
weight += stats.mMagicEffects.get (MWMechanics::EffectKey (7)).mMagnitude; // burden
|
||||
|
||||
if (weight<0)
|
||||
weight = 0;
|
||||
|
||||
return weight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,16 +22,16 @@ 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.
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
|
||||
///< Return creature stats
|
||||
|
||||
|
@ -46,6 +46,14 @@ namespace MWClass
|
|||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
||||
///< Return total weight that fits into the object. Throws an exception, if the object can't
|
||||
/// hold other objects.
|
||||
|
||||
virtual float getEncumbrance (const MWWorld::Ptr& ptr) const;
|
||||
///< Returns total weight of objects inside this object (including modifications from magic
|
||||
/// effects). Throws an exception, if the object can't hold other objects.
|
||||
|
||||
static void registerSelf();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include "../mwworld/actionteleport.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
@ -143,4 +146,63 @@ namespace MWClass
|
|||
|
||||
registerClass (typeid (ESM::Door).name(), instance);
|
||||
}
|
||||
|
||||
bool Door::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Door>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Door::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Door>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
|
||||
std::string text;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
if (ref->ref.teleport)
|
||||
{
|
||||
std::string dest;
|
||||
if (ref->ref.destCell != "")
|
||||
{
|
||||
// door leads to an interior, use interior name as tooltip
|
||||
dest = ref->ref.destCell;
|
||||
}
|
||||
else
|
||||
{
|
||||
// door leads to exterior, use cell name (if any), otherwise translated region name
|
||||
int x,y;
|
||||
MWBase::Environment::get().getWorld()->positionToIndex (ref->ref.doorDest.pos[0], ref->ref.doorDest.pos[1], x, y);
|
||||
const ESM::Cell* cell = store.cells.findExt(x,y);
|
||||
if (cell->name != "")
|
||||
dest = cell->name;
|
||||
else
|
||||
{
|
||||
const ESM::Region* region = store.regions.search(cell->region);
|
||||
dest = region->name;
|
||||
}
|
||||
}
|
||||
text += "\n" + store.gameSettings.search("sTo")->str;
|
||||
text += "\n"+dest;
|
||||
}
|
||||
|
||||
if (ref->ref.lockLevel > 0)
|
||||
text += "\n" + store.gameSettings.search("sLockLevel")->str + ": " + MWGui::ToolTips::toString(ref->ref.lockLevel);
|
||||
if (ref->ref.trap != "")
|
||||
text += "\n" + store.gameSettings.search("sTrapped")->str;
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,12 @@ namespace MWClass
|
|||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
|
||||
///< Lock object
|
||||
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
|
@ -93,4 +97,59 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Ingredient Down");
|
||||
}
|
||||
|
||||
std::string Ingredient::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Ingredient>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Ingredient::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Ingredient>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Ingredient::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Ingredient>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
|
||||
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);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,12 @@ namespace MWClass
|
|||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
|
@ -35,6 +41,9 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,13 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
|
@ -51,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())
|
||||
{
|
||||
|
@ -135,4 +134,54 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Misc Down");
|
||||
}
|
||||
|
||||
|
||||
std::string Light::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Light>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Light::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Light>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Light::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Light>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
|
||||
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);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.text = text;
|
||||
|
||||
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,15 +14,16 @@ 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.
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
||||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
@ -44,6 +45,13 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,11 @@
|
|||
|
||||
#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"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
|
@ -106,4 +110,57 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Lockpick Down");
|
||||
}
|
||||
|
||||
std::string Lockpick::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
|
||||
/// \todo store remaining uses somewhere
|
||||
|
||||
text += "\n" + store.gameSettings.search("sUses")->str + ": " + MWGui::ToolTips::toString(ref->base->data.uses);
|
||||
text += "\n" + store.gameSettings.search("sQuality")->str + ": " + MWGui::ToolTips::toString(ref->base->data.quality);
|
||||
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);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.text = text;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,12 @@ namespace MWClass
|
|||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
|
@ -39,6 +45,13 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include "misc.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/esm/loadmisc.hpp>
|
||||
|
||||
#include <components/esm_store/cell_store.hpp>
|
||||
|
@ -9,11 +11,17 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||
|
@ -91,7 +99,7 @@ namespace MWClass
|
|||
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
if (ref->base->name =="Gold")
|
||||
if (ref->base->name == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
|
||||
{
|
||||
return std::string("Item Gold Up");
|
||||
}
|
||||
|
@ -103,10 +111,74 @@ namespace MWClass
|
|||
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
if (ref->base->name =="Gold")
|
||||
if (ref->base->name == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
|
||||
{
|
||||
return std::string("Item Gold Down");
|
||||
}
|
||||
return std::string("Item Misc Down");
|
||||
}
|
||||
|
||||
std::string Miscellaneous::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Miscellaneous::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Miscellaneous::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
int count = ptr.getRefData().getCount();
|
||||
|
||||
bool isGold = (ref->base->name == store.gameSettings.search("sGold")->str);
|
||||
if (isGold && count == 1)
|
||||
count = ref->base->data.value;
|
||||
|
||||
std::string countString;
|
||||
if (!isGold)
|
||||
countString = MWGui::ToolTips::getCountString(count);
|
||||
else // gold displays its count also if it's 1.
|
||||
countString = " (" + boost::lexical_cast<std::string>(count) + ")";
|
||||
|
||||
info.caption = ref->base->name + countString;
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
if (ref->ref.soul != "")
|
||||
{
|
||||
const ESM::Creature *creature = store.creatures.search(ref->ref.soul);
|
||||
info.caption += " (" + creature->name + ")";
|
||||
}
|
||||
|
||||
std::string text;
|
||||
|
||||
if (!isGold)
|
||||
{
|
||||
text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight);
|
||||
text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str);
|
||||
}
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,12 @@ namespace MWClass
|
|||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
|
@ -35,6 +41,9 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
|
@ -18,6 +20,8 @@
|
|||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/customdata.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
namespace
|
||||
|
@ -54,13 +58,15 @@ namespace MWClass
|
|||
// NPC stats
|
||||
if (!ref->base->faction.empty())
|
||||
{
|
||||
std::string faction = ref->base->faction;
|
||||
boost::algorithm::to_lower(faction);
|
||||
if(ref->base->npdt52.gold != -10)
|
||||
{
|
||||
data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt52.rank;
|
||||
data->mNpcStats.mFactionRank[faction] = (int)ref->base->npdt52.rank;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt12.rank;
|
||||
data->mNpcStats.mFactionRank[faction] = (int)ref->base->npdt12.rank;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,11 +92,9 @@ namespace MWClass
|
|||
}
|
||||
else
|
||||
{
|
||||
//TODO: do something with npdt12 maybe:p
|
||||
/// \todo do something with npdt12 maybe:p
|
||||
}
|
||||
|
||||
// \todo add initial container content
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
}
|
||||
|
@ -106,44 +110,27 @@ namespace MWClass
|
|||
|
||||
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||
{
|
||||
|
||||
|
||||
renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr));
|
||||
|
||||
}
|
||||
|
||||
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
|
||||
{
|
||||
|
||||
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::NPC>();
|
||||
|
||||
|
||||
assert (ref->base != NULL);
|
||||
std::string headID = ref->base->head;
|
||||
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
|
||||
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
|
||||
|
||||
|
||||
std::string smodel = "meshes\\base_anim.nif";
|
||||
if(beast)
|
||||
smodel = "meshes\\base_animkna.nif";
|
||||
physics.insertActorPhysics(ptr, smodel);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Npc::enable (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
|
||||
}
|
||||
|
||||
void Npc::disable (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->removeActor (ptr);
|
||||
}
|
||||
|
||||
std::string Npc::getName (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
|
||||
|
@ -285,11 +272,12 @@ namespace MWClass
|
|||
{
|
||||
Ogre::Vector3 vector (0, 0, 0);
|
||||
|
||||
vector.x = - getMovementSettings (ptr).mLeftRight * 200;
|
||||
vector.y = getMovementSettings (ptr).mForwardBackward * 200;
|
||||
vector.x = - getMovementSettings (ptr).mLeftRight * 127;
|
||||
vector.y = getMovementSettings (ptr).mForwardBackward * 127;
|
||||
vector.z = getMovementSettings(ptr).mUpDown * 127;
|
||||
|
||||
if (getStance (ptr, Run, false))
|
||||
vector *= 2;
|
||||
//if (getStance (ptr, Run, false))
|
||||
// vector *= 2;
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
@ -299,4 +287,49 @@ namespace MWClass
|
|||
boost::shared_ptr<Class> instance (new Npc);
|
||||
registerClass (typeid (ESM::NPC).name(), instance);
|
||||
}
|
||||
|
||||
bool Npc::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
/// \todo We don't want tooltips for NPCs in combat mode.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Npc::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::NPC>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name;
|
||||
|
||||
std::string text;
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
float Npc::getCapacity (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
return stats.mAttributes[0].getModified()*5;
|
||||
}
|
||||
|
||||
float Npc::getEncumbrance (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
float weight = getContainerStore (ptr).getWeight();
|
||||
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
|
||||
weight -= stats.mMagicEffects.get (MWMechanics::EffectKey (8)).mMagnitude; // feather
|
||||
|
||||
weight += stats.mMagicEffects.get (MWMechanics::EffectKey (7)).mMagnitude; // burden
|
||||
|
||||
if (weight<0)
|
||||
weight = 0;
|
||||
|
||||
return weight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,6 @@ namespace MWClass
|
|||
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
|
||||
|
||||
virtual void enable (const MWWorld::Ptr& ptr) const;
|
||||
///< Enable reference; only does the non-rendering part
|
||||
|
||||
virtual void disable (const MWWorld::Ptr& ptr) const;
|
||||
///< Enable reference; only does the non-rendering part
|
||||
|
||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
/// can return an empty string.
|
||||
|
@ -38,6 +32,12 @@ namespace MWClass
|
|||
virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const;
|
||||
///< Return container store
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const;
|
||||
///< Return inventory store
|
||||
|
||||
|
@ -68,6 +68,14 @@ namespace MWClass
|
|||
///< Return desired movement vector (determined based on movement settings,
|
||||
/// stance and stats).
|
||||
|
||||
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
||||
///< Return total weight that fits into the object. Throws an exception, if the object can't
|
||||
/// hold other objects.
|
||||
|
||||
virtual float getEncumbrance (const MWWorld::Ptr& ptr) const;
|
||||
///< Returns total weight of objects inside this object (including modifications from magic
|
||||
/// effects). Throws an exception, if the object can't hold other objects.
|
||||
|
||||
static void registerSelf();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
|
@ -95,4 +99,48 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Potion Down");
|
||||
}
|
||||
|
||||
std::string Potion::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Potion>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Potion::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Potion>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Potion::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Potion>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
|
||||
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 = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->base->effects);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,12 @@ namespace MWClass
|
|||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
|
@ -35,6 +41,9 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,11 @@
|
|||
|
||||
#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"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
|
@ -105,4 +109,57 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Probe Down");
|
||||
}
|
||||
|
||||
std::string Probe::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Probe>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Probe::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Probe>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Probe::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Probe>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
|
||||
/// \todo store remaining uses somewhere
|
||||
|
||||
text += "\n" + store.gameSettings.search("sUses")->str + ": " + MWGui::ToolTips::toString(ref->base->data.uses);
|
||||
text += "\n" + store.gameSettings.search("sQuality")->str + ": " + MWGui::ToolTips::toString(ref->base->data.quality);
|
||||
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);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.text = text;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,12 @@ namespace MWClass
|
|||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
|
@ -39,6 +45,13 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
|
@ -95,4 +98,49 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Repair Down");
|
||||
}
|
||||
|
||||
std::string Repair::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Repair>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Repair::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Repair>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Repair>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
std::string text;
|
||||
|
||||
/// \todo store remaining uses somewhere
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
text += "\n" + store.gameSettings.search("sUses")->str + ": " + MWGui::ToolTips::toString(ref->base->data.uses);
|
||||
text += "\n" + store.gameSettings.search("sQuality")->str + ": " + MWGui::ToolTips::toString(ref->base->data.quality);
|
||||
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);
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,12 @@ namespace MWClass
|
|||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
|
@ -35,6 +41,9 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
|
||||
#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"
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
|
@ -245,4 +250,117 @@ namespace MWClass
|
|||
|
||||
return std::string("Item Misc Down");
|
||||
}
|
||||
|
||||
std::string Weapon::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
|
||||
return ref->base->icon;
|
||||
}
|
||||
|
||||
bool Weapon::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
|
||||
return (ref->base->name != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Weapon::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
info.icon = ref->base->icon;
|
||||
|
||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string text;
|
||||
|
||||
// weapon type & damage. arrows / bolts don't have his info.
|
||||
if (ref->base->data.type < 12)
|
||||
{
|
||||
text += "\n" + store.gameSettings.search("sType")->str + " ";
|
||||
|
||||
std::map <int, std::pair <std::string, std::string> > mapping;
|
||||
mapping[ESM::Weapon::ShortBladeOneHand] = std::make_pair("sSkillShortblade", "sOneHanded");
|
||||
mapping[ESM::Weapon::LongBladeOneHand] = std::make_pair("sSkillLongblade", "sOneHanded");
|
||||
mapping[ESM::Weapon::LongBladeTwoHand] = std::make_pair("sSkillLongblade", "sTwoHanded");
|
||||
mapping[ESM::Weapon::BluntOneHand] = std::make_pair("sSkillBluntweapon", "sOneHanded");
|
||||
mapping[ESM::Weapon::BluntTwoClose] = std::make_pair("sSkillBluntweapon", "sTwoHanded");
|
||||
mapping[ESM::Weapon::BluntTwoWide] = std::make_pair("sSkillBluntweapon", "sTwoHanded");
|
||||
mapping[ESM::Weapon::SpearTwoWide] = std::make_pair("sSkillSpear", "sTwoHanded");
|
||||
mapping[ESM::Weapon::AxeOneHand] = std::make_pair("sSkillAxe", "sOneHanded");
|
||||
mapping[ESM::Weapon::AxeTwoHand] = std::make_pair("sSkillAxe", "sTwoHanded");
|
||||
mapping[ESM::Weapon::MarksmanBow] = std::make_pair("sSkillMarksman", "");
|
||||
mapping[ESM::Weapon::MarksmanCrossbow] = std::make_pair("sSkillMarksman", "");
|
||||
mapping[ESM::Weapon::MarksmanThrown] = std::make_pair("sSkillMarksman", "");
|
||||
|
||||
std::string type = mapping[ref->base->data.type].first;
|
||||
std::string oneOrTwoHanded = mapping[ref->base->data.type].second;
|
||||
|
||||
text += store.gameSettings.search(type)->str +
|
||||
((oneOrTwoHanded != "") ? ", " + store.gameSettings.search(oneOrTwoHanded)->str : "");
|
||||
|
||||
// weapon damage
|
||||
if (ref->base->data.type >= 9)
|
||||
{
|
||||
// marksman
|
||||
text += "\n" + store.gameSettings.search("sAttack")->str + ": "
|
||||
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->data.chop[0]))
|
||||
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->data.chop[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Chop
|
||||
text += "\n" + store.gameSettings.search("sChop")->str + ": "
|
||||
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->data.chop[0]))
|
||||
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->data.chop[1]));
|
||||
// Slash
|
||||
text += "\n" + store.gameSettings.search("sSlash")->str + ": "
|
||||
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->data.slash[0]))
|
||||
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->data.slash[1]));
|
||||
// Thrust
|
||||
text += "\n" + store.gameSettings.search("sThrust")->str + ": "
|
||||
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->data.thrust[0]))
|
||||
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->data.thrust[1]));
|
||||
}
|
||||
}
|
||||
|
||||
/// \todo store the current weapon health somewhere
|
||||
if (ref->base->data.type < 11) // thrown weapons and arrows/bolts don't have health, only quantity
|
||||
text += "\n" + store.gameSettings.search("sCondition")->str + ": " + MWGui::ToolTips::toString(ref->base->data.health);
|
||||
|
||||
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.enchant = ref->base->enchant;
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner");
|
||||
text += MWGui::ToolTips::getMiscString(ref->base->script, "Script");
|
||||
}
|
||||
|
||||
info.text = text;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string Weapon::getEnchantment (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,12 @@ namespace MWClass
|
|||
const MWWorld::Ptr& actor) const;
|
||||
///< Generate action for activation
|
||||
|
||||
virtual bool hasToolTip (const MWWorld::Ptr& ptr) const;
|
||||
///< @return true if this object has a tooltip when focused (default implementation: false)
|
||||
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const;
|
||||
///< \return Item health data available?
|
||||
|
||||
|
@ -49,6 +55,17 @@ namespace MWClass
|
|||
|
||||
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
|
||||
///< Return the put down sound Id
|
||||
|
||||
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,20 @@ namespace
|
|||
return lowerCase;
|
||||
}
|
||||
|
||||
bool stringCompareNoCase (std::string first, std::string second)
|
||||
{
|
||||
unsigned int i=0;
|
||||
while ( (i<first.length()) && (i<second.length()) )
|
||||
{
|
||||
if (tolower(first[i])<tolower(second[i])) return true;
|
||||
else if (tolower(first[i])>tolower(second[i])) return false;
|
||||
++i;
|
||||
}
|
||||
if (first.length()<second.length())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
bool selectCompare (char comp, T1 value1, T2 value2)
|
||||
|
@ -147,6 +161,8 @@ namespace MWDialogue
|
|||
|
||||
bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice)
|
||||
{
|
||||
bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
|
||||
|
||||
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.selects.begin());
|
||||
iter != info.selects.end(); ++iter)
|
||||
{
|
||||
|
@ -181,13 +197,16 @@ namespace MWDialogue
|
|||
|
||||
case 46://Same faction
|
||||
{
|
||||
if (isCreature)
|
||||
return false;
|
||||
|
||||
MWMechanics::NpcStats PCstats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor);
|
||||
int sameFaction = 0;
|
||||
if(!NPCstats.mFactionRank.empty())
|
||||
{
|
||||
std::string NPCFaction = NPCstats.mFactionRank.begin()->first;
|
||||
if(PCstats.mFactionRank.find(NPCFaction) != PCstats.mFactionRank.end()) sameFaction = 1;
|
||||
if(PCstats.mFactionRank.find(toLower(NPCFaction)) != PCstats.mFactionRank.end()) sameFaction = 1;
|
||||
}
|
||||
if(!selectCompare<int,int>(comp,sameFaction,select.i)) return false;
|
||||
}
|
||||
|
@ -269,6 +288,8 @@ namespace MWDialogue
|
|||
bool DialogueManager::isMatching (const MWWorld::Ptr& actor,
|
||||
const ESM::DialInfo::SelectStruct& select) const
|
||||
{
|
||||
bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
|
||||
|
||||
char type = select.selectRule[1];
|
||||
|
||||
if (type!='0')
|
||||
|
@ -342,7 +363,7 @@ namespace MWDialogue
|
|||
int sum = 0;
|
||||
|
||||
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
|
||||
if (iter->getCellRef().refID==name)
|
||||
if (toLower(iter->getCellRef().refID) == toLower(name))
|
||||
sum += iter->getRefData().getCount();
|
||||
if(!selectCompare<int,int>(comp,sum,select.i)) return false;
|
||||
}
|
||||
|
@ -366,6 +387,9 @@ namespace MWDialogue
|
|||
return true;
|
||||
|
||||
case '8':// not faction
|
||||
if (isCreature)
|
||||
return false;
|
||||
|
||||
if(select.type==ESM::VT_Int)
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
||||
|
@ -380,6 +404,9 @@ namespace MWDialogue
|
|||
return true;
|
||||
|
||||
case '9':// not class
|
||||
if (isCreature)
|
||||
return false;
|
||||
|
||||
if(select.type==ESM::VT_Int)
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
||||
|
@ -394,6 +421,9 @@ namespace MWDialogue
|
|||
return true;
|
||||
|
||||
case 'A'://not Race
|
||||
if (isCreature)
|
||||
return false;
|
||||
|
||||
if(select.type==ESM::VT_Int)
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
||||
|
@ -450,6 +480,8 @@ namespace MWDialogue
|
|||
|
||||
bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const
|
||||
{
|
||||
bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
|
||||
|
||||
// actor id
|
||||
if (!info.actor.empty())
|
||||
if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
|
||||
|
@ -458,6 +490,9 @@ namespace MWDialogue
|
|||
//NPC race
|
||||
if (!info.race.empty())
|
||||
{
|
||||
if (isCreature)
|
||||
return false;
|
||||
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
|
||||
|
||||
if (!cellRef)
|
||||
|
@ -470,6 +505,9 @@ namespace MWDialogue
|
|||
//NPC class
|
||||
if (!info.clas.empty())
|
||||
{
|
||||
if (isCreature)
|
||||
return false;
|
||||
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
|
||||
|
||||
if (!cellRef)
|
||||
|
@ -482,9 +520,12 @@ namespace MWDialogue
|
|||
//NPC faction
|
||||
if (!info.npcFaction.empty())
|
||||
{
|
||||
if (isCreature)
|
||||
return false;
|
||||
|
||||
//MWWorld::Class npcClass = MWWorld::Class::get(actor);
|
||||
MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
|
||||
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.npcFaction);
|
||||
std::map<std::string,int>::iterator it = stats.mFactionRank.find(toLower(info.npcFaction));
|
||||
if(it!=stats.mFactionRank.end())
|
||||
{
|
||||
//check rank
|
||||
|
@ -501,7 +542,7 @@ namespace MWDialogue
|
|||
if(!info.pcFaction.empty())
|
||||
{
|
||||
MWMechanics::NpcStats stats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.pcFaction);
|
||||
std::map<std::string,int>::iterator it = stats.mFactionRank.find(toLower(info.pcFaction));
|
||||
if(it!=stats.mFactionRank.end())
|
||||
{
|
||||
//check rank
|
||||
|
@ -515,6 +556,8 @@ namespace MWDialogue
|
|||
}
|
||||
|
||||
//check gender
|
||||
if (!isCreature)
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
||||
if(npc->base->flags&npc->base->Female)
|
||||
{
|
||||
|
@ -524,7 +567,7 @@ namespace MWDialogue
|
|||
{
|
||||
if(static_cast<int> (info.data.gender)==1) return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check cell
|
||||
if (!info.cell.empty())
|
||||
|
@ -564,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)
|
||||
|
@ -592,9 +635,9 @@ namespace MWDialogue
|
|||
actorKnownTopics.clear();
|
||||
|
||||
//initialise the GUI
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Dialogue);
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue);
|
||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
||||
win->startDialogue(MWWorld::Class::get (actor).getName (actor));
|
||||
win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor));
|
||||
|
||||
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
|
||||
updateTopics();
|
||||
|
@ -723,7 +766,41 @@ namespace MWDialogue
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check the available services of this actor
|
||||
int services = 0;
|
||||
if (mActor.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mActor.get<ESM::NPC>();
|
||||
if (ref->base->hasAI)
|
||||
services = ref->base->AI.services;
|
||||
}
|
||||
else if (mActor.getTypeName() == typeid(ESM::Creature).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mActor.get<ESM::Creature>();
|
||||
if (ref->base->hasAI)
|
||||
services = ref->base->AI.services;
|
||||
}
|
||||
|
||||
if (services & ESM::NPC::Weapon
|
||||
|| services & ESM::NPC::Armor
|
||||
|| services & ESM::NPC::Clothing
|
||||
|| services & ESM::NPC::Books
|
||||
|| services & ESM::NPC::Ingredients
|
||||
|| services & ESM::NPC::Picks
|
||||
|| services & ESM::NPC::Probes
|
||||
|| services & ESM::NPC::Lights
|
||||
|| services & ESM::NPC::Apparatus
|
||||
|| services & ESM::NPC::RepairItem
|
||||
|| services & ESM::NPC::Misc)
|
||||
win->setShowTrade(true);
|
||||
else
|
||||
win->setShowTrade(false);
|
||||
|
||||
// sort again, because the previous sort was case-sensitive
|
||||
keywordList.sort(stringCompareNoCase);
|
||||
win->setKeywords(keywordList);
|
||||
|
||||
mChoice = choice;
|
||||
}
|
||||
|
||||
|
@ -766,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)
|
||||
|
@ -815,12 +892,15 @@ namespace MWDialogue
|
|||
{
|
||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
||||
win->askQuestion(question);
|
||||
mChoiceMap[question] = choice;
|
||||
mChoiceMap[toLower(question)] = choice;
|
||||
mIsInChoice = true;
|
||||
}
|
||||
|
||||
std::string DialogueManager::getFaction()
|
||||
{
|
||||
if (mActor.getTypeName() != typeid(ESM::NPC).name())
|
||||
return "";
|
||||
|
||||
std::string factionID("");
|
||||
MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
|
||||
if(stats.mFactionRank.empty())
|
||||
|
@ -833,4 +913,11 @@ namespace MWDialogue
|
|||
}
|
||||
return factionID;
|
||||
}
|
||||
|
||||
void DialogueManager::goodbye()
|
||||
{
|
||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
||||
|
||||
win->goodbye();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ namespace MWDialogue
|
|||
|
||||
void askQuestion(std::string question,int choice);
|
||||
|
||||
void goodbye();
|
||||
|
||||
///get the faction of the actor you are talking with
|
||||
std::string getFaction();
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/messagebox.hpp"
|
||||
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
namespace MWDialogue
|
||||
{
|
||||
Quest& Journal::getQuest (const std::string& id)
|
||||
|
@ -38,7 +40,7 @@ namespace MWDialogue
|
|||
quest.addEntry (entry, *MWBase::Environment::get().getWorld()); // we are doing slicing on purpose here
|
||||
|
||||
std::vector<std::string> empty;
|
||||
std::string notification = "Your Journal has been updated.";
|
||||
std::string notification = MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sJournalEntry")->str;
|
||||
MWBase::Environment::get().getWindowManager()->messageBox (notification, empty);
|
||||
}
|
||||
|
||||
|
|
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
|
|
@ -25,13 +25,13 @@ BirthDialog::BirthDialog(WindowManager& parWindowManager)
|
|||
birthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
|
||||
birthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked);
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
|
||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked);
|
||||
|
||||
updateBirths();
|
||||
|
@ -46,21 +46,16 @@ void BirthDialog::setNextButtonShow(bool shown)
|
|||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
|
||||
// TODO: All hardcoded coords for buttons are temporary, will be replaced with a dynamic system.
|
||||
if (shown)
|
||||
{
|
||||
okButton->setCaption("Next");
|
||||
|
||||
// Adjust back button when next is shown
|
||||
backButton->setCoord(MyGUI::IntCoord(375 - 18, 340, 53, 23));
|
||||
okButton->setCoord(MyGUI::IntCoord(431 - 18, 340, 42 + 18, 23));
|
||||
}
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sNext", ""));
|
||||
else
|
||||
{
|
||||
okButton->setCaption("OK");
|
||||
backButton->setCoord(MyGUI::IntCoord(375, 340, 53, 23));
|
||||
okButton->setCoord(MyGUI::IntCoord(431, 340, 42, 23));
|
||||
}
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
|
||||
|
||||
int okButtonWidth = okButton->getTextSize().width + 24;
|
||||
int backButtonWidth = backButton->getTextSize().width + 24;
|
||||
|
||||
okButton->setCoord(473 - okButtonWidth, 340, okButtonWidth, 23);
|
||||
backButton->setCoord(473 - okButtonWidth - backButtonWidth - 6, 340, backButtonWidth, 23);
|
||||
}
|
||||
|
||||
void BirthDialog::open()
|
||||
|
@ -206,7 +201,7 @@ void BirthDialog::updateSpells()
|
|||
|
||||
MyGUI::IntCoord spellCoord = coord;
|
||||
spellCoord.height = 24; // TODO: This should be fetched from the skin somehow, or perhaps a widget in the layout as a template?
|
||||
spellWidget->createEffectWidgets(spellItems, spellArea, spellCoord);
|
||||
spellWidget->createEffectWidgets(spellItems, spellArea, spellCoord, (category == 0) ? MWEffectList::EF_Constant : 0);
|
||||
coord.top = spellCoord.top;
|
||||
|
||||
++i;
|
||||
|
|
149
apps/openmw/mwgui/bookwindow.cpp
Normal file
149
apps/openmw/mwgui/bookwindow.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
#include "bookwindow.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "formatting.hpp"
|
||||
#include "window_manager.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
BookWindow::BookWindow (WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_book_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onCloseButtonClicked);
|
||||
|
||||
getWidget(mTakeButton, "TakeButton");
|
||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onTakeButtonClicked);
|
||||
|
||||
getWidget(mNextPageButton, "NextPageBTN");
|
||||
mNextPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onNextPageButtonClicked);
|
||||
|
||||
getWidget(mPrevPageButton, "PrevPageBTN");
|
||||
mPrevPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onPrevPageButtonClicked);
|
||||
|
||||
getWidget(mLeftPageNumber, "LeftPageNumber");
|
||||
getWidget(mRightPageNumber, "RightPageNumber");
|
||||
|
||||
getWidget(mLeftPage, "LeftPage");
|
||||
getWidget(mRightPage, "RightPage");
|
||||
|
||||
center();
|
||||
}
|
||||
|
||||
void BookWindow::clearPages()
|
||||
{
|
||||
for (std::vector<MyGUI::Widget*>::iterator it=mPages.begin();
|
||||
it!=mPages.end(); ++it)
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(*it);
|
||||
}
|
||||
mPages.clear();
|
||||
}
|
||||
|
||||
void BookWindow::open (MWWorld::Ptr book)
|
||||
{
|
||||
mBook = book;
|
||||
|
||||
clearPages();
|
||||
mCurrentPage = 0;
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
|
||||
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
mBook.get<ESM::Book>();
|
||||
|
||||
BookTextParser parser;
|
||||
std::vector<std::string> results = parser.split(ref->base->text, mLeftPage->getSize().width, mLeftPage->getSize().height);
|
||||
|
||||
int i=0;
|
||||
for (std::vector<std::string>::iterator it=results.begin();
|
||||
it!=results.end(); ++it)
|
||||
{
|
||||
MyGUI::Widget* parent;
|
||||
if (i%2 == 0)
|
||||
parent = mLeftPage;
|
||||
else
|
||||
parent = mRightPage;
|
||||
|
||||
MyGUI::Widget* pageWidget = parent->createWidgetReal<MyGUI::Widget>("", MyGUI::FloatCoord(0.0,0.0,1.0,1.0), MyGUI::Align::Default, "BookPage" + boost::lexical_cast<std::string>(i));
|
||||
parser.parse(*it, pageWidget, mLeftPage->getSize().width);
|
||||
mPages.push_back(pageWidget);
|
||||
++i;
|
||||
}
|
||||
|
||||
updatePages();
|
||||
|
||||
setTakeButtonShow(true);
|
||||
}
|
||||
|
||||
void BookWindow::setTakeButtonShow(bool show)
|
||||
{
|
||||
mTakeButton->setVisible(show);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
||||
|
||||
void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
|
||||
|
||||
MWWorld::ActionTake take(mBook);
|
||||
take.execute();
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
||||
|
||||
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
if ((mCurrentPage+1)*2 < mPages.size())
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0);
|
||||
|
||||
++mCurrentPage;
|
||||
|
||||
updatePages();
|
||||
}
|
||||
}
|
||||
|
||||
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mCurrentPage > 0)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0);
|
||||
|
||||
--mCurrentPage;
|
||||
|
||||
updatePages();
|
||||
}
|
||||
}
|
||||
|
||||
void BookWindow::updatePages()
|
||||
{
|
||||
mLeftPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 1) );
|
||||
mRightPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 2) );
|
||||
|
||||
unsigned int i=0;
|
||||
for (std::vector<MyGUI::Widget*>::iterator it = mPages.begin();
|
||||
it != mPages.end(); ++it)
|
||||
{
|
||||
if (mCurrentPage*2 == i || mCurrentPage*2+1 == i)
|
||||
(*it)->setVisible(true);
|
||||
else
|
||||
{
|
||||
(*it)->setVisible(false);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
46
apps/openmw/mwgui/bookwindow.hpp
Normal file
46
apps/openmw/mwgui/bookwindow.hpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef MWGUI_BOOKWINDOW_H
|
||||
#define MWGUI_BOOKWINDOW_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class BookWindow : public WindowBase
|
||||
{
|
||||
public:
|
||||
BookWindow(WindowManager& parWindowManager);
|
||||
|
||||
void open(MWWorld::Ptr book);
|
||||
void setTakeButtonShow(bool show);
|
||||
|
||||
protected:
|
||||
void onNextPageButtonClicked (MyGUI::Widget* _sender);
|
||||
void onPrevPageButtonClicked (MyGUI::Widget* _sender);
|
||||
void onCloseButtonClicked (MyGUI::Widget* _sender);
|
||||
void onTakeButtonClicked (MyGUI::Widget* _sender);
|
||||
|
||||
void updatePages();
|
||||
void clearPages();
|
||||
|
||||
private:
|
||||
MyGUI::Button* mCloseButton;
|
||||
MyGUI::Button* mTakeButton;
|
||||
MyGUI::Button* mNextPageButton;
|
||||
MyGUI::Button* mPrevPageButton;
|
||||
MyGUI::TextBox* mLeftPageNumber;
|
||||
MyGUI::TextBox* mRightPageNumber;
|
||||
MyGUI::Widget* mLeftPage;
|
||||
MyGUI::Widget* mRightPage;
|
||||
|
||||
unsigned int mCurrentPage; // 0 is first page
|
||||
std::vector<MyGUI::Widget*> mPages;
|
||||
|
||||
MWWorld::Ptr mBook;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#include "mode.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -16,6 +17,7 @@ namespace
|
|||
{
|
||||
const char* mText;
|
||||
const char* mButtons[3];
|
||||
const char* mSound;
|
||||
ESM::Class::Specialization mSpecializations[3]; // The specialization for each answer
|
||||
};
|
||||
|
||||
|
@ -25,6 +27,7 @@ namespace
|
|||
{"Draw your dagger, mercifully endings its life with a single thrust.",
|
||||
"Use herbs from your pack to put it to sleep.",
|
||||
"Do not interfere in the natural evolution of events, but rather take the opportunity to learn more about a strange animal that you have never seen before."},
|
||||
"vo\\misc\\chargen qa1.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
},
|
||||
// Question 2
|
||||
|
@ -32,6 +35,7 @@ namespace
|
|||
{"Work in the forge with him casting iron for a new plow.",
|
||||
"Gather herbs for your mother who is preparing dinner.",
|
||||
"Go catch fish at the stream using a net and line."},
|
||||
"vo\\misc\\chargen qa2.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
},
|
||||
// Question 3
|
||||
|
@ -39,6 +43,7 @@ namespace
|
|||
{"Beat up your cousin, then tell him that if he ever calls you that nickname again, you will bloody him worse than this time.",
|
||||
"Make up a story that makes your nickname a badge of honor instead of something humiliating.",
|
||||
"Make up an even more embarrassing nickname for him and use it constantly until he learns his lesson."},
|
||||
"vo\\misc\\chargen qa3.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
},
|
||||
// Question 4
|
||||
|
@ -46,6 +51,7 @@ namespace
|
|||
{"This is a terrible practice. A person's thoughts are his own and no one, not even a king, has the right to make such an invasion into another human's mind.",
|
||||
"Loyal followers to the king have nothing to fear from a Telepath. It is important to have a method of finding assassins and spies before it is too late.",
|
||||
"In these times, it is a necessary evil. Although you do not necessarily like the idea, a Telepath could have certain advantages during a time of war or in finding someone innocent of a crime."},
|
||||
"vo\\misc\\chargen qa4.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
},
|
||||
// Question 5
|
||||
|
@ -53,6 +59,7 @@ namespace
|
|||
{"Return to the store and give the shopkeeper his hard-earned money, explaining to him the mistake?",
|
||||
"Decide to put the extra money to good use and purchase items that would help your family?",
|
||||
"Pocket the extra money, knowing that shopkeepers in general tend to overcharge customers anyway?"},
|
||||
"vo\\misc\\chargen qa5.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
},
|
||||
// Question 6
|
||||
|
@ -60,6 +67,7 @@ namespace
|
|||
{"Pick up the bag and signal to the guard, knowing that the only honorable thing to do is return the money to its rightful owner.",
|
||||
"Leave the bag there, knowing that it is better not to get involved.",
|
||||
"Pick up the bag and pocket it, knowing that the extra windfall will help your family in times of trouble."},
|
||||
"vo\\misc\\chargen qa6.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
},
|
||||
// Question 7
|
||||
|
@ -67,6 +75,7 @@ namespace
|
|||
{"Decline his offer, knowing that your father expects you to do the work, and it is better not to be in debt.",
|
||||
"Ask him to help you, knowing that two people can do the job faster than one, and agree to help him with one task of his choosing in the future.",
|
||||
"Accept his offer, reasoning that as long as the stables are cleaned, it matters not who does the cleaning."},
|
||||
"vo\\misc\\chargen qa7.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
},
|
||||
// Question 8
|
||||
|
@ -74,6 +83,7 @@ namespace
|
|||
{"Position yourself between the pipe and your mother.",
|
||||
"Grab the hot pipe and try to push it away.",
|
||||
"Push your mother out of the way."},
|
||||
"vo\\misc\\chargen qa8.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
},
|
||||
// Question 9
|
||||
|
@ -81,6 +91,7 @@ namespace
|
|||
{"Drop the sweetroll and step on it, then get ready for the fight.",
|
||||
"Give him the sweetroll now without argument, knowing that later this afternoon you will have all your friends with you and can come and take whatever he owes you.",
|
||||
"Act like you're going to give him the sweetroll, but at the last minute throw it in the air, hoping that they'll pay attention to it long enough for you to get a shot in on the leader."},
|
||||
"vo\\misc\\chargen qa9.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
},
|
||||
// Question 10
|
||||
|
@ -88,6 +99,7 @@ namespace
|
|||
{"Rush to the town's aid immediately, despite your lack of knowledge of the circumstances.",
|
||||
"Stand aside and allow the man and the mob to pass, realizing it is probably best not to get involved.",
|
||||
"Rush to the man's aid immediately, despite your lack of knowledge of the circumstances."},
|
||||
"vo\\misc\\chargen qa10.wav",
|
||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||
}
|
||||
} };
|
||||
|
@ -98,7 +110,6 @@ using namespace MWGui;
|
|||
CharacterCreation::CharacterCreation(WindowManager* _wm)
|
||||
: mNameDialog(0)
|
||||
, mRaceDialog(0)
|
||||
, mDialogueWindow(0)
|
||||
, mClassChoiceDialog(0)
|
||||
, mGenerateClassQuestionDialog(0)
|
||||
, mGenerateClassResultDialog(0)
|
||||
|
@ -106,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)
|
||||
|
@ -161,7 +223,6 @@ void CharacterCreation::spawnDialog(const char id)
|
|||
mWM->removeDialog(mBirthSignDialog);
|
||||
mBirthSignDialog = new BirthDialog(*mWM);
|
||||
mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen);
|
||||
mBirthSignDialog->setBirthId(mPlayerBirthSignId);
|
||||
mBirthSignDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogDone);
|
||||
mBirthSignDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogBack);
|
||||
mBirthSignDialog->open();
|
||||
|
@ -171,6 +232,7 @@ void CharacterCreation::spawnDialog(const char id)
|
|||
if (mCreateClassDialog)
|
||||
mWM->removeDialog(mCreateClassDialog);
|
||||
mCreateClassDialog = new CreateClassDialog(*mWM);
|
||||
mCreateClassDialog->setNextButtonShow(mCreationStage >= CSE_ClassChosen);
|
||||
mCreateClassDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogDone);
|
||||
mCreateClassDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogBack);
|
||||
mCreateClassDialog->open();
|
||||
|
@ -197,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);
|
||||
|
@ -241,7 +305,7 @@ void CharacterCreation::onReviewDialogDone(WindowBase* parWindow)
|
|||
if (mReviewDialog)
|
||||
mWM->removeDialog(mReviewDialog);
|
||||
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
|
||||
void CharacterCreation::onReviewDialogBack()
|
||||
|
@ -249,7 +313,7 @@ void CharacterCreation::onReviewDialogBack()
|
|||
if (mReviewDialog)
|
||||
mWM->removeDialog(mReviewDialog);
|
||||
|
||||
mWM->setGuiMode(GM_Birth);
|
||||
mWM->pushGuiMode(GM_Birth);
|
||||
}
|
||||
|
||||
void CharacterCreation::onReviewActivateDialog(int parDialog)
|
||||
|
@ -258,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);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -292,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,7 +384,8 @@ void CharacterCreation::onPickClassDialogBack()
|
|||
mWM->removeDialog(mPickClassDialog);
|
||||
}
|
||||
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
|
||||
void CharacterCreation::onClassChoice(int _index)
|
||||
|
@ -322,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;
|
||||
|
||||
};
|
||||
|
@ -351,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,7 +452,8 @@ void CharacterCreation::onRaceDialogBack()
|
|||
mWM->removeDialog(mRaceDialog);
|
||||
}
|
||||
|
||||
mWM->setGuiMode(GM_Name);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Name);
|
||||
}
|
||||
|
||||
void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
|
||||
|
@ -386,13 +468,19 @@ void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
|
|||
}
|
||||
|
||||
if (mCreationStage == CSE_ReviewNext)
|
||||
mWM->setGuiMode(GM_Review);
|
||||
else if(mCreationStage >= CSE_RaceChosen)
|
||||
mWM->setGuiMode(GM_Class);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Review);
|
||||
}
|
||||
else if (mCreationStage >= CSE_RaceChosen)
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCreationStage = CSE_RaceChosen;
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,18 +489,20 @@ void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
|
|||
if (mBirthSignDialog)
|
||||
{
|
||||
mPlayerBirthSignId = mBirthSignDialog->getBirthId();
|
||||
mWM->setBirthSign(mPlayerBirthSignId);
|
||||
if (!mPlayerBirthSignId.empty())
|
||||
MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mPlayerBirthSignId);
|
||||
mWM->removeDialog(mBirthSignDialog);
|
||||
}
|
||||
|
||||
if (mCreationStage >= CSE_BirthSignChosen)
|
||||
mWM->setGuiMode(GM_Review);
|
||||
{
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Review);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCreationStage = CSE_BirthSignChosen;
|
||||
mWM->setGuiMode(GM_Game);
|
||||
mWM->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -424,7 +514,8 @@ void CharacterCreation::onBirthSignDialogBack()
|
|||
mWM->removeDialog(mBirthSignDialog);
|
||||
}
|
||||
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
|
||||
void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
|
||||
|
@ -459,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,16 +571,20 @@ void CharacterCreation::onCreateClassDialogBack()
|
|||
if (mCreateClassDialog)
|
||||
mWM->removeDialog(mCreateClassDialog);
|
||||
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
}
|
||||
|
||||
void CharacterCreation::onClassQuestionChosen(int _index)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->stopSay();
|
||||
|
||||
if (mGenerateClassQuestionDialog)
|
||||
mWM->removeDialog(mGenerateClassQuestionDialog);
|
||||
if (_index < 0 || _index >= 3)
|
||||
{
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -568,7 +669,8 @@ void CharacterCreation::showClassQuestionDialog()
|
|||
|
||||
if (mGenerateClassStep > sGenerateClassSteps.size())
|
||||
{
|
||||
mWM->setGuiMode(GM_Class);
|
||||
mWM->popGuiMode();
|
||||
mWM->pushGuiMode(GM_Class);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -584,6 +686,8 @@ void CharacterCreation::showClassQuestionDialog()
|
|||
mGenerateClassQuestionDialog->setButtons(buttons);
|
||||
mGenerateClassQuestionDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen);
|
||||
mGenerateClassQuestionDialog->open();
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->say(sGenerateClassSteps[mGenerateClassStep].mSound);
|
||||
}
|
||||
|
||||
void CharacterCreation::onGenerateClassBack()
|
||||
|
@ -595,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)
|
||||
|
@ -605,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -619,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
|
||||
|
||||
|
@ -26,14 +29,19 @@ GenerateClassResultDialog::GenerateClassResultDialog(WindowManager& parWindowMan
|
|||
getWidget(classImage, "ClassImage");
|
||||
getWidget(className, "ClassName");
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked);
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
|
||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked);
|
||||
|
||||
int okButtonWidth = okButton->getTextSize().width + 24;
|
||||
int backButtonWidth = backButton->getTextSize().width + 24;
|
||||
okButton->setCoord(315 - okButtonWidth, 219, okButtonWidth, 23);
|
||||
backButton->setCoord(315 - okButtonWidth - backButtonWidth - 6, 219, backButtonWidth, 23);
|
||||
}
|
||||
|
||||
void GenerateClassResultDialog::open()
|
||||
|
@ -74,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;
|
||||
|
@ -102,7 +106,6 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager)
|
|||
|
||||
getWidget(classImage, "ClassImage");
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked);
|
||||
|
@ -123,21 +126,16 @@ void PickClassDialog::setNextButtonShow(bool shown)
|
|||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
|
||||
// TODO: All hardcoded coords for buttons are temporary, will be replaced with a dynamic system.
|
||||
if (shown)
|
||||
{
|
||||
okButton->setCaption("Next");
|
||||
|
||||
// Adjust back button when next is shown
|
||||
backButton->setCoord(MyGUI::IntCoord(382 - 18, 265, 53, 23));
|
||||
okButton->setCoord(MyGUI::IntCoord(434 - 18, 265, 42 + 18, 23));
|
||||
}
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sNext", ""));
|
||||
else
|
||||
{
|
||||
okButton->setCaption("OK");
|
||||
backButton->setCoord(MyGUI::IntCoord(382, 265, 53, 23));
|
||||
okButton->setCoord(MyGUI::IntCoord(434, 265, 42, 23));
|
||||
}
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
|
||||
|
||||
int okButtonWidth = okButton->getTextSize().width + 24;
|
||||
int backButtonWidth = backButton->getTextSize().width + 24;
|
||||
|
||||
okButton->setCoord(476 - okButtonWidth, 265, okButtonWidth, 23);
|
||||
backButton->setCoord(476 - okButtonWidth - backButtonWidth - 6, 265, backButtonWidth, 23);
|
||||
}
|
||||
|
||||
void PickClassDialog::open()
|
||||
|
@ -232,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");
|
||||
|
@ -388,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:"));
|
||||
|
@ -423,9 +426,9 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
|
|||
// Make sure the edit box has focus
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(editName);
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
MyGUI::ButtonPtr descriptionButton;
|
||||
getWidget(descriptionButton, "DescriptionButton");
|
||||
descriptionButton->setCaption(mWindowManager.getGameSettingString("sCreateClassMenu1", ""));
|
||||
descriptionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionClicked);
|
||||
|
||||
MyGUI::ButtonPtr backButton;
|
||||
|
@ -452,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()
|
||||
|
@ -462,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();
|
||||
|
@ -500,39 +518,34 @@ 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;
|
||||
}
|
||||
|
||||
void CreateClassDialog::setNextButtonShow(bool shown)
|
||||
{
|
||||
MyGUI::ButtonPtr descriptionButton;
|
||||
getWidget(descriptionButton, "DescriptionButton");
|
||||
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
|
||||
// TODO: All hardcoded coords for buttons are temporary, will be replaced with a dynamic system.
|
||||
if (shown)
|
||||
{
|
||||
okButton->setCaption("Next");
|
||||
MyGUI::ButtonPtr descriptionButton;
|
||||
getWidget(descriptionButton, "DescriptionButton");
|
||||
|
||||
// Adjust back button when next is shown
|
||||
descriptionButton->setCoord(MyGUI::IntCoord(207 - 18, 158, 143, 23));
|
||||
backButton->setCoord(MyGUI::IntCoord(356 - 18, 158, 53, 23));
|
||||
okButton->setCoord(MyGUI::IntCoord(417 - 18, 158, 42 + 18, 23));
|
||||
}
|
||||
if (shown)
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sNext", ""));
|
||||
else
|
||||
{
|
||||
okButton->setCaption("OK");
|
||||
descriptionButton->setCoord(MyGUI::IntCoord(207, 158, 143, 23));
|
||||
backButton->setCoord(MyGUI::IntCoord(356, 158, 53, 23));
|
||||
okButton->setCoord(MyGUI::IntCoord(417, 158, 42, 23));
|
||||
}
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
|
||||
|
||||
int okButtonWidth = okButton->getTextSize().width + 24;
|
||||
int backButtonWidth = backButton->getTextSize().width + 24;
|
||||
int descriptionButtonWidth = descriptionButton->getTextSize().width + 24;
|
||||
|
||||
okButton->setCoord(459 - okButtonWidth, 158, okButtonWidth, 23);
|
||||
backButton->setCoord(459 - okButtonWidth - backButtonWidth - 6, 158, backButtonWidth, 23);
|
||||
descriptionButton->setCoord(459 - okButtonWidth - backButtonWidth - descriptionButtonWidth - 12, 158, descriptionButtonWidth, 23);
|
||||
}
|
||||
|
||||
void CreateClassDialog::open()
|
||||
|
@ -545,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);
|
||||
|
@ -568,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);
|
||||
|
@ -598,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);
|
||||
|
@ -631,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)
|
||||
|
@ -646,6 +687,7 @@ void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow)
|
|||
{
|
||||
description = descDialog->getTextInput();
|
||||
mWindowManager.removeDialog(descDialog);
|
||||
descDialog = 0;
|
||||
}
|
||||
|
||||
void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender)
|
||||
|
@ -671,19 +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;
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
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
|
||||
|
@ -726,13 +784,22 @@ 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());
|
||||
}
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
MyGUI::ButtonPtr cancelButton;
|
||||
getWidget(cancelButton, "CancelButton");
|
||||
cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", ""));
|
||||
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
|
||||
|
@ -814,14 +881,23 @@ 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());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
MyGUI::ButtonPtr cancelButton;
|
||||
getWidget(cancelButton, "CancelButton");
|
||||
cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", ""));
|
||||
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
|
||||
|
@ -847,14 +923,22 @@ DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager)
|
|||
|
||||
getWidget(textEdit, "TextEdit");
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked);
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sInputMenu1", ""));
|
||||
int buttonWidth = okButton->getTextSize().width + 24;
|
||||
okButton->setCoord(234 - buttonWidth, 214, buttonWidth, 24);
|
||||
|
||||
// Make sure the edit box has focus
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit);
|
||||
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
DescriptionDialog::~DescriptionDialog()
|
||||
{
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
|
||||
// widget controls
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace MWGui
|
|||
typedef delegates::CMultiDelegate1<int> EventHandle_Int;
|
||||
|
||||
/** Event : Button was clicked.\n
|
||||
signature : void method(MyGUI::WidgetPtr widget, int index)\n
|
||||
signature : void method(int index)\n
|
||||
*/
|
||||
EventHandle_Int eventButtonSelected;
|
||||
|
||||
|
@ -139,6 +139,7 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
SelectSpecializationDialog(WindowManager& parWindowManager);
|
||||
~SelectSpecializationDialog();
|
||||
|
||||
ESM::Class::Specialization getSpecializationId() const { return specializationId; }
|
||||
|
||||
|
@ -169,6 +170,7 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
SelectAttributeDialog(WindowManager& parWindowManager);
|
||||
~SelectAttributeDialog();
|
||||
|
||||
ESM::Attribute::AttributeID getAttributeId() const { return attributeId; }
|
||||
Widgets::MWAttributePtr getAffectedWidget() const { return affectedWidget; }
|
||||
|
@ -201,6 +203,7 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
SelectSkillDialog(WindowManager& parWindowManager);
|
||||
~SelectSkillDialog();
|
||||
|
||||
ESM::Skill::SkillEnum getSkillId() const { return skillId; }
|
||||
Widgets::MWSkillPtr getAffectedWidget() const { return affectedWidget; }
|
||||
|
@ -236,6 +239,7 @@ namespace MWGui
|
|||
{
|
||||
public:
|
||||
DescriptionDialog(WindowManager& parWindowManager);
|
||||
~DescriptionDialog();
|
||||
|
||||
std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; }
|
||||
void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); }
|
||||
|
@ -285,6 +289,10 @@ namespace MWGui
|
|||
void onDescriptionEntered(WindowBase* parWindow);
|
||||
void onDialogCancel();
|
||||
|
||||
void setSpecialization(int id);
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
MyGUI::EditPtr editName;
|
||||
MyGUI::TextBox* specializationName;
|
||||
|
|
70
apps/openmw/mwgui/confirmationdialog.cpp
Normal file
70
apps/openmw/mwgui/confirmationdialog.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "confirmationdialog.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
ConfirmationDialog::ConfirmationDialog(WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_confirmation_dialog_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mMessage, "Message");
|
||||
getWidget(mOkButton, "OkButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ConfirmationDialog::onCancelButtonClicked);
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ConfirmationDialog::onOkButtonClicked);
|
||||
}
|
||||
|
||||
void ConfirmationDialog::open(const std::string& message)
|
||||
{
|
||||
setVisible(true);
|
||||
|
||||
mMessage->setCaptionWithReplacing(message);
|
||||
|
||||
int height = mMessage->getTextSize().height + 72;
|
||||
|
||||
mMainWidget->setSize(mMainWidget->getWidth(), height);
|
||||
|
||||
mMessage->setSize(mMessage->getWidth(), mMessage->getTextSize().height+24);
|
||||
|
||||
center();
|
||||
|
||||
// make other gui elements inaccessible while this dialog is open
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
|
||||
int okButtonWidth = mOkButton->getTextSize().width + 24;
|
||||
mOkButton->setCoord(mMainWidget->getWidth() - 30 - okButtonWidth,
|
||||
mOkButton->getTop(),
|
||||
okButtonWidth,
|
||||
mOkButton->getHeight());
|
||||
|
||||
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
|
||||
mCancelButton->setCoord(mMainWidget->getWidth() - 30 - okButtonWidth - cancelButtonWidth - 8,
|
||||
mCancelButton->getTop(),
|
||||
cancelButtonWidth,
|
||||
mCancelButton->getHeight());
|
||||
}
|
||||
|
||||
void ConfirmationDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
eventCancelClicked();
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void ConfirmationDialog::onOkButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
eventOkClicked();
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void ConfirmationDialog::close()
|
||||
{
|
||||
setVisible(false);
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
}
|
35
apps/openmw/mwgui/confirmationdialog.hpp
Normal file
35
apps/openmw/mwgui/confirmationdialog.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef MWGUI_CONFIRMATIONDIALOG_H
|
||||
#define MWGUI_CONFIRMATIONDIALOG_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class ConfirmationDialog : public WindowBase
|
||||
{
|
||||
public:
|
||||
ConfirmationDialog(WindowManager& parWindowManager);
|
||||
void open(const std::string& message);
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
||||
|
||||
/** Event : Ok button was clicked.\n
|
||||
signature : void method()\n
|
||||
*/
|
||||
EventHandle_Void eventOkClicked;
|
||||
EventHandle_Void eventCancelClicked;
|
||||
|
||||
private:
|
||||
MyGUI::EditBox* mMessage;
|
||||
MyGUI::Button* mOkButton;
|
||||
MyGUI::Button* mCancelButton;
|
||||
|
||||
void onCancelButtonClicked(MyGUI::Widget* _sender);
|
||||
void onOkButtonClicked(MyGUI::Widget* _sender);
|
||||
|
||||
void close();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -138,6 +138,7 @@ namespace MWGui
|
|||
void Console::disable()
|
||||
{
|
||||
setVisible(false);
|
||||
setSelectedObject(MWWorld::Ptr());
|
||||
// Remove keyboard focus from the console input whenever the
|
||||
// console is turned off
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL);
|
||||
|
@ -240,7 +241,7 @@ namespace MWGui
|
|||
{
|
||||
try
|
||||
{
|
||||
ConsoleInterpreterContext interpreterContext (*this, MWWorld::Ptr());
|
||||
ConsoleInterpreterContext interpreterContext (*this, mPtr);
|
||||
Interpreter::Interpreter interpreter;
|
||||
MWScript::installOpcodes (interpreter);
|
||||
std::vector<Interpreter::Type_Code> code;
|
||||
|
@ -267,7 +268,7 @@ namespace MWGui
|
|||
/* Are there quotation marks? */
|
||||
if( tmp.find('"') != string::npos ) {
|
||||
int numquotes=0;
|
||||
for(string::iterator it=tmp.begin(); it < tmp.end(); it++) {
|
||||
for(string::iterator it=tmp.begin(); it < tmp.end(); ++it) {
|
||||
if( *it == '"' )
|
||||
numquotes++;
|
||||
}
|
||||
|
@ -310,7 +311,7 @@ namespace MWGui
|
|||
}
|
||||
|
||||
/* Iterate through the vector. */
|
||||
for(vector<string>::iterator it=mNames.begin(); it < mNames.end();it++) {
|
||||
for(vector<string>::iterator it=mNames.begin(); it < mNames.end();++it) {
|
||||
bool string_different=false;
|
||||
|
||||
/* Is the string shorter than the input string? If yes skip it. */
|
||||
|
@ -358,7 +359,7 @@ namespace MWGui
|
|||
int i = tmp.length();
|
||||
|
||||
for(string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) {
|
||||
for(vector<string>::iterator it=matches.begin(); it < matches.end();it++) {
|
||||
for(vector<string>::iterator it=matches.begin(); it < matches.end();++it) {
|
||||
if( tolower((*it)[i]) != tolower(*iter) ) {
|
||||
/* Append the longest match to the end of the output string*/
|
||||
output.append(matches.front().substr( 0, i));
|
||||
|
@ -370,4 +371,24 @@ namespace MWGui
|
|||
/* All keywords match with the shortest. Append it to the output string and return it. */
|
||||
return output.append(matches.front());
|
||||
}
|
||||
|
||||
void Console::onResChange(int width, int height)
|
||||
{
|
||||
setCoord(10,10, width-10, height/2);
|
||||
}
|
||||
|
||||
void Console::setSelectedObject(const MWWorld::Ptr& object)
|
||||
{
|
||||
mPtr = object;
|
||||
if (!mPtr.isEmpty())
|
||||
setTitle("#{sConsoleTitle} (" + mPtr.getCellRef().refID + ")");
|
||||
else
|
||||
setTitle("#{sConsoleTitle}");
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
||||
}
|
||||
|
||||
void Console::onReferenceUnavailable()
|
||||
{
|
||||
setSelectedObject(MWWorld::Ptr());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
#include "../mwscript/compilercontext.hpp"
|
||||
#include "../mwscript/interpretercontext.hpp"
|
||||
|
||||
#include "referenceinterface.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler
|
||||
class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler, public ReferenceInterface
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -39,6 +41,16 @@ namespace MWGui
|
|||
/// \note The list may contain duplicates (if a name is a keyword and an identifier at the same
|
||||
/// time).
|
||||
|
||||
public:
|
||||
|
||||
void setSelectedObject(const MWWorld::Ptr& object);
|
||||
///< Set the implicit object for script execution
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
|
||||
|
||||
public:
|
||||
MyGUI::EditPtr command;
|
||||
MyGUI::EditPtr history;
|
||||
|
@ -58,6 +70,8 @@ namespace MWGui
|
|||
|
||||
void setFont(const std::string &fntName);
|
||||
|
||||
void onResChange(int width, int height);
|
||||
|
||||
void clearHistory();
|
||||
|
||||
// Print a message to the console. Messages may contain color
|
||||
|
|
681
apps/openmw/mwgui/container.cpp
Normal file
681
apps/openmw/mwgui/container.cpp
Normal file
|
@ -0,0 +1,681 @@
|
|||
#include "container.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "countdialog.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace Widgets;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
bool compareType(std::string type1, std::string type2)
|
||||
{
|
||||
// this defines the sorting order of types. types that are first in the vector, appear before other types.
|
||||
std::vector<std::string> mapping;
|
||||
mapping.push_back( typeid(ESM::Weapon).name() );
|
||||
mapping.push_back( typeid(ESM::Armor).name() );
|
||||
mapping.push_back( typeid(ESM::Clothing).name() );
|
||||
mapping.push_back( typeid(ESM::Potion).name() );
|
||||
mapping.push_back( typeid(ESM::Ingredient).name() );
|
||||
mapping.push_back( typeid(ESM::Apparatus).name() );
|
||||
mapping.push_back( typeid(ESM::Book).name() );
|
||||
mapping.push_back( typeid(ESM::Light).name() );
|
||||
mapping.push_back( typeid(ESM::Miscellaneous).name() );
|
||||
mapping.push_back( typeid(ESM::Tool).name() );
|
||||
mapping.push_back( typeid(ESM::Repair).name() );
|
||||
mapping.push_back( typeid(ESM::Probe).name() );
|
||||
|
||||
assert( std::find(mapping.begin(), mapping.end(), type1) != mapping.end() );
|
||||
assert( std::find(mapping.begin(), mapping.end(), type2) != mapping.end() );
|
||||
|
||||
return std::find(mapping.begin(), mapping.end(), type1) < std::find(mapping.begin(), mapping.end(), type2);
|
||||
}
|
||||
|
||||
bool sortItems(MWWorld::Ptr left, MWWorld::Ptr right)
|
||||
{
|
||||
if (left.getTypeName() == right.getTypeName())
|
||||
{
|
||||
int cmp = MWWorld::Class::get(left).getName(left).compare(
|
||||
MWWorld::Class::get(right).getName(right));
|
||||
return cmp < 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return compareType(left.getTypeName(), right.getTypeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ContainerBase::ContainerBase(DragAndDrop* dragAndDrop) :
|
||||
mDragAndDrop(dragAndDrop),
|
||||
mFilter(ContainerBase::Filter_All)
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerBase::setWidgets(Widget* containerWidget, ScrollView* itemView)
|
||||
{
|
||||
mContainerWidget = containerWidget;
|
||||
mItemView = itemView;
|
||||
|
||||
mContainerWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onContainerClicked);
|
||||
mContainerWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerWindow::onMouseWheel);
|
||||
}
|
||||
|
||||
ContainerBase::~ContainerBase()
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
|
||||
{
|
||||
mSelectedItem = _sender;
|
||||
|
||||
if (mDragAndDrop && !isTrading())
|
||||
{
|
||||
if(!mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
|
||||
int count = object.getRefData().getCount();
|
||||
|
||||
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
|
||||
{
|
||||
startDragItem(_sender, count);
|
||||
}
|
||||
else if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
{
|
||||
startDragItem(_sender, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string message = MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTake")->str;
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::startDragItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
onContainerClicked(mContainerWidget);
|
||||
}
|
||||
else if (isTrading())
|
||||
{
|
||||
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
|
||||
int count = object.getRefData().getCount();
|
||||
|
||||
if (isInventory())
|
||||
{
|
||||
// the player is trying to sell an item, check if the merchant accepts it
|
||||
// also, don't allow selling gold (let's be better than Morrowind at this, can we?)
|
||||
if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object)
|
||||
|| MWWorld::Class::get(object).getName(object) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
|
||||
{
|
||||
// user notification "i don't buy this item"
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog4")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool buying = isTradeWindow(); // buying or selling?
|
||||
std::string message = buying ? MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage02")->str
|
||||
: MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage01")->str;
|
||||
|
||||
if (std::find(mBoughtItems.begin(), mBoughtItems.end(), object) != mBoughtItems.end())
|
||||
{
|
||||
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
|
||||
{
|
||||
sellAlreadyBoughtItem(NULL, count);
|
||||
}
|
||||
else if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
{
|
||||
sellAlreadyBoughtItem(NULL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellAlreadyBoughtItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
|
||||
{
|
||||
sellItem(NULL, count);
|
||||
}
|
||||
else if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
{
|
||||
sellItem(NULL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onSelectedItemImpl(*_sender->getUserData<MWWorld::Ptr>());
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
|
||||
{
|
||||
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
|
||||
|
||||
if (isInventory())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
}
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::sellItem(MyGUI::Widget* _sender, int count)
|
||||
{
|
||||
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
|
||||
|
||||
if (isInventory())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addBarteredItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addBarteredItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
}
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::startDragItem(MyGUI::Widget* _sender, int count)
|
||||
{
|
||||
mDragAndDrop->mIsOnDragAndDrop = true;
|
||||
mSelectedItem->detachFromWidget();
|
||||
mSelectedItem->attachToWidget(mDragAndDrop->mDragAndDropWidget);
|
||||
|
||||
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
|
||||
_unequipItem(object);
|
||||
|
||||
mDragAndDrop->mDraggedCount = count;
|
||||
|
||||
mDragAndDrop->mDraggedFrom = this;
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
mDragAndDrop->mDraggedWidget = mSelectedItem;
|
||||
static_cast<MyGUI::ImageBox*>(mSelectedItem)->setImageTexture(""); // remove the background texture (not visible during drag)
|
||||
static_cast<MyGUI::TextBox*>(mSelectedItem->getChildAt(0)->getChildAt(0))->setCaption(
|
||||
getCountString(mDragAndDrop->mDraggedCount));
|
||||
|
||||
drawItems();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(true);
|
||||
}
|
||||
|
||||
void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mDragAndDrop == NULL) return;
|
||||
|
||||
if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
|
||||
{
|
||||
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
{
|
||||
assert(object.getContainerStore() && "Item is not in a container!");
|
||||
|
||||
// check the container's Organic flag (if this is a container). container with Organic flag doesn't allow putting items inside
|
||||
if (mPtr.getTypeName() == typeid(ESM::Container).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mPtr.get<ESM::Container>();
|
||||
if (ref->base->flags & ESM::Container::Organic)
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage2")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int origCount = object.getRefData().getCount();
|
||||
|
||||
// check that we don't exceed the allowed weight (only for containers, not for inventory)
|
||||
if (!isInventory())
|
||||
{
|
||||
float capacity = MWWorld::Class::get(mPtr).getCapacity(mPtr);
|
||||
|
||||
// try adding the item, and if weight is exceeded, just remove it again.
|
||||
object.getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
MWWorld::ContainerStoreIterator it = containerStore.add(object);
|
||||
|
||||
float curWeight = MWWorld::Class::get(mPtr).getEncumbrance(mPtr);
|
||||
if (curWeight > capacity)
|
||||
{
|
||||
it->getRefData().setCount(0);
|
||||
object.getRefData().setCount(origCount);
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage3")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
std::cout << "container weight " << curWeight << "/" << capacity << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
object.getRefData().setCount (mDragAndDrop->mDraggedCount);
|
||||
containerStore.add(object);
|
||||
object.getRefData().setCount (origCount - mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
}
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
drawItems();
|
||||
mDragAndDrop->mDraggedFrom->drawItems();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (mItemView->getViewOffset().left + _rel*0.3 > 0)
|
||||
mItemView->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||
else
|
||||
mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0));
|
||||
}
|
||||
|
||||
void ContainerBase::setFilter(ContainerBase::Filter filter)
|
||||
{
|
||||
mFilter = filter;
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::openContainer(MWWorld::Ptr container)
|
||||
{
|
||||
mPtr = container;
|
||||
}
|
||||
|
||||
void ContainerBase::drawItems()
|
||||
{
|
||||
while (mContainerWidget->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0));
|
||||
}
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int maxHeight = mItemView->getSize().height - 58;
|
||||
|
||||
bool onlyMagic = false;
|
||||
int categories;
|
||||
if (mFilter == Filter_All)
|
||||
categories = MWWorld::ContainerStore::Type_All;
|
||||
else if (mFilter == Filter_Weapon)
|
||||
categories = MWWorld::ContainerStore::Type_Weapon;
|
||||
else if (mFilter == Filter_Apparel)
|
||||
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor;
|
||||
else if (mFilter == Filter_Magic)
|
||||
{
|
||||
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor
|
||||
+ MWWorld::ContainerStore::Type_Weapon + MWWorld::ContainerStore::Type_Book
|
||||
+ MWWorld::ContainerStore::Type_Potion;
|
||||
onlyMagic = true;
|
||||
}
|
||||
else if (mFilter == Filter_Misc)
|
||||
{
|
||||
categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book
|
||||
+ MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair
|
||||
+ MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light
|
||||
+ MWWorld::ContainerStore::Type_Apparatus + MWWorld::ContainerStore::Type_Probe;
|
||||
}
|
||||
else if (mFilter == Filter_Ingredients)
|
||||
categories = MWWorld::ContainerStore::Type_Ingredient;
|
||||
|
||||
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
|
||||
|
||||
std::vector< std::pair<MWWorld::Ptr, ItemState> > items;
|
||||
|
||||
std::vector<MWWorld::Ptr> equippedItems = getEquippedItems();
|
||||
|
||||
// add bought items (always at the beginning)
|
||||
std::vector<MWWorld::Ptr> boughtItems;
|
||||
for (MWWorld::ContainerStoreIterator it (mBoughtItems.begin()); it!=mBoughtItems.end(); ++it)
|
||||
{
|
||||
boughtItems.push_back(*it);
|
||||
}
|
||||
std::sort(boughtItems.begin(), boughtItems.end(), sortItems);
|
||||
|
||||
for (std::vector<MWWorld::Ptr>::iterator it=boughtItems.begin();
|
||||
it != boughtItems.end(); ++it)
|
||||
{
|
||||
items.push_back( std::make_pair(*it, ItemState_Barter) );
|
||||
}
|
||||
|
||||
// filter out the equipped items of categories we don't want
|
||||
std::vector<MWWorld::Ptr> unwantedItems = equippedItems;
|
||||
for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
|
||||
{
|
||||
std::vector<MWWorld::Ptr>::iterator found = std::find(unwantedItems.begin(), unwantedItems.end(), *iter);
|
||||
if (found != unwantedItems.end())
|
||||
{
|
||||
unwantedItems.erase(found);
|
||||
}
|
||||
}
|
||||
// now erase everything that's still in unwantedItems.
|
||||
for (std::vector<MWWorld::Ptr>::iterator it=unwantedItems.begin();
|
||||
it != unwantedItems.end(); ++it)
|
||||
{
|
||||
std::vector<MWWorld::Ptr>::iterator found = std::find(equippedItems.begin(), equippedItems.end(), *it);
|
||||
assert(found != equippedItems.end());
|
||||
equippedItems.erase(found);
|
||||
}
|
||||
// and add the items that are left (= have the correct category)
|
||||
if (!ignoreEquippedItems())
|
||||
{
|
||||
for (std::vector<MWWorld::Ptr>::const_iterator it=equippedItems.begin();
|
||||
it != equippedItems.end(); ++it)
|
||||
{
|
||||
items.push_back( std::make_pair(*it, ItemState_Equipped) );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> ignoreItems = itemsToIgnore();
|
||||
|
||||
// now add the regular items
|
||||
std::vector<MWWorld::Ptr> regularItems;
|
||||
for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
|
||||
{
|
||||
if (std::find(equippedItems.begin(), equippedItems.end(), *iter) == equippedItems.end()
|
||||
&& std::find(ignoreItems.begin(), ignoreItems.end(), *iter) == ignoreItems.end()
|
||||
&& std::find(mBoughtItems.begin(), mBoughtItems.end(), *iter) == mBoughtItems.end())
|
||||
regularItems.push_back(*iter);
|
||||
}
|
||||
|
||||
// sort them and add
|
||||
std::sort(regularItems.begin(), regularItems.end(), sortItems);
|
||||
for (std::vector<MWWorld::Ptr>::const_iterator it=regularItems.begin(); it!=regularItems.end(); ++it)
|
||||
{
|
||||
items.push_back( std::make_pair(*it, ItemState_Normal) );
|
||||
}
|
||||
|
||||
for (std::vector< std::pair<MWWorld::Ptr, ItemState> >::const_iterator it=items.begin();
|
||||
it != items.end(); ++it)
|
||||
{
|
||||
const MWWorld::Ptr* iter = &((*it).first);
|
||||
|
||||
int displayCount = iter->getRefData().getCount();
|
||||
if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>())
|
||||
{
|
||||
displayCount -= mDragAndDrop->mDraggedCount;
|
||||
}
|
||||
if(displayCount > 0 && !(onlyMagic && it->second != ItemState_Barter && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name()))
|
||||
{
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(*iter).getInventoryIcon(*iter);
|
||||
|
||||
// background widget (for the "equipped" frame and magic item background image)
|
||||
bool isMagic = (MWWorld::Class::get(*iter).getEnchantment(*iter) != "");
|
||||
MyGUI::ImageBox* backgroundWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
|
||||
backgroundWidget->setUserString("ToolTipType", "ItemPtr");
|
||||
backgroundWidget->setUserData(*iter);
|
||||
|
||||
std::string backgroundTex = "textures\\menu_icon";
|
||||
if (isMagic)
|
||||
backgroundTex += "_magic";
|
||||
if (it->second == ItemState_Normal)
|
||||
{
|
||||
if (!isMagic)
|
||||
backgroundTex = "";
|
||||
}
|
||||
else if (it->second == ItemState_Equipped)
|
||||
{
|
||||
backgroundTex += "_equip";
|
||||
}
|
||||
else if (it->second == ItemState_Barter)
|
||||
{
|
||||
backgroundTex += "_barter";
|
||||
}
|
||||
if (backgroundTex != "")
|
||||
backgroundTex += ".dds";
|
||||
|
||||
backgroundWidget->setImageTexture(backgroundTex);
|
||||
if (it->second == ItemState_Barter && !isMagic)
|
||||
backgroundWidget->setProperty("ImageCoord", "2 2 42 42");
|
||||
else
|
||||
backgroundWidget->setProperty("ImageCoord", "0 0 42 42");
|
||||
backgroundWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onSelectedItem);
|
||||
backgroundWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerBase::onMouseWheel);
|
||||
|
||||
// image
|
||||
ImageBox* image = backgroundWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
image->setImageTexture(path);
|
||||
image->setNeedMouseFocus(false);
|
||||
|
||||
// text widget that shows item count
|
||||
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
|
||||
text->setTextAlign(MyGUI::Align::Right);
|
||||
text->setNeedMouseFocus(false);
|
||||
text->setTextShadow(true);
|
||||
text->setTextShadowColour(MyGUI::Colour(0,0,0));
|
||||
text->setCaption(getCountString(displayCount));
|
||||
|
||||
y += 42;
|
||||
if (y > maxHeight)
|
||||
{
|
||||
x += 42;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
MyGUI::IntSize size = MyGUI::IntSize(std::max(mItemView->getSize().width, x+42), mItemView->getSize().height);
|
||||
mItemView->setCanvasSize(size);
|
||||
mContainerWidget->setSize(size);
|
||||
|
||||
notifyContentChanged();
|
||||
}
|
||||
|
||||
std::string ContainerBase::getCountString(const int count)
|
||||
{
|
||||
if (count == 1)
|
||||
return "";
|
||||
if (count > 9999)
|
||||
return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
|
||||
else
|
||||
return boost::lexical_cast<std::string>(count);
|
||||
}
|
||||
|
||||
void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
|
||||
{
|
||||
int origCount = item.getRefData().getCount();
|
||||
item.getRefData().setCount(count);
|
||||
MWWorld::ContainerStoreIterator it = mBoughtItems.add(item);
|
||||
item.getRefData().setCount(origCount - count);
|
||||
}
|
||||
|
||||
void ContainerBase::addItem(MWWorld::Ptr item, int count)
|
||||
{
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
int origCount = item.getRefData().getCount();
|
||||
|
||||
item.getRefData().setCount(count);
|
||||
MWWorld::ContainerStoreIterator it = containerStore.add(item);
|
||||
|
||||
item.getRefData().setCount(origCount - count);
|
||||
}
|
||||
|
||||
void ContainerBase::transferBoughtItems()
|
||||
{
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
|
||||
{
|
||||
containerStore.add(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
|
||||
{
|
||||
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
|
||||
{
|
||||
store.add(*it);
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::ContainerStore& ContainerBase::getContainerStore()
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
return store;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
ContainerWindow::ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)
|
||||
: ContainerBase(dragAndDrop)
|
||||
, WindowBase("openmw_container_window_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mTakeButton, "TakeButton");
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
|
||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
|
||||
|
||||
// adjust buttons size to fit text
|
||||
int closeButtonWidth = mCloseButton->getTextSize().width+24;
|
||||
int takeButtonWidth = mTakeButton->getTextSize().width+24;
|
||||
mCloseButton->setCoord(600-20-closeButtonWidth, mCloseButton->getCoord().top, closeButtonWidth, mCloseButton->getCoord().height);
|
||||
mTakeButton->setCoord(600-20-closeButtonWidth-takeButtonWidth-8, mTakeButton->getCoord().top, takeButtonWidth, mTakeButton->getCoord().height);
|
||||
|
||||
int w = MyGUI::RenderManager::getInstance().getViewSize().width;
|
||||
//int h = MyGUI::RenderManager::getInstance().getViewSize().height;
|
||||
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ContainerWindow::onWindowResize);
|
||||
|
||||
setCoord(w-600,0,600,300);
|
||||
}
|
||||
|
||||
ContainerWindow::~ContainerWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerWindow::onWindowResize(MyGUI::Window* window)
|
||||
{
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerWindow::open(MWWorld::Ptr container)
|
||||
{
|
||||
openContainer(container);
|
||||
setTitle(MWWorld::Class::get(container).getName(container));
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// transfer everything into the player's inventory
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);
|
||||
|
||||
int i=0;
|
||||
for (MWWorld::ContainerStoreIterator iter (containerStore.begin()); iter!=containerStore.end(); ++iter)
|
||||
{
|
||||
playerStore.add(*iter);
|
||||
|
||||
if (i==0)
|
||||
{
|
||||
// play the sound of the first object
|
||||
std::string sound = MWWorld::Class::get(*iter).getUpSoundId(*iter);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
containerStore.clear();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWindow::onReferenceUnavailable()
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
}
|
147
apps/openmw/mwgui/container.hpp
Normal file
147
apps/openmw/mwgui/container.hpp
Normal file
|
@ -0,0 +1,147 @@
|
|||
#ifndef MGUI_CONTAINER_H
|
||||
#define MGUI_CONTAINER_H
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "window_base.hpp"
|
||||
#include "referenceinterface.hpp"
|
||||
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Environment;
|
||||
}
|
||||
|
||||
namespace MyGUI
|
||||
{
|
||||
class Gui;
|
||||
class Widget;
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class WindowManager;
|
||||
class ContainerWindow;
|
||||
class ContainerBase;
|
||||
}
|
||||
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class DragAndDrop
|
||||
{
|
||||
public:
|
||||
bool mIsOnDragAndDrop;
|
||||
MyGUI::Widget* mDraggedWidget;
|
||||
MyGUI::Widget* mDragAndDropWidget;
|
||||
ContainerBase* mDraggedFrom;
|
||||
int mDraggedCount;
|
||||
};
|
||||
|
||||
class ContainerBase : public ReferenceInterface
|
||||
{
|
||||
public:
|
||||
ContainerBase(DragAndDrop* dragAndDrop);
|
||||
virtual ~ContainerBase();
|
||||
|
||||
enum Filter
|
||||
{
|
||||
Filter_All = 0x01,
|
||||
Filter_Weapon = 0x02,
|
||||
Filter_Apparel = 0x03,
|
||||
Filter_Magic = 0x04,
|
||||
Filter_Misc = 0x05,
|
||||
|
||||
Filter_Ingredients = 0x06
|
||||
};
|
||||
|
||||
enum ItemState
|
||||
{
|
||||
ItemState_Normal = 0x01,
|
||||
ItemState_Equipped = 0x02,
|
||||
ItemState_Barter = 0x03
|
||||
};
|
||||
|
||||
void setWidgets(MyGUI::Widget* containerWidget, MyGUI::ScrollView* itemView); ///< only call once
|
||||
|
||||
void addBarteredItem(MWWorld::Ptr item, int count);
|
||||
void addItem(MWWorld::Ptr item, int count);
|
||||
|
||||
void transferBoughtItems(); ///< transfer bought items into the inventory
|
||||
void returnBoughtItems(MWWorld::ContainerStore& store); ///< return bought items into the specified ContainerStore
|
||||
|
||||
MWWorld::ContainerStore& getContainerStore();
|
||||
MWWorld::ContainerStore& getBoughtItems() { return mBoughtItems; }
|
||||
|
||||
void openContainer(MWWorld::Ptr container);
|
||||
void setFilter(Filter filter); ///< set category filter
|
||||
void drawItems();
|
||||
|
||||
protected:
|
||||
MyGUI::ScrollView* mItemView;
|
||||
MyGUI::Widget* mContainerWidget;
|
||||
|
||||
MyGUI::Widget* mSelectedItem;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
Filter mFilter;
|
||||
|
||||
// bought items are put in a separate ContainerStore so that they don't stack with other (not bought) items.
|
||||
MWWorld::ContainerStore mBoughtItems;
|
||||
|
||||
void onSelectedItem(MyGUI::Widget* _sender);
|
||||
void onContainerClicked(MyGUI::Widget* _sender);
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
|
||||
/// start dragging an item (drag & drop)
|
||||
void startDragItem(MyGUI::Widget* _sender, int count);
|
||||
|
||||
/// sell an item from this container
|
||||
void sellItem(MyGUI::Widget* _sender, int count);
|
||||
|
||||
/// sell an item from this container, that was previously just bought
|
||||
void sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count);
|
||||
|
||||
std::string getCountString(const int count);
|
||||
|
||||
virtual bool isTradeWindow() { return false; }
|
||||
virtual bool isInventory() { return false; }
|
||||
virtual std::vector<MWWorld::Ptr> getEquippedItems() { return std::vector<MWWorld::Ptr>(); }
|
||||
virtual void _unequipItem(MWWorld::Ptr item) { ; }
|
||||
|
||||
virtual bool isTrading() { return false; }
|
||||
|
||||
virtual void onSelectedItemImpl(MWWorld::Ptr item) { ; }
|
||||
|
||||
virtual bool ignoreEquippedItems() { return false; }
|
||||
virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); }
|
||||
|
||||
virtual void notifyContentChanged() { ; }
|
||||
};
|
||||
|
||||
class ContainerWindow : public ContainerBase, public WindowBase
|
||||
{
|
||||
public:
|
||||
ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop);
|
||||
|
||||
virtual ~ContainerWindow();
|
||||
|
||||
void open(MWWorld::Ptr container);
|
||||
|
||||
protected:
|
||||
MyGUI::Button* mTakeButton;
|
||||
MyGUI::Button* mCloseButton;
|
||||
|
||||
void onWindowResize(MyGUI::Window* window);
|
||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
};
|
||||
}
|
||||
#endif // CONTAINER_H
|
108
apps/openmw/mwgui/countdialog.cpp
Normal file
108
apps/openmw/mwgui/countdialog.cpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
#include "countdialog.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
CountDialog::CountDialog(WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_count_window_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mSlider, "CountSlider");
|
||||
getWidget(mItemEdit, "ItemEdit");
|
||||
getWidget(mItemText, "ItemText");
|
||||
getWidget(mLabelText, "LabelText");
|
||||
getWidget(mOkButton, "OkButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked);
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked);
|
||||
mItemEdit->eventEditTextChange += MyGUI::newDelegate(this, &CountDialog::onEditTextChange);
|
||||
mSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &CountDialog::onSliderMoved);
|
||||
}
|
||||
|
||||
void CountDialog::open(const std::string& item, const std::string& message, const int maxCount)
|
||||
{
|
||||
setVisible(true);
|
||||
|
||||
mLabelText->setCaption(message);
|
||||
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
||||
mSlider->setScrollRange(maxCount);
|
||||
mItemText->setCaption(item);
|
||||
|
||||
int width = std::max(mItemText->getTextSize().width + 128, 320);
|
||||
setCoord(viewSize.width/2 - width/2,
|
||||
viewSize.height/2 - mMainWidget->getHeight()/2,
|
||||
width,
|
||||
mMainWidget->getHeight());
|
||||
|
||||
// make other gui elements inaccessible while this dialog is open
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit);
|
||||
|
||||
mSlider->setScrollPosition(maxCount-1);
|
||||
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));
|
||||
|
||||
int okButtonWidth = mOkButton->getTextSize().width + 24;
|
||||
mOkButton->setCoord(width - 30 - okButtonWidth,
|
||||
mOkButton->getTop(),
|
||||
okButtonWidth,
|
||||
mOkButton->getHeight());
|
||||
|
||||
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
|
||||
mCancelButton->setCoord(width - 30 - okButtonWidth - cancelButtonWidth - 8,
|
||||
mCancelButton->getTop(),
|
||||
cancelButtonWidth,
|
||||
mCancelButton->getHeight());
|
||||
}
|
||||
|
||||
void CountDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void CountDialog::onOkButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
eventOkClicked(NULL, mSlider->getScrollPosition()+1);
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void CountDialog::onEditTextChange(MyGUI::EditBox* _sender)
|
||||
{
|
||||
if (_sender->getCaption() == "")
|
||||
return;
|
||||
|
||||
unsigned int count;
|
||||
try
|
||||
{
|
||||
count = boost::lexical_cast<unsigned int>(_sender->getCaption());
|
||||
}
|
||||
catch (std::bad_cast&)
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
if (count > mSlider->getScrollRange())
|
||||
{
|
||||
count = mSlider->getScrollRange();
|
||||
}
|
||||
mSlider->setScrollPosition(count-1);
|
||||
onSliderMoved(mSlider, count-1);
|
||||
}
|
||||
|
||||
void CountDialog::onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position)
|
||||
{
|
||||
mItemEdit->setCaption(boost::lexical_cast<std::string>(_position+1));
|
||||
}
|
||||
|
||||
void CountDialog::close()
|
||||
{
|
||||
setVisible(false);
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
}
|
39
apps/openmw/mwgui/countdialog.hpp
Normal file
39
apps/openmw/mwgui/countdialog.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef MWGUI_COUNTDIALOG_H
|
||||
#define MWGUI_COUNTDIALOG_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class CountDialog : public WindowBase
|
||||
{
|
||||
public:
|
||||
CountDialog(WindowManager& parWindowManager);
|
||||
void open(const std::string& item, const std::string& message, const int maxCount);
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, int> EventHandle_WidgetInt;
|
||||
|
||||
/** Event : Ok button was clicked.\n
|
||||
signature : void method(MyGUI::Widget* _sender, int _count)\n
|
||||
*/
|
||||
EventHandle_WidgetInt eventOkClicked;
|
||||
|
||||
private:
|
||||
MyGUI::ScrollBar* mSlider;
|
||||
MyGUI::EditBox* mItemEdit;
|
||||
MyGUI::TextBox* mItemText;
|
||||
MyGUI::TextBox* mLabelText;
|
||||
MyGUI::Button* mOkButton;
|
||||
MyGUI::Button* mCancelButton;
|
||||
|
||||
void onCancelButtonClicked(MyGUI::Widget* _sender);
|
||||
void onOkButtonClicked(MyGUI::Widget* _sender);
|
||||
void onEditTextChange(MyGUI::EditBox* _sender);
|
||||
void onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position);
|
||||
|
||||
void close();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <openengine/ogre/imagerotate.hpp>
|
||||
#include <openengine/ogre/atlas.hpp>
|
||||
|
||||
#include <OgreResourceGroupManager.h>
|
||||
#include <OgreRoot.h>
|
||||
|
@ -13,4 +14,6 @@ CursorReplace::CursorReplace()
|
|||
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90);
|
||||
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize1.png", -45);
|
||||
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize2.png", 45);
|
||||
|
||||
OEngine::Render::Atlas::createFromFile("atlas1.cfg", "mwgui1", "textures\\");
|
||||
}
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
#include "dialogue.hpp"
|
||||
#include "dialogue_history.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "components/esm_store/store.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwdialogue/dialoguemanager.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
@ -13,6 +7,18 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwdialogue/dialoguemanager.hpp"
|
||||
|
||||
#include "dialogue_history.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "list.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace Widgets;
|
||||
|
||||
|
@ -38,6 +44,8 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su
|
|||
|
||||
DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
|
||||
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager)
|
||||
, mEnabled(true)
|
||||
, mShowTrade(false)
|
||||
{
|
||||
// Centre dialog
|
||||
center();
|
||||
|
@ -50,16 +58,13 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
|
|||
|
||||
//An EditBox cannot receive mouse click events, so we use an
|
||||
//invisible widget on top of the editbox to receive them
|
||||
/// \todo scrolling the dialogue history with the mouse wheel doesn't work using this solution
|
||||
getWidget(eventbox, "EventBox");
|
||||
eventbox->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked);
|
||||
eventbox->eventMouseWheel += MyGUI::newDelegate(this, &DialogueWindow::onMouseWheel);
|
||||
|
||||
//Topics list
|
||||
getWidget(topicsList, "TopicsList");
|
||||
topicsList->setScrollVisible(true);
|
||||
//topicsList->eventListSelectAccept += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
||||
topicsList->eventListMouseItemActivate += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
||||
//topicsList->eventListChangePosition += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
||||
topicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
||||
|
||||
MyGUI::ButtonPtr byeButton;
|
||||
getWidget(byeButton, "ByeButton");
|
||||
|
@ -67,6 +72,8 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
|
|||
|
||||
getWidget(pDispositionBar, "Disposition");
|
||||
getWidget(pDispositionText,"DispositionText");
|
||||
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
|
||||
}
|
||||
|
||||
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
|
||||
|
@ -79,22 +86,30 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
|
|||
|
||||
size_t cursorPosition = t->getCursorPosition(lastPressed);
|
||||
MyGUI::UString color = history->getColorAtPos(cursorPosition);
|
||||
|
||||
if (!mEnabled && color == "#572D21")
|
||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||
|
||||
if(color != "#B29154")
|
||||
{
|
||||
UString key = history->getColorTextAt(cursorPosition);
|
||||
if(color == "#686EBA") MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(key));
|
||||
|
||||
if(color == "#572D21") MWBase::Environment::get().getDialogueManager()->questionAnswered(key);
|
||||
if(color == "#572D21") MWBase::Environment::get().getDialogueManager()->questionAnswered(lower_string(key));
|
||||
}
|
||||
}
|
||||
|
||||
void DialogueWindow::open()
|
||||
void DialogueWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
{
|
||||
topicsList->removeAllItems();
|
||||
pTopicsText.clear();
|
||||
history->eraseText(0,history->getTextLength());
|
||||
updateOptions();
|
||||
setVisible(true);
|
||||
topicsList->adjustSize();
|
||||
}
|
||||
|
||||
void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (history->getVScrollPosition() - _rel*0.3 < 0)
|
||||
history->setVScrollPosition(0);
|
||||
else
|
||||
history->setVScrollPosition(history->getVScrollPosition() - _rel*0.3);
|
||||
}
|
||||
|
||||
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
|
||||
|
@ -102,36 +117,59 @@ void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
|
|||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||
}
|
||||
|
||||
void DialogueWindow::onSelectTopic(MyGUI::ListBox* _sender, size_t _index)
|
||||
void DialogueWindow::onSelectTopic(std::string topic)
|
||||
{
|
||||
if (_index == MyGUI::ITEM_NONE)
|
||||
return;
|
||||
std::string topic = _sender->getItemNameAt(_index);
|
||||
if (!mEnabled) return;
|
||||
|
||||
if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str)
|
||||
{
|
||||
/// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)?
|
||||
mWindowManager.pushGuiMode(GM_Barter);
|
||||
mWindowManager.getTradeWindow()->startTrade(mPtr);
|
||||
}
|
||||
|
||||
else
|
||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
|
||||
}
|
||||
|
||||
void DialogueWindow::startDialogue(std::string npcName)
|
||||
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
|
||||
{
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(npcName);
|
||||
adjustWindowCaption();
|
||||
mEnabled = true;
|
||||
mPtr = actor;
|
||||
topicsList->setEnabled(true);
|
||||
setTitle(npcName);
|
||||
|
||||
topicsList->clear();
|
||||
history->eraseText(0,history->getTextLength());
|
||||
updateOptions();
|
||||
}
|
||||
|
||||
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
|
||||
{
|
||||
topicsList->removeAllItems();
|
||||
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); it++)
|
||||
topicsList->clear();
|
||||
|
||||
bool anyService = mShowTrade;
|
||||
|
||||
if (mShowTrade)
|
||||
topicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str);
|
||||
|
||||
if (anyService)
|
||||
topicsList->addSeparator();
|
||||
|
||||
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
|
||||
{
|
||||
topicsList->addItem(*it);
|
||||
}
|
||||
topicsList->adjustSize();
|
||||
}
|
||||
|
||||
void DialogueWindow::removeKeyword(std::string keyWord)
|
||||
{
|
||||
if(topicsList->findItemIndexWith(keyWord) != MyGUI::ITEM_NONE)
|
||||
if(topicsList->hasItem(keyWord))
|
||||
{
|
||||
topicsList->removeItemAt(topicsList->findItemIndexWith(keyWord));
|
||||
pTopicsText.erase(keyWord);
|
||||
topicsList->removeItem(keyWord);
|
||||
}
|
||||
topicsList->adjustSize();
|
||||
}
|
||||
|
||||
void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2)
|
||||
|
@ -170,6 +208,7 @@ std::string DialogueWindow::parseText(std::string text)
|
|||
for(unsigned int i = 0;i<topicsList->getItemCount();i++)
|
||||
{
|
||||
std::string keyWord = topicsList->getItemNameAt(i);
|
||||
if (keyWord != "")
|
||||
addColorInString(text,keyWord,"#686EBA","#B29154");
|
||||
}
|
||||
return text;
|
||||
|
@ -203,8 +242,7 @@ void DialogueWindow::askQuestion(std::string question)
|
|||
void DialogueWindow::updateOptions()
|
||||
{
|
||||
//Clear the list of topics
|
||||
topicsList->removeAllItems();
|
||||
pTopicsText.clear();
|
||||
topicsList->clear();
|
||||
history->eraseText(0,history->getTextLength());
|
||||
|
||||
pDispositionBar->setProgressRange(100);
|
||||
|
@ -212,3 +250,15 @@ void DialogueWindow::updateOptions()
|
|||
pDispositionText->eraseText(0,pDispositionText->getTextLength());
|
||||
pDispositionText->addText("#B29154"+std::string("40/100")+"#B29154");
|
||||
}
|
||||
|
||||
void DialogueWindow::goodbye()
|
||||
{
|
||||
history->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->str);
|
||||
topicsList->setEnabled(false);
|
||||
mEnabled = false;
|
||||
}
|
||||
|
||||
void DialogueWindow::onReferenceUnavailable()
|
||||
{
|
||||
mWindowManager.removeGuiMode(GM_Dialogue);
|
||||
}
|
||||
|
|
|
@ -2,11 +2,19 @@
|
|||
#define MWGUI_DIALOGE_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
#include "referenceinterface.hpp"
|
||||
#include <boost/array.hpp>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class WindowManager;
|
||||
|
||||
namespace Widgets
|
||||
{
|
||||
class MWList;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -18,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;
|
||||
|
||||
|
@ -33,18 +39,27 @@ namespace MWGui
|
|||
*/
|
||||
EventHandle_Void eventBye;
|
||||
|
||||
void startDialogue(std::string npcName);
|
||||
void startDialogue(MWWorld::Ptr actor, std::string npcName);
|
||||
void stopDialogue();
|
||||
void setKeywords(std::list<std::string> keyWord);
|
||||
void removeKeyword(std::string keyWord);
|
||||
void addText(std::string text);
|
||||
void addTitle(std::string text);
|
||||
void askQuestion(std::string question);
|
||||
void goodbye();
|
||||
|
||||
// various service button visibilities, depending if the npc/creature talked to has these services
|
||||
// make sure to call these before setKeywords()
|
||||
void setShowTrade(bool show) { mShowTrade = show; }
|
||||
|
||||
protected:
|
||||
void onSelectTopic(MyGUI::ListBox* _sender, size_t _index);
|
||||
void onSelectTopic(std::string topic);
|
||||
void onByeClicked(MyGUI::Widget* _sender);
|
||||
void onHistoryClicked(MyGUI::Widget* _sender);
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
|
||||
private:
|
||||
void updateOptions();
|
||||
|
@ -53,11 +68,15 @@ namespace MWGui
|
|||
*/
|
||||
std::string parseText(std::string text);
|
||||
|
||||
// various service button visibilities, depending if the npc/creature talked to has these services
|
||||
bool mShowTrade;
|
||||
|
||||
bool mEnabled;
|
||||
|
||||
DialogueHistory* history;
|
||||
MyGUI::ListBox* topicsList;
|
||||
Widgets::MWList* topicsList;
|
||||
MyGUI::ProgressPtr pDispositionBar;
|
||||
MyGUI::EditPtr pDispositionText;
|
||||
std::map<std::string,std::string> pTopicsText;// this map links keyword and "real" text.
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
331
apps/openmw/mwgui/formatting.cpp
Normal file
331
apps/openmw/mwgui/formatting.cpp
Normal file
|
@ -0,0 +1,331 @@
|
|||
#include "formatting.hpp"
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
namespace
|
||||
{
|
||||
int convertFromHex(std::string hex)
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
int a = 0;
|
||||
int b = hex.length() - 1;
|
||||
for (; b >= 0; a++, b--)
|
||||
{
|
||||
if (hex[b] >= '0' && hex[b] <= '9')
|
||||
{
|
||||
value += (hex[b] - '0') * (1 << (a * 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (hex[b])
|
||||
{
|
||||
case 'A':
|
||||
case 'a':
|
||||
value += 10 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case 'b':
|
||||
value += 11 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'c':
|
||||
value += 12 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
value += 13 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
case 'e':
|
||||
value += 14 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
case 'f':
|
||||
value += 15 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error("invalid character in hex number");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> BookTextParser::split(std::string text, const int width, const int height)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
boost::algorithm::replace_all(text, "<BR>", "\n");
|
||||
boost::algorithm::replace_all(text, "<P>", "\n\n");
|
||||
|
||||
const int spacing = 48;
|
||||
|
||||
while (text.size() > 0)
|
||||
{
|
||||
// read in characters until we have exceeded the size, or run out of text
|
||||
int currentWidth = 0;
|
||||
int currentHeight = 0;
|
||||
std::string currentText;
|
||||
std::string currentWord;
|
||||
|
||||
unsigned int i=0;
|
||||
while (currentHeight <= height-spacing && i<text.size())
|
||||
{
|
||||
if (text[i] == '<')
|
||||
{
|
||||
if (text.find('>', i) == std::string::npos)
|
||||
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
||||
|
||||
if (text.size() > i+4 && text.substr(i, 4) == "<IMG")
|
||||
{
|
||||
int h = mHeight;
|
||||
parseImage(text.substr(i, text.find('>', i)-i), false);
|
||||
currentHeight += (mHeight-h);
|
||||
currentWidth = 0;
|
||||
}
|
||||
else if (text.size() > i+5 && text.substr(i, 5) == "<FONT")
|
||||
{
|
||||
parseFont(text.substr(i, text.find('>', i)-i));
|
||||
currentHeight += 18; // keep this in sync with the font size
|
||||
currentWidth = 0;
|
||||
}
|
||||
else if (text.size() > i+4 && text.substr(i, 4) == "<DIV")
|
||||
{
|
||||
parseDiv(text.substr(i, text.find('>', i)-i));
|
||||
currentHeight += 18; // keep this in sync with the font size
|
||||
currentWidth = 0;
|
||||
}
|
||||
|
||||
currentText += text.substr(i, text.find('>', i)-i+1);
|
||||
i = text.find('>', i);
|
||||
}
|
||||
else if (text[i] == '\n')
|
||||
{
|
||||
currentHeight += 18; // keep this in sync with the font size
|
||||
currentWidth = 0;
|
||||
currentWord = "";
|
||||
currentText += text[i];
|
||||
}
|
||||
else if (text[i] == ' ')
|
||||
{
|
||||
currentWidth += 3; // keep this in sync with the font's SpaceWidth property
|
||||
currentWord = "";
|
||||
currentText += text[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
currentWidth +=
|
||||
MyGUI::FontManager::getInstance().getByName (mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont)
|
||||
->getGlyphInfo(static_cast<unsigned int>(text[i]))->width;
|
||||
currentWord += text[i];
|
||||
currentText += text[i];
|
||||
}
|
||||
|
||||
if (currentWidth > width)
|
||||
{
|
||||
currentHeight += 18; // keep this in sync with the font size
|
||||
currentWidth = 0;
|
||||
|
||||
// add size of the current word
|
||||
unsigned int j=0;
|
||||
while (j<currentWord.size())
|
||||
{
|
||||
currentWidth +=
|
||||
MyGUI::FontManager::getInstance().getByName (mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont)
|
||||
->getGlyphInfo(static_cast<unsigned int>(currentWord[j]))->width;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
if (currentHeight > height-spacing)
|
||||
{
|
||||
// remove the last word
|
||||
currentText.erase(currentText.size()-currentWord.size(), currentText.size());
|
||||
}
|
||||
|
||||
result.push_back(currentText);
|
||||
text.erase(0, currentText.size());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, const int width)
|
||||
{
|
||||
mParent = parent;
|
||||
mWidth = width;
|
||||
mHeight = 0;
|
||||
|
||||
assert(mParent);
|
||||
while (mParent->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0));
|
||||
}
|
||||
|
||||
boost::algorithm::replace_all(text, "<BR>", "\n");
|
||||
boost::algorithm::replace_all(text, "<P>", "\n\n");
|
||||
|
||||
// remove leading newlines
|
||||
//while (text[0] == '\n')
|
||||
// text.erase(0);
|
||||
|
||||
// remove trailing "
|
||||
if (text[text.size()-1] == '\"')
|
||||
text.erase(text.size()-1);
|
||||
|
||||
parseSubText(text);
|
||||
return MyGUI::IntSize(mWidth, mHeight);
|
||||
}
|
||||
|
||||
void BookTextParser::parseImage(std::string tag, bool createWidget)
|
||||
{
|
||||
int src_start = tag.find("SRC=")+5;
|
||||
std::string image = tag.substr(src_start, tag.find('"', src_start)-src_start);
|
||||
|
||||
// fix texture extension to .dds
|
||||
if (image.size() > 4)
|
||||
{
|
||||
image[image.size()-3] = 'd';
|
||||
image[image.size()-2] = 'd';
|
||||
image[image.size()-1] = 's';
|
||||
}
|
||||
|
||||
int width_start = tag.find("WIDTH=")+7;
|
||||
int width = boost::lexical_cast<int>(tag.substr(width_start, tag.find('"', width_start)-width_start));
|
||||
|
||||
int height_start = tag.find("HEIGHT=")+8;
|
||||
int height = boost::lexical_cast<int>(tag.substr(height_start, tag.find('"', height_start)-height_start));
|
||||
|
||||
if (createWidget)
|
||||
{
|
||||
MyGUI::ImageBox* box = mParent->createWidget<MyGUI::ImageBox> ("ImageBox",
|
||||
MyGUI::IntCoord(0, mHeight, width, height), MyGUI::Align::Left | MyGUI::Align::Top,
|
||||
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
||||
box->setImageTexture("bookart\\" + image);
|
||||
box->setProperty("NeedMouse", "false");
|
||||
}
|
||||
|
||||
mWidth = std::max(mWidth, width);
|
||||
mHeight += height;
|
||||
}
|
||||
|
||||
void BookTextParser::parseDiv(std::string tag)
|
||||
{
|
||||
if (tag.find("ALIGN=") == std::string::npos)
|
||||
return;
|
||||
|
||||
int align_start = tag.find("ALIGN=")+7;
|
||||
std::string align = tag.substr(align_start, tag.find('"', align_start)-align_start);
|
||||
if (align == "CENTER")
|
||||
mTextStyle.mTextAlign = MyGUI::Align::HCenter;
|
||||
else if (align == "LEFT")
|
||||
mTextStyle.mTextAlign = MyGUI::Align::Left;
|
||||
}
|
||||
|
||||
void BookTextParser::parseFont(std::string tag)
|
||||
{
|
||||
if (tag.find("COLOR=") != std::string::npos)
|
||||
{
|
||||
int color_start = tag.find("COLOR=")+7;
|
||||
std::string color = tag.substr(color_start, tag.find('"', color_start)-color_start);
|
||||
|
||||
mTextStyle.mColour = MyGUI::Colour(
|
||||
convertFromHex(color.substr(0, 2))/255.0,
|
||||
convertFromHex(color.substr(2, 2))/255.0,
|
||||
convertFromHex(color.substr(4, 2))/255.0);
|
||||
}
|
||||
if (tag.find("FACE=") != std::string::npos)
|
||||
{
|
||||
int face_start = tag.find("FACE=")+6;
|
||||
std::string face = tag.substr(face_start, tag.find('"', face_start)-face_start);
|
||||
|
||||
if (face != "Magic Cards")
|
||||
mTextStyle.mFont = face;
|
||||
}
|
||||
if (tag.find("SIZE=") != std::string::npos)
|
||||
{
|
||||
/// \todo
|
||||
}
|
||||
}
|
||||
|
||||
void BookTextParser::parseSubText(std::string text)
|
||||
{
|
||||
if (text[0] == '<')
|
||||
{
|
||||
if (text.find('>') == std::string::npos)
|
||||
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
||||
|
||||
if (text.size() > 4 && text.substr(0, 4) == "<IMG")
|
||||
parseImage(text.substr(0, text.find('>')));
|
||||
else if (text.size() > 5 && text.substr(0, 5) == "<FONT")
|
||||
parseFont(text.substr(0, text.find('>')));
|
||||
else if (text.size() > 4 && text.substr(0, 4) == "<DIV")
|
||||
parseDiv(text.substr(0, text.find('>')));
|
||||
|
||||
text.erase(0, text.find('>')+1);
|
||||
}
|
||||
|
||||
bool tagFound = false;
|
||||
std::string realText; // real text, without tags
|
||||
unsigned int i=0;
|
||||
for (; i<text.size(); ++i)
|
||||
{
|
||||
char c = text[i];
|
||||
if (c == '<')
|
||||
{
|
||||
if (text[i+1] == '/') // ignore closing tags
|
||||
{
|
||||
while (c != '>')
|
||||
{
|
||||
if (i >= text.size())
|
||||
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
||||
++i;
|
||||
c = text[i];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
tagFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
realText += c;
|
||||
}
|
||||
|
||||
MyGUI::EditBox* box = mParent->createWidget<MyGUI::EditBox>("NormalText",
|
||||
MyGUI::IntCoord(0, mHeight, mWidth, 24), MyGUI::Align::Left | MyGUI::Align::Top,
|
||||
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
||||
box->setProperty("Static", "true");
|
||||
box->setProperty("MultiLine", "true");
|
||||
box->setProperty("WordWrap", "true");
|
||||
box->setProperty("NeedMouse", "false");
|
||||
box->setMaxTextLength(realText.size());
|
||||
box->setTextAlign(mTextStyle.mTextAlign);
|
||||
box->setTextColour(mTextStyle.mColour);
|
||||
box->setFontName(mTextStyle.mFont);
|
||||
box->setCaption(realText);
|
||||
box->setSize(box->getSize().width, box->getTextSize().height);
|
||||
mHeight += box->getTextSize().height;
|
||||
|
||||
if (tagFound)
|
||||
{
|
||||
parseSubText(text.substr(i, text.size()));
|
||||
}
|
||||
}
|
56
apps/openmw/mwgui/formatting.hpp
Normal file
56
apps/openmw/mwgui/formatting.hpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#ifndef MWGUI_FORMATTING_H
|
||||
#define MWGUI_FORMATTING_H
|
||||
|
||||
#include <MyGUI.h>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
struct TextStyle
|
||||
{
|
||||
TextStyle() :
|
||||
mColour(0,0,0)
|
||||
, mFont("Default")
|
||||
, mTextSize(16)
|
||||
, mTextAlign(MyGUI::Align::Left | MyGUI::Align::Top)
|
||||
{
|
||||
}
|
||||
|
||||
MyGUI::Colour mColour;
|
||||
std::string mFont;
|
||||
int mTextSize;
|
||||
MyGUI::Align mTextAlign;
|
||||
};
|
||||
|
||||
/// \brief utilities for parsing book/scroll text as mygui widgets
|
||||
class BookTextParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Parse markup as MyGUI widgets
|
||||
* @param markup to parse
|
||||
* @param parent for the created widgets
|
||||
* @param maximum width
|
||||
* @return size of the created widgets
|
||||
*/
|
||||
MyGUI::IntSize parse(std::string text, MyGUI::Widget* parent, const int width);
|
||||
|
||||
/**
|
||||
* Split the specified text into pieces that fit in the area specified by width and height parameters
|
||||
*/
|
||||
std::vector<std::string> split(std::string text, const int width, const int height);
|
||||
|
||||
protected:
|
||||
void parseSubText(std::string text);
|
||||
|
||||
void parseImage(std::string tag, bool createWidget=true);
|
||||
void parseDiv(std::string tag);
|
||||
void parseFont(std::string tag);
|
||||
private:
|
||||
MyGUI::Widget* mParent;
|
||||
int mWidth; // maximum width
|
||||
int mHeight; // current height
|
||||
TextStyle mTextStyle;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
516
apps/openmw/mwgui/hud.cpp
Normal file
516
apps/openmw/mwgui/hud.cpp
Normal file
|
@ -0,0 +1,516 @@
|
|||
#include "hud.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <MyGUI.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "container.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
|
||||
: Layout("openmw_hud_layout.xml")
|
||||
, health(NULL)
|
||||
, magicka(NULL)
|
||||
, stamina(NULL)
|
||||
, weapImage(NULL)
|
||||
, spellImage(NULL)
|
||||
, weapStatus(NULL)
|
||||
, spellStatus(NULL)
|
||||
, effectBox(NULL)
|
||||
, effect1(NULL)
|
||||
, minimap(NULL)
|
||||
, compass(NULL)
|
||||
, crosshair(NULL)
|
||||
, fpsbox(NULL)
|
||||
, fpscounter(NULL)
|
||||
, trianglecounter(NULL)
|
||||
, batchcounter(NULL)
|
||||
, hmsBaseLeft(0)
|
||||
, weapBoxBaseLeft(0)
|
||||
, spellBoxBaseLeft(0)
|
||||
, effectBoxBaseRight(0)
|
||||
, minimapBoxBaseRight(0)
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mCellNameTimer(0.0f)
|
||||
, mCellNameBox(NULL)
|
||||
, mMapVisible(true)
|
||||
, mWeaponVisible(true)
|
||||
, mSpellVisible(true)
|
||||
, mWorldMouseOver(false)
|
||||
{
|
||||
setCoord(0,0, width, height);
|
||||
|
||||
// Energy bars
|
||||
getWidget(mHealthFrame, "HealthFrame");
|
||||
getWidget(health, "Health");
|
||||
getWidget(magicka, "Magicka");
|
||||
getWidget(stamina, "Stamina");
|
||||
|
||||
hmsBaseLeft = mHealthFrame->getLeft();
|
||||
|
||||
MyGUI::Widget *healthFrame, *magickaFrame, *fatigueFrame;
|
||||
getWidget(healthFrame, "HealthFrame");
|
||||
getWidget(magickaFrame, "MagickaFrame");
|
||||
getWidget(fatigueFrame, "FatigueFrame");
|
||||
healthFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
|
||||
magickaFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
|
||||
fatigueFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
|
||||
|
||||
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
||||
// Item and spell images and status bars
|
||||
getWidget(weapBox, "WeapBox");
|
||||
getWidget(weapImage, "WeapImage");
|
||||
getWidget(weapStatus, "WeapStatus");
|
||||
weapBoxBaseLeft = weapBox->getLeft();
|
||||
weapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWeaponClicked);
|
||||
|
||||
getWidget(spellBox, "SpellBox");
|
||||
getWidget(spellImage, "SpellImage");
|
||||
getWidget(spellStatus, "SpellStatus");
|
||||
spellBoxBaseLeft = spellBox->getLeft();
|
||||
spellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
|
||||
|
||||
getWidget(effectBox, "EffectBox");
|
||||
getWidget(effect1, "Effect1");
|
||||
effectBoxBaseRight = viewSize.width - effectBox->getRight();
|
||||
effectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
|
||||
|
||||
getWidget(minimapBox, "MiniMapBox");
|
||||
minimapBoxBaseRight = viewSize.width - minimapBox->getRight();
|
||||
minimapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
|
||||
getWidget(minimap, "MiniMap");
|
||||
getWidget(compass, "Compass");
|
||||
|
||||
getWidget(mCellNameBox, "CellName");
|
||||
getWidget(mWeaponSpellBox, "WeaponSpellName");
|
||||
|
||||
getWidget(crosshair, "Crosshair");
|
||||
|
||||
setFpsLevel(fpsLevel);
|
||||
|
||||
getWidget(trianglecounter, "TriangleCounter");
|
||||
getWidget(batchcounter, "BatchCounter");
|
||||
|
||||
setEffect("icons\\s\\tx_s_chameleon.dds");
|
||||
|
||||
LocalMapBase::init(minimap, compass, this);
|
||||
|
||||
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
|
||||
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
|
||||
mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus);
|
||||
}
|
||||
|
||||
void HUD::setFpsLevel(int level)
|
||||
{
|
||||
fpscounter = 0;
|
||||
|
||||
MyGUI::Widget* fps;
|
||||
getWidget(fps, "FPSBoxAdv");
|
||||
fps->setVisible(false);
|
||||
getWidget(fps, "FPSBox");
|
||||
fps->setVisible(false);
|
||||
|
||||
if (level == 2)
|
||||
{
|
||||
getWidget(fpsbox, "FPSBoxAdv");
|
||||
fpsbox->setVisible(true);
|
||||
getWidget(fpscounter, "FPSCounterAdv");
|
||||
}
|
||||
else if (level == 1)
|
||||
{
|
||||
getWidget(fpsbox, "FPSBox");
|
||||
fpsbox->setVisible(true);
|
||||
getWidget(fpscounter, "FPSCounter");
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setFPS(float fps)
|
||||
{
|
||||
if (fpscounter)
|
||||
fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps));
|
||||
}
|
||||
|
||||
void HUD::setTriangleCount(size_t count)
|
||||
{
|
||||
trianglecounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||
}
|
||||
|
||||
void HUD::setBatchCount(size_t count)
|
||||
{
|
||||
batchcounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||
}
|
||||
|
||||
void HUD::setEffect(const char *img)
|
||||
{
|
||||
effect1->setImageTexture(img);
|
||||
}
|
||||
|
||||
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& value)
|
||||
{
|
||||
static const char *ids[] =
|
||||
{
|
||||
"HBar", "MBar", "FBar", 0
|
||||
};
|
||||
|
||||
for (int i=0; ids[i]; ++i)
|
||||
if (ids[i]==id)
|
||||
{
|
||||
MyGUI::Widget* w;
|
||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
health->setProgressRange (value.getModified());
|
||||
health->setProgressPosition (value.getCurrent());
|
||||
getWidget(w, "HealthFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||
break;
|
||||
case 1:
|
||||
magicka->setProgressRange (value.getModified());
|
||||
magicka->setProgressPosition (value.getCurrent());
|
||||
getWidget(w, "MagickaFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||
break;
|
||||
case 2:
|
||||
stamina->setProgressRange (value.getModified());
|
||||
stamina->setProgressPosition (value.getCurrent());
|
||||
getWidget(w, "FatigueFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible)
|
||||
{
|
||||
int weapDx = 0, spellDx = 0;
|
||||
if (!hmsVisible)
|
||||
spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft;
|
||||
|
||||
if (!weapVisible)
|
||||
spellDx += spellBoxBaseLeft - weapBoxBaseLeft;
|
||||
|
||||
mWeaponVisible = weapVisible;
|
||||
mSpellVisible = spellVisible;
|
||||
if (!mWeaponVisible && !mSpellVisible)
|
||||
mWeaponSpellBox->setVisible(false);
|
||||
|
||||
health->setVisible(hmsVisible);
|
||||
stamina->setVisible(hmsVisible);
|
||||
magicka->setVisible(hmsVisible);
|
||||
weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop());
|
||||
weapBox->setVisible(weapVisible);
|
||||
spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop());
|
||||
spellBox->setVisible(spellVisible);
|
||||
}
|
||||
|
||||
void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible)
|
||||
{
|
||||
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
||||
// effect box can have variable width -> variable left coordinate
|
||||
int effectsDx = 0;
|
||||
if (!minimapBoxVisible)
|
||||
effectsDx = (viewSize.width - minimapBoxBaseRight) - (viewSize.width - effectBoxBaseRight);
|
||||
|
||||
mMapVisible = minimapBoxVisible;
|
||||
minimapBox->setVisible(minimapBoxVisible);
|
||||
effectBox->setPosition((viewSize.width - effectBoxBaseRight) - effectBox->getWidth() + effectsDx, effectBox->getTop());
|
||||
effectBox->setVisible(effectBoxVisible);
|
||||
}
|
||||
|
||||
void HUD::onWorldClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// drop item into the gameworld
|
||||
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
|
||||
MWWorld::World* world = MWBase::Environment::get().getWorld();
|
||||
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
|
||||
float mouseX = cursorPosition.left / float(viewSize.width);
|
||||
float mouseY = cursorPosition.top / float(viewSize.height);
|
||||
|
||||
int origCount = object.getRefData().getCount();
|
||||
object.getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
|
||||
if (world->canPlaceObject(mouseX, mouseY))
|
||||
world->placeObject(object, mouseX, mouseY);
|
||||
else
|
||||
world->dropObjectOnGround(object);
|
||||
|
||||
MyGUI::PointerManager::getInstance().setPointer("arrow");
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
// remove object from the container it was coming from
|
||||
object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
mDragAndDrop->mDraggedWidget = 0;
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode();
|
||||
|
||||
if ( (mode != GM_Console) && (mode != GM_Container) && (mode != GM_Inventory) )
|
||||
return;
|
||||
|
||||
std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle();
|
||||
MWWorld::Ptr object;
|
||||
try
|
||||
{
|
||||
object = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == GM_Console)
|
||||
MWBase::Environment::get().getWindowManager()->getConsole()->setSelectedObject(object);
|
||||
else if ((mode == GM_Container) || (mode == GM_Inventory))
|
||||
{
|
||||
// pick up object
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
mWorldMouseOver = false;
|
||||
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
|
||||
float mouseX = cursorPosition.left / float(viewSize.width);
|
||||
float mouseY = cursorPosition.top / float(viewSize.height);
|
||||
|
||||
MWWorld::World* world = MWBase::Environment::get().getWorld();
|
||||
|
||||
// if we can't drop the object at the wanted position, show the "drop on ground" cursor.
|
||||
bool canDrop = world->canPlaceObject(mouseX, mouseY);
|
||||
|
||||
if (!canDrop)
|
||||
MyGUI::PointerManager::getInstance().setPointer("drop_ground");
|
||||
else
|
||||
MyGUI::PointerManager::getInstance().setPointer("arrow");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
MyGUI::PointerManager::getInstance().setPointer("arrow");
|
||||
mWorldMouseOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new)
|
||||
{
|
||||
MyGUI::PointerManager::getInstance().setPointer("arrow");
|
||||
mWorldMouseOver = false;
|
||||
}
|
||||
|
||||
void HUD::onHMSClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Stats);
|
||||
}
|
||||
|
||||
void HUD::onMapClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Map);
|
||||
}
|
||||
|
||||
void HUD::onWeaponClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Inventory);
|
||||
}
|
||||
|
||||
void HUD::onMagicClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Magic);
|
||||
}
|
||||
|
||||
void HUD::setCellName(const std::string& cellName)
|
||||
{
|
||||
if (mCellName != cellName)
|
||||
{
|
||||
mCellNameTimer = 5.0f;
|
||||
mCellName = cellName;
|
||||
|
||||
mCellNameBox->setCaption(mCellName);
|
||||
mCellNameBox->setVisible(mMapVisible);
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::onFrame(float dt)
|
||||
{
|
||||
mCellNameTimer -= dt;
|
||||
mWeaponSpellTimer -= dt;
|
||||
if (mCellNameTimer < 0)
|
||||
mCellNameBox->setVisible(false);
|
||||
if (mWeaponSpellTimer < 0)
|
||||
mWeaponSpellBox->setVisible(false);
|
||||
}
|
||||
|
||||
void HUD::onResChange(int width, int height)
|
||||
{
|
||||
setCoord(0, 0, width, height);
|
||||
}
|
||||
|
||||
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
|
||||
std::string spellName = spell->name;
|
||||
if (spellName != mSpellName && mSpellVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mSpellName = spellName;
|
||||
mWeaponSpellBox->setCaption(mSpellName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
spellStatus->setProgressRange(100);
|
||||
spellStatus->setProgressPosition(successChancePercent);
|
||||
|
||||
if (spellImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0));
|
||||
|
||||
spellBox->setUserString("ToolTipType", "Spell");
|
||||
spellBox->setUserString("Spell", spellId);
|
||||
|
||||
// use the icon of the first effect
|
||||
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(spell->effects.list.front().effectID);
|
||||
std::string icon = effect->icon;
|
||||
int slashPos = icon.find("\\");
|
||||
icon.insert(slashPos+1, "b_");
|
||||
icon = std::string("icons\\") + icon;
|
||||
Widgets::fixTexturePath(icon);
|
||||
spellImage->setImageTexture(icon);
|
||||
}
|
||||
|
||||
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
|
||||
{
|
||||
std::string itemName = MWWorld::Class::get(item).getName(item);
|
||||
if (itemName != mSpellName && mSpellVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mSpellName = itemName;
|
||||
mWeaponSpellBox->setCaption(mSpellName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
spellStatus->setProgressRange(100);
|
||||
spellStatus->setProgressPosition(chargePercent);
|
||||
|
||||
if (spellImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0));
|
||||
|
||||
spellBox->setUserString("ToolTipType", "ItemPtr");
|
||||
spellBox->setUserData(item);
|
||||
|
||||
spellImage->setImageTexture("textures\\menu_icon_magic_mini.dds");
|
||||
MyGUI::ImageBox* itemBox = spellImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
|
||||
, MyGUI::Align::Stretch);
|
||||
|
||||
std::string path = std::string("icons\\");
|
||||
path+=MWWorld::Class::get(item).getInventoryIcon(item);
|
||||
Widgets::fixTexturePath(path);
|
||||
itemBox->setImageTexture(path);
|
||||
itemBox->setNeedMouseFocus(false);
|
||||
}
|
||||
|
||||
void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
|
||||
{
|
||||
std::string itemName = MWWorld::Class::get(item).getName(item);
|
||||
if (itemName != mWeaponName && mWeaponVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mWeaponName = itemName;
|
||||
mWeaponSpellBox->setCaption(mWeaponName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
weapBox->setUserString("ToolTipType", "ItemPtr");
|
||||
weapBox->setUserData(item);
|
||||
|
||||
weapStatus->setProgressRange(100);
|
||||
weapStatus->setProgressPosition(durabilityPercent);
|
||||
|
||||
if (weapImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(weapImage->getChildAt(0));
|
||||
|
||||
std::string path = std::string("icons\\");
|
||||
path+=MWWorld::Class::get(item).getInventoryIcon(item);
|
||||
Widgets::fixTexturePath(path);
|
||||
|
||||
if (MWWorld::Class::get(item).getEnchantment(item) != "")
|
||||
{
|
||||
weapImage->setImageTexture("textures\\menu_icon_magic_mini.dds");
|
||||
MyGUI::ImageBox* itemBox = weapImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
|
||||
, MyGUI::Align::Stretch);
|
||||
itemBox->setImageTexture(path);
|
||||
itemBox->setNeedMouseFocus(false);
|
||||
}
|
||||
else
|
||||
weapImage->setImageTexture(path);
|
||||
}
|
||||
|
||||
void HUD::unsetSelectedSpell()
|
||||
{
|
||||
std::string spellName = "#{sNone}";
|
||||
if (spellName != mSpellName && mSpellVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mSpellName = spellName;
|
||||
mWeaponSpellBox->setCaptionWithReplacing(mSpellName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
if (spellImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0));
|
||||
spellStatus->setProgressRange(100);
|
||||
spellStatus->setProgressPosition(0);
|
||||
spellImage->setImageTexture("");
|
||||
spellBox->clearUserStrings();
|
||||
}
|
||||
|
||||
void HUD::unsetSelectedWeapon()
|
||||
{
|
||||
std::string itemName = "#{sSkillHandtohand}";
|
||||
if (itemName != mWeaponName && mWeaponVisible)
|
||||
{
|
||||
mWeaponSpellTimer = 5.0f;
|
||||
mWeaponName = itemName;
|
||||
mWeaponSpellBox->setCaptionWithReplacing(mWeaponName);
|
||||
mWeaponSpellBox->setVisible(true);
|
||||
}
|
||||
|
||||
if (weapImage->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(weapImage->getChildAt(0));
|
||||
weapStatus->setProgressRange(100);
|
||||
weapStatus->setProgressPosition(0);
|
||||
weapImage->setImageTexture("icons\\k\\stealth_handtohand.dds");
|
||||
weapBox->clearUserStrings();
|
||||
}
|
85
apps/openmw/mwgui/hud.hpp
Normal file
85
apps/openmw/mwgui/hud.hpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include "map_window.hpp"
|
||||
|
||||
#include <openengine/gui/layout.hpp>
|
||||
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class DragAndDrop;
|
||||
|
||||
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
||||
{
|
||||
public:
|
||||
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
|
||||
void setEffect(const char *img);
|
||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
||||
void setFPS(float fps);
|
||||
void setTriangleCount(size_t count);
|
||||
void setBatchCount(size_t count);
|
||||
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
|
||||
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
|
||||
void setFpsLevel(const int level);
|
||||
|
||||
void setSelectedSpell(const std::string& spellId, int successChancePercent);
|
||||
void setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent);
|
||||
void setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent);
|
||||
void unsetSelectedSpell();
|
||||
void unsetSelectedWeapon();
|
||||
|
||||
void onFrame(float dt);
|
||||
void onResChange(int width, int height);
|
||||
|
||||
void setCellName(const std::string& cellName);
|
||||
|
||||
bool getWorldMouseOver() { return mWorldMouseOver; }
|
||||
|
||||
MyGUI::ProgressPtr health, magicka, stamina;
|
||||
MyGUI::Widget* mHealthFrame;
|
||||
MyGUI::Widget *weapBox, *spellBox;
|
||||
MyGUI::ImageBox *weapImage, *spellImage;
|
||||
MyGUI::ProgressPtr weapStatus, spellStatus;
|
||||
MyGUI::Widget *effectBox, *minimapBox;
|
||||
MyGUI::ImageBox* effect1;
|
||||
MyGUI::ScrollView* minimap;
|
||||
MyGUI::ImageBox* compass;
|
||||
MyGUI::ImageBox* crosshair;
|
||||
MyGUI::TextBox* mCellNameBox;
|
||||
MyGUI::TextBox* mWeaponSpellBox;
|
||||
|
||||
MyGUI::WidgetPtr fpsbox;
|
||||
MyGUI::TextBox* fpscounter;
|
||||
MyGUI::TextBox* trianglecounter;
|
||||
MyGUI::TextBox* batchcounter;
|
||||
|
||||
private:
|
||||
// bottom left elements
|
||||
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
|
||||
// bottom right elements
|
||||
int minimapBoxBaseRight, effectBoxBaseRight;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
std::string mCellName;
|
||||
float mCellNameTimer;
|
||||
|
||||
std::string mWeaponName;
|
||||
std::string mSpellName;
|
||||
float mWeaponSpellTimer;
|
||||
|
||||
bool mMapVisible;
|
||||
bool mWeaponVisible;
|
||||
bool mSpellVisible;
|
||||
|
||||
bool mWorldMouseOver;
|
||||
|
||||
void onWorldClicked(MyGUI::Widget* _sender);
|
||||
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
|
||||
void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new);
|
||||
void onHMSClicked(MyGUI::Widget* _sender);
|
||||
void onWeaponClicked(MyGUI::Widget* _sender);
|
||||
void onMagicClicked(MyGUI::Widget* _sender);
|
||||
void onMapClicked(MyGUI::Widget* _sender);
|
||||
};
|
||||
}
|
349
apps/openmw/mwgui/inventorywindow.cpp
Normal file
349
apps/openmw/mwgui/inventorywindow.cpp
Normal file
|
@ -0,0 +1,349 @@
|
|||
#include "inventorywindow.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "bookwindow.hpp"
|
||||
#include "scrollwindow.hpp"
|
||||
#include "spellwindow.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string toLower (const std::string& name)
|
||||
{
|
||||
std::string lowerCase;
|
||||
|
||||
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
|
||||
(int(*)(int)) std::tolower);
|
||||
|
||||
return lowerCase;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
InventoryWindow::InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)
|
||||
: ContainerBase(dragAndDrop)
|
||||
, WindowPinnableBase("openmw_inventory_window_layout.xml", parWindowManager)
|
||||
, mTrading(false)
|
||||
{
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
|
||||
|
||||
getWidget(mAvatar, "Avatar");
|
||||
getWidget(mEncumbranceBar, "EncumbranceBar");
|
||||
getWidget(mEncumbranceText, "EncumbranceBarT");
|
||||
getWidget(mFilterAll, "AllButton");
|
||||
getWidget(mFilterWeapon, "WeaponButton");
|
||||
getWidget(mFilterApparel, "ApparelButton");
|
||||
getWidget(mFilterMagic, "MagicButton");
|
||||
getWidget(mFilterMisc, "MiscButton");
|
||||
getWidget(mLeftPane, "LeftPane");
|
||||
getWidget(mRightPane, "RightPane");
|
||||
|
||||
mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
// adjust size of buttons to fit text
|
||||
int curX = 0;
|
||||
mFilterAll->setSize( mFilterAll->getTextSize().width + 24, mFilterAll->getSize().height );
|
||||
curX += mFilterAll->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterWeapon->setPosition(curX, mFilterWeapon->getPosition().top);
|
||||
mFilterWeapon->setSize( mFilterWeapon->getTextSize().width + 24, mFilterWeapon->getSize().height );
|
||||
curX += mFilterWeapon->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterApparel->setPosition(curX, mFilterApparel->getPosition().top);
|
||||
mFilterApparel->setSize( mFilterApparel->getTextSize().width + 24, mFilterApparel->getSize().height );
|
||||
curX += mFilterApparel->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMagic->setPosition(curX, mFilterMagic->getPosition().top);
|
||||
mFilterMagic->setSize( mFilterMagic->getTextSize().width + 24, mFilterMagic->getSize().height );
|
||||
curX += mFilterMagic->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMisc->setPosition(curX, mFilterMisc->getPosition().top);
|
||||
mFilterMisc->setSize( mFilterMisc->getTextSize().width + 24, mFilterMisc->getSize().height );
|
||||
|
||||
mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterMagic->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterMisc->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
|
||||
mFilterAll->setStateSelected(true);
|
||||
|
||||
setCoord(0, 342, 498, 258);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
openContainer(player);
|
||||
}
|
||||
|
||||
void InventoryWindow::open()
|
||||
{
|
||||
updateEncumbranceBar();
|
||||
|
||||
mTrading = false;
|
||||
|
||||
mBoughtItems.clear();
|
||||
|
||||
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
|
||||
}
|
||||
|
||||
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
{
|
||||
const float aspect = 0.5; // fixed aspect ratio for the left pane
|
||||
mLeftPane->setSize( (_sender->getSize().height-44) * aspect, _sender->getSize().height-44 );
|
||||
mRightPane->setCoord( mLeftPane->getPosition().left + (_sender->getSize().height-44) * aspect + 4,
|
||||
mRightPane->getPosition().top,
|
||||
_sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15,
|
||||
_sender->getSize().height-44 );
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (_sender == mFilterAll)
|
||||
setFilter(ContainerBase::Filter_All);
|
||||
else if (_sender == mFilterWeapon)
|
||||
setFilter(ContainerBase::Filter_Weapon);
|
||||
else if (_sender == mFilterApparel)
|
||||
setFilter(ContainerBase::Filter_Apparel);
|
||||
else if (_sender == mFilterMagic)
|
||||
setFilter(ContainerBase::Filter_Magic);
|
||||
else if (_sender == mFilterMisc)
|
||||
setFilter(ContainerBase::Filter_Misc);
|
||||
|
||||
mFilterAll->setStateSelected(false);
|
||||
mFilterWeapon->setStateSelected(false);
|
||||
mFilterApparel->setStateSelected(false);
|
||||
mFilterMagic->setStateSelected(false);
|
||||
mFilterMisc->setStateSelected(false);
|
||||
|
||||
static_cast<MyGUI::Button*>(_sender)->setStateSelected(true);
|
||||
}
|
||||
|
||||
void InventoryWindow::onPinToggled()
|
||||
{
|
||||
mWindowManager.setWeaponVisibility(!mPinned);
|
||||
}
|
||||
|
||||
void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWWorld::Ptr ptr = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
|
||||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
{
|
||||
// add item to the player's inventory
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
|
||||
int origCount = ptr.getRefData().getCount();
|
||||
ptr.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
it = invStore.add(ptr);
|
||||
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
ptr = *it;
|
||||
}
|
||||
|
||||
/// \todo scripts
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
|
||||
|
||||
action->execute();
|
||||
|
||||
// this is necessary for books/scrolls: if they are already in the player's inventory,
|
||||
// the "Take" button should not be visible.
|
||||
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
|
||||
// without screwing up future book windows
|
||||
if (mDragAndDrop->mDraggedFrom == this)
|
||||
{
|
||||
mWindowManager.getBookWindow()->setTakeButtonShow(false);
|
||||
mWindowManager.getScrollWindow()->setTakeButtonShow(false);
|
||||
}
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
|
||||
mWindowManager.setDragDrop(false);
|
||||
|
||||
drawItems();
|
||||
|
||||
// update selected weapon icon
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator weaponSlot = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
if (weaponSlot == invStore.end())
|
||||
mWindowManager.unsetSelectedWeapon();
|
||||
else
|
||||
mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems()
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end())
|
||||
{
|
||||
items.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
void InventoryWindow::_unequipItem(MWWorld::Ptr item)
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end() && *it == item)
|
||||
{
|
||||
invStore.equip(slot, invStore.end());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryWindow::updateEncumbranceBar()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
|
||||
float capacity = MWWorld::Class::get(player).getCapacity(player);
|
||||
float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
|
||||
mEncumbranceBar->setProgressRange(capacity);
|
||||
mEncumbranceBar->setProgressPosition(encumbrance);
|
||||
mEncumbranceText->setCaption( boost::lexical_cast<std::string>(int(encumbrance)) + "/" + boost::lexical_cast<std::string>(int(capacity)) );
|
||||
}
|
||||
|
||||
void InventoryWindow::onFrame()
|
||||
{
|
||||
if (!mMainWidget->getVisible())
|
||||
return;
|
||||
|
||||
updateEncumbranceBar();
|
||||
}
|
||||
|
||||
int InventoryWindow::getPlayerGold()
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
it != invStore.end(); ++it)
|
||||
{
|
||||
if (toLower(it->getCellRef().refID) == "gold_001")
|
||||
return it->getRefData().getCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InventoryWindow::startTrade()
|
||||
{
|
||||
mTrading = true;
|
||||
}
|
||||
|
||||
void InventoryWindow::notifyContentChanged()
|
||||
{
|
||||
// update the spell window just in case new enchanted items were added to inventory
|
||||
if (mWindowManager.getSpellWindow())
|
||||
mWindowManager.getSpellWindow()->updateSpells();
|
||||
|
||||
// update selected weapon icon
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator weaponSlot = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
if (weaponSlot == invStore.end())
|
||||
mWindowManager.unsetSelectedWeapon();
|
||||
else
|
||||
mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability
|
||||
}
|
||||
|
||||
void InventoryWindow::pickUpObject (MWWorld::Ptr object)
|
||||
{
|
||||
/// \todo scripts
|
||||
|
||||
// make sure the object is of a type that can be picked up
|
||||
std::string type = object.getTypeName();
|
||||
if ( (type != typeid(ESM::Apparatus).name())
|
||||
&& (type != typeid(ESM::Armor).name())
|
||||
&& (type != typeid(ESM::Book).name())
|
||||
&& (type != typeid(ESM::Clothing).name())
|
||||
&& (type != typeid(ESM::Ingredient).name())
|
||||
&& (type != typeid(ESM::Light).name())
|
||||
&& (type != typeid(ESM::Miscellaneous).name())
|
||||
&& (type != typeid(ESM::Tool).name())
|
||||
&& (type != typeid(ESM::Probe).name())
|
||||
&& (type != typeid(ESM::Repair).name())
|
||||
&& (type != typeid(ESM::Weapon).name())
|
||||
&& (type != typeid(ESM::Potion).name()))
|
||||
return;
|
||||
|
||||
// sound
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound(sound, 1, 1);
|
||||
|
||||
int count = object.getRefData().getCount();
|
||||
|
||||
// add to player inventory
|
||||
// can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::Ptr newObject = *MWWorld::Class::get (player).getContainerStore (player).add (object);
|
||||
// remove from world
|
||||
MWBase::Environment::get().getWorld()->deleteObject (object);
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = true;
|
||||
mDragAndDrop->mDraggedCount = count;
|
||||
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(newObject).getInventoryIcon(newObject);
|
||||
MyGUI::ImageBox* baseWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
|
||||
baseWidget->detachFromWidget();
|
||||
baseWidget->attachToWidget(mDragAndDrop->mDragAndDropWidget);
|
||||
baseWidget->setUserData(newObject);
|
||||
mDragAndDrop->mDraggedWidget = baseWidget;
|
||||
ImageBox* image = baseWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
image->setImageTexture(path);
|
||||
image->setNeedMouseFocus(false);
|
||||
|
||||
// text widget that shows item count
|
||||
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
|
||||
text->setTextAlign(MyGUI::Align::Right);
|
||||
text->setNeedMouseFocus(false);
|
||||
text->setTextShadow(true);
|
||||
text->setTextShadowColour(MyGUI::Colour(0,0,0));
|
||||
text->setCaption(getCountString(count));
|
||||
mDragAndDrop->mDraggedFrom = this;
|
||||
}
|
||||
}
|
60
apps/openmw/mwgui/inventorywindow.hpp
Normal file
60
apps/openmw/mwgui/inventorywindow.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef MGUI_Inventory_H
|
||||
#define MGUI_Inventory_H
|
||||
|
||||
#include "container.hpp"
|
||||
#include "window_pinnable_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class InventoryWindow : public ContainerBase, public WindowPinnableBase
|
||||
{
|
||||
public:
|
||||
InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop);
|
||||
|
||||
virtual void open();
|
||||
|
||||
/// start trading, disables item drag&drop
|
||||
void startTrade();
|
||||
|
||||
void onFrame();
|
||||
|
||||
void pickUpObject (MWWorld::Ptr object);
|
||||
|
||||
int getPlayerGold();
|
||||
|
||||
protected:
|
||||
MyGUI::Widget* mAvatar;
|
||||
MyGUI::TextBox* mArmorRating;
|
||||
MyGUI::ProgressBar* mEncumbranceBar;
|
||||
MyGUI::TextBox* mEncumbranceText;
|
||||
|
||||
MyGUI::Widget* mLeftPane;
|
||||
MyGUI::Widget* mRightPane;
|
||||
|
||||
MyGUI::Button* mFilterAll;
|
||||
MyGUI::Button* mFilterWeapon;
|
||||
MyGUI::Button* mFilterApparel;
|
||||
MyGUI::Button* mFilterMagic;
|
||||
MyGUI::Button* mFilterMisc;
|
||||
|
||||
bool mTrading;
|
||||
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
void onFilterChanged(MyGUI::Widget* _sender);
|
||||
void onAvatarClicked(MyGUI::Widget* _sender);
|
||||
void onPinToggled();
|
||||
|
||||
void updateEncumbranceBar();
|
||||
|
||||
virtual bool isTrading() { return mTrading; }
|
||||
virtual bool isInventory() { return true; }
|
||||
virtual std::vector<MWWorld::Ptr> getEquippedItems();
|
||||
virtual void _unequipItem(MWWorld::Ptr item);
|
||||
|
||||
virtual void onReferenceUnavailable() { ; }
|
||||
|
||||
virtual void notifyContentChanged();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // Inventory_H
|
|
@ -82,6 +82,7 @@ book formatText(std::string text,book mBook,int maxLine, int lineSize)
|
|||
MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager)
|
||||
: WindowBase("openmw_journal_layout.xml", parWindowManager)
|
||||
, lastPos(0)
|
||||
, mVisible(false)
|
||||
{
|
||||
//setCoord(0,0,498, 342);
|
||||
center();
|
||||
|
@ -109,9 +110,15 @@ MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager)
|
|||
//std::list<std::string> list = formatText("OpenMW rgh dsfg sqef srg ZT uzql n ZLIEHRF LQSJH GLOIjf qjfmj hslkdgn jlkdjhg qlr isgli shli uhs fiuh qksf cg ksjnf lkqsnbf ksbf sbfkl zbf kuyzflkj sbgdfkj zlfh ozhjfmo hzmfh lizuf rty qzt ezy tkyEZT RYYJ DG fgh is an open-source implementation of the game engine found in the game Morrowind. This is a dumb test text msodjbg smojg smoig fiiinnn");
|
||||
//std::list<std::string> list = formatText();
|
||||
//displayLeftText(list.front());
|
||||
}
|
||||
|
||||
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget);
|
||||
t->eventWindowChangeCoord += MyGUI::newDelegate(this, &JournalWindow::onWindowResize);
|
||||
void MWGui::JournalWindow::setVisible(bool visible)
|
||||
{
|
||||
if (mVisible && !visible)
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
||||
mVisible = visible;
|
||||
|
||||
mMainWidget->setVisible(visible);
|
||||
}
|
||||
|
||||
void MWGui::JournalWindow::open()
|
||||
|
@ -124,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);
|
||||
|
@ -134,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)
|
||||
{
|
||||
|
@ -159,10 +166,6 @@ void MWGui::JournalWindow::open()
|
|||
}
|
||||
}
|
||||
|
||||
void MWGui::JournalWindow::onWindowResize(MyGUI::Window* window)
|
||||
{
|
||||
}
|
||||
|
||||
void MWGui::JournalWindow::displayLeftText(std::string text)
|
||||
{
|
||||
mLeftTextWidget->eraseText(0,mLeftTextWidget->getTextLength());
|
||||
|
|
|
@ -18,16 +18,9 @@ namespace MWGui
|
|||
JournalWindow(WindowManager& parWindowManager);
|
||||
void open();
|
||||
|
||||
virtual void setVisible(bool visible); // only used to play close sound
|
||||
|
||||
private:
|
||||
enum ColorStyle
|
||||
{
|
||||
CS_Sub,
|
||||
CS_Normal,
|
||||
CS_Super
|
||||
};
|
||||
|
||||
void onWindowResize(MyGUI::Window* window);
|
||||
|
||||
void displayLeftText(std::string text);
|
||||
void displayRightText(std::string text);
|
||||
|
||||
|
@ -50,6 +43,7 @@ namespace MWGui
|
|||
std::vector<std::string> leftPages;
|
||||
std::vector<std::string> rightPages;
|
||||
int mPageNumber; //store the number of the current left page
|
||||
bool mVisible;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,332 +0,0 @@
|
|||
#include "layouts.hpp"
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include "window_manager.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
|
||||
HUD::HUD(int width, int height, int fpsLevel)
|
||||
: Layout("openmw_hud_layout.xml")
|
||||
, health(NULL)
|
||||
, magicka(NULL)
|
||||
, stamina(NULL)
|
||||
, weapImage(NULL)
|
||||
, spellImage(NULL)
|
||||
, weapStatus(NULL)
|
||||
, spellStatus(NULL)
|
||||
, effectBox(NULL)
|
||||
, effect1(NULL)
|
||||
, minimap(NULL)
|
||||
, compass(NULL)
|
||||
, crosshair(NULL)
|
||||
, fpsbox(NULL)
|
||||
, fpscounter(NULL)
|
||||
, trianglecounter(NULL)
|
||||
, batchcounter(NULL)
|
||||
, hmsBaseLeft(0)
|
||||
, weapBoxBaseLeft(0)
|
||||
, spellBoxBaseLeft(0)
|
||||
, effectBoxBaseRight(0)
|
||||
, minimapBoxBaseRight(0)
|
||||
{
|
||||
setCoord(0,0, width, height);
|
||||
|
||||
// Energy bars
|
||||
getWidget(health, "Health");
|
||||
getWidget(magicka, "Magicka");
|
||||
getWidget(stamina, "Stamina");
|
||||
hmsBaseLeft = health->getLeft();
|
||||
|
||||
// Item and spell images and status bars
|
||||
getWidget(weapBox, "WeapBox");
|
||||
getWidget(weapImage, "WeapImage");
|
||||
getWidget(weapStatus, "WeapStatus");
|
||||
weapBoxBaseLeft = weapBox->getLeft();
|
||||
|
||||
getWidget(spellBox, "SpellBox");
|
||||
getWidget(spellImage, "SpellImage");
|
||||
getWidget(spellStatus, "SpellStatus");
|
||||
spellBoxBaseLeft = spellBox->getLeft();
|
||||
|
||||
getWidget(effectBox, "EffectBox");
|
||||
getWidget(effect1, "Effect1");
|
||||
effectBoxBaseRight = effectBox->getRight();
|
||||
|
||||
getWidget(minimapBox, "MiniMapBox");
|
||||
minimapBoxBaseRight = minimapBox->getRight();
|
||||
getWidget(minimap, "MiniMap");
|
||||
getWidget(compass, "Compass");
|
||||
|
||||
getWidget(crosshair, "Crosshair");
|
||||
|
||||
setFpsLevel(fpsLevel);
|
||||
|
||||
getWidget(trianglecounter, "TriangleCounter");
|
||||
getWidget(batchcounter, "BatchCounter");
|
||||
|
||||
compass->setImageTexture("textures\\compass.dds");
|
||||
crosshair->setImageTexture("textures\\target.dds");
|
||||
|
||||
// These are just demo values, you should replace these with
|
||||
// real calls from outside the class later.
|
||||
setWeapIcon("icons\\w\\tx_knife_iron.dds");
|
||||
setWeapStatus(90, 100);
|
||||
setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds");
|
||||
setSpellStatus(65, 100);
|
||||
setEffect("icons\\s\\tx_s_chameleon.dds");
|
||||
|
||||
LocalMapBase::init(minimap, this);
|
||||
}
|
||||
|
||||
void HUD::setFpsLevel(int level)
|
||||
{
|
||||
MyGUI::Widget* fps;
|
||||
getWidget(fps, "FPSBoxAdv");
|
||||
fps->setVisible(false);
|
||||
getWidget(fps, "FPSBox");
|
||||
fps->setVisible(false);
|
||||
|
||||
if (level == 2)
|
||||
{
|
||||
getWidget(fpsbox, "FPSBoxAdv");
|
||||
fpsbox->setVisible(true);
|
||||
getWidget(fpscounter, "FPSCounterAdv");
|
||||
}
|
||||
else if (level == 1)
|
||||
{
|
||||
getWidget(fpsbox, "FPSBox");
|
||||
fpsbox->setVisible(true);
|
||||
getWidget(fpscounter, "FPSCounter");
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setFPS(float fps)
|
||||
{
|
||||
fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps));
|
||||
}
|
||||
|
||||
void HUD::setTriangleCount(size_t count)
|
||||
{
|
||||
trianglecounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||
}
|
||||
|
||||
void HUD::setBatchCount(size_t count)
|
||||
{
|
||||
batchcounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||
}
|
||||
|
||||
void HUD::setStats(int h, int hmax, int m, int mmax, int s, int smax)
|
||||
{
|
||||
health->setProgressRange(hmax);
|
||||
health->setProgressPosition(h);
|
||||
magicka->setProgressRange(mmax);
|
||||
magicka->setProgressPosition(m);
|
||||
stamina->setProgressRange(smax);
|
||||
stamina->setProgressPosition(s);
|
||||
}
|
||||
|
||||
void HUD::setWeapIcon(const char *str)
|
||||
{
|
||||
weapImage->setImageTexture(str);
|
||||
}
|
||||
|
||||
void HUD::setSpellIcon(const char *str)
|
||||
{
|
||||
spellImage->setImageTexture(str);
|
||||
}
|
||||
|
||||
void HUD::setWeapStatus(int s, int smax)
|
||||
{
|
||||
weapStatus->setProgressRange(smax);
|
||||
weapStatus->setProgressPosition(s);
|
||||
}
|
||||
|
||||
void HUD::setSpellStatus(int s, int smax)
|
||||
{
|
||||
spellStatus->setProgressRange(smax);
|
||||
spellStatus->setProgressPosition(s);
|
||||
}
|
||||
|
||||
void HUD::setEffect(const char *img)
|
||||
{
|
||||
effect1->setImageTexture(img);
|
||||
}
|
||||
|
||||
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& value)
|
||||
{
|
||||
static const char *ids[] =
|
||||
{
|
||||
"HBar", "MBar", "FBar", 0
|
||||
};
|
||||
|
||||
for (int i=0; ids[i]; ++i)
|
||||
if (ids[i]==id)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
health->setProgressRange (value.getModified());
|
||||
health->setProgressPosition (value.getCurrent());
|
||||
break;
|
||||
case 1:
|
||||
magicka->setProgressRange (value.getModified());
|
||||
magicka->setProgressPosition (value.getCurrent());
|
||||
break;
|
||||
case 2:
|
||||
stamina->setProgressRange (value.getModified());
|
||||
stamina->setProgressPosition (value.getCurrent());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setPlayerDir(const float x, const float y)
|
||||
{
|
||||
if (!minimapBox->getVisible() || (x == mLastPositionX && y == mLastPositionY)) return;
|
||||
|
||||
MyGUI::ISubWidget* main = compass->getSubWidgetMain();
|
||||
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
||||
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
||||
float angle = std::atan2(x,y);
|
||||
rotatingSubskin->setAngle(angle);
|
||||
mLastPositionX = x;
|
||||
mLastPositionY = y;
|
||||
}
|
||||
|
||||
void HUD::setPlayerPos(const float x, const float y)
|
||||
{
|
||||
if (!minimapBox->getVisible() || (x == mLastDirectionX && y == mLastDirectionY)) return;
|
||||
|
||||
MyGUI::IntSize size = minimap->getCanvasSize();
|
||||
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
||||
MyGUI::IntCoord viewsize = minimap->getCoord();
|
||||
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
|
||||
|
||||
minimap->setViewOffset(pos);
|
||||
compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
|
||||
|
||||
mLastDirectionX = x;
|
||||
mLastDirectionY = y;
|
||||
}
|
||||
|
||||
void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible)
|
||||
{
|
||||
int weapDx = 0, spellDx = 0;
|
||||
if (!hmsVisible)
|
||||
spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft;
|
||||
|
||||
if (!weapVisible)
|
||||
spellDx -= spellBoxBaseLeft - weapBoxBaseLeft;
|
||||
|
||||
health->setVisible(hmsVisible);
|
||||
stamina->setVisible(hmsVisible);
|
||||
magicka->setVisible(hmsVisible);
|
||||
weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop());
|
||||
weapBox->setVisible(weapVisible);
|
||||
spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop());
|
||||
spellBox->setVisible(spellVisible);
|
||||
}
|
||||
|
||||
void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible)
|
||||
{
|
||||
// effect box can have variable width -> variable left coordinate
|
||||
int effectsDx = 0;
|
||||
if (!minimapBoxVisible)
|
||||
effectsDx = minimapBoxBaseRight - effectBoxBaseRight;
|
||||
|
||||
minimapBox->setVisible(minimapBoxVisible);
|
||||
effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop());
|
||||
effectBox->setVisible(effectBoxVisible);
|
||||
}
|
||||
|
||||
LocalMapBase::LocalMapBase()
|
||||
: mCurX(0)
|
||||
, mCurY(0)
|
||||
, mInterior(false)
|
||||
, mFogOfWar(true)
|
||||
, mLocalMap(NULL)
|
||||
, mPrefix()
|
||||
, mChanged(true)
|
||||
, mLayout(NULL)
|
||||
, mLastPositionX(0.0f)
|
||||
, mLastPositionY(0.0f)
|
||||
, mLastDirectionX(0.0f)
|
||||
, mLastDirectionY(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout)
|
||||
{
|
||||
mLocalMap = widget;
|
||||
mLayout = layout;
|
||||
}
|
||||
|
||||
void LocalMapBase::setCellPrefix(const std::string& prefix)
|
||||
{
|
||||
mPrefix = prefix;
|
||||
mChanged = true;
|
||||
}
|
||||
|
||||
void LocalMapBase::toggleFogOfWar()
|
||||
{
|
||||
mFogOfWar = !mFogOfWar;
|
||||
applyFogOfWar();
|
||||
}
|
||||
|
||||
void LocalMapBase::applyFogOfWar()
|
||||
{
|
||||
for (int mx=0; mx<3; ++mx)
|
||||
{
|
||||
for (int my=0; my<3; ++my)
|
||||
{
|
||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||
+ boost::lexical_cast<std::string>(my);
|
||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
|
||||
+ boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1)));
|
||||
MyGUI::ImageBox* fog;
|
||||
mLayout->getWidget(fog, name+"_fog");
|
||||
fog->setImageTexture(mFogOfWar ?
|
||||
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
|
||||
: "black.png" )
|
||||
: "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
||||
{
|
||||
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
|
||||
for (int mx=0; mx<3; ++mx)
|
||||
{
|
||||
for (int my=0; my<3; ++my)
|
||||
{
|
||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||
+ boost::lexical_cast<std::string>(my);
|
||||
|
||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
|
||||
+ boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1)));
|
||||
|
||||
MyGUI::ImageBox* box;
|
||||
mLayout->getWidget(box, name);
|
||||
|
||||
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
|
||||
box->setImageTexture(image);
|
||||
else
|
||||
box->setImageTexture("black.png");
|
||||
}
|
||||
}
|
||||
mInterior = interior;
|
||||
mCurX = x;
|
||||
mCurY = y;
|
||||
mChanged = false;
|
||||
applyFogOfWar();
|
||||
}
|
||||
|
|
@ -1,236 +0,0 @@
|
|||
#ifndef MWGUI_LAYOUTS_H
|
||||
#define MWGUI_LAYOUTS_H
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
/*
|
||||
This file contains classes corresponding to window layouts
|
||||
defined in resources/mygui/ *.xml.
|
||||
|
||||
Each class inherites GUI::Layout and loads the XML file, and
|
||||
provides some helper functions to manipulate the elements of the
|
||||
window.
|
||||
|
||||
The windows are never created or destroyed (except at startup and
|
||||
shutdown), they are only hid. You can control visibility with
|
||||
setVisible().
|
||||
*/
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class LocalMapBase
|
||||
{
|
||||
public:
|
||||
LocalMapBase();
|
||||
void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout);
|
||||
|
||||
void setCellPrefix(const std::string& prefix);
|
||||
void setActiveCell(const int x, const int y, bool interior=false);
|
||||
|
||||
void toggleFogOfWar();
|
||||
|
||||
protected:
|
||||
int mCurX, mCurY;
|
||||
bool mInterior;
|
||||
MyGUI::ScrollView* mLocalMap;
|
||||
std::string mPrefix;
|
||||
bool mChanged;
|
||||
bool mFogOfWar;
|
||||
|
||||
void applyFogOfWar();
|
||||
|
||||
OEngine::GUI::Layout* mLayout;
|
||||
|
||||
float mLastPositionX;
|
||||
float mLastPositionY;
|
||||
float mLastDirectionX;
|
||||
float mLastDirectionY;
|
||||
};
|
||||
|
||||
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
||||
{
|
||||
public:
|
||||
HUD(int width, int height, int fpsLevel);
|
||||
void setStats(int h, int hmax, int m, int mmax, int s, int smax);
|
||||
void setWeapIcon(const char *str);
|
||||
void setSpellIcon(const char *str);
|
||||
void setWeapStatus(int s, int smax);
|
||||
void setSpellStatus(int s, int smax);
|
||||
void setEffect(const char *img);
|
||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
||||
void setFPS(float fps);
|
||||
void setTriangleCount(size_t count);
|
||||
void setBatchCount(size_t count);
|
||||
void setPlayerDir(const float x, const float y);
|
||||
void setPlayerPos(const float x, const float y);
|
||||
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
|
||||
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
|
||||
void setFpsLevel(const int level);
|
||||
|
||||
MyGUI::ProgressPtr health, magicka, stamina;
|
||||
MyGUI::Widget *weapBox, *spellBox;
|
||||
MyGUI::ImageBox *weapImage, *spellImage;
|
||||
MyGUI::ProgressPtr weapStatus, spellStatus;
|
||||
MyGUI::Widget *effectBox, *minimapBox;
|
||||
MyGUI::ImageBox* effect1;
|
||||
MyGUI::ScrollView* minimap;
|
||||
MyGUI::ImageBox* compass;
|
||||
MyGUI::ImageBox* crosshair;
|
||||
|
||||
MyGUI::WidgetPtr fpsbox;
|
||||
MyGUI::TextBox* fpscounter;
|
||||
MyGUI::TextBox* trianglecounter;
|
||||
MyGUI::TextBox* batchcounter;
|
||||
|
||||
private:
|
||||
// bottom left elements
|
||||
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
|
||||
// bottom right elements
|
||||
int minimapBoxBaseRight, effectBoxBaseRight;
|
||||
};
|
||||
|
||||
class MainMenu : public OEngine::GUI::Layout
|
||||
{
|
||||
public:
|
||||
MainMenu(int w, int h)
|
||||
: Layout("openmw_mainmenu_layout.xml")
|
||||
{
|
||||
setCoord(0,0,w,h);
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
class InventoryWindow : public OEngine::GUI::Layout
|
||||
{
|
||||
public:
|
||||
enum CategoryMode
|
||||
{
|
||||
CM_All = 0, // All items
|
||||
CM_Weapon = 1, // Only weapons
|
||||
CM_Apparel = 2, // Apparel
|
||||
CM_Magic = 3, // Magic
|
||||
CM_Misc = 4 // Misc
|
||||
};
|
||||
|
||||
InventoryWindow ()
|
||||
: Layout("openmw_inventory_window_layout.xml")
|
||||
, categoryMode(CM_All)
|
||||
|
||||
// color should be fetched from skin
|
||||
, activeColor(0, 0, 1)
|
||||
, inactiveColor(0.7, 0.7, 0.7)
|
||||
{
|
||||
setCoord(0, 200, 600, 400);
|
||||
|
||||
// These are just demo values, you should replace these with
|
||||
// real calls from outside the class later.
|
||||
|
||||
mMainWidget->setCaption("Glass Frostsword");
|
||||
setText("EncumbranceBarT", "176/210");
|
||||
|
||||
MyGUI::ProgressPtr pt;
|
||||
getWidget(pt, "EncumbranceBar");
|
||||
pt->setProgressRange(210);
|
||||
pt->setProgressPosition(176);
|
||||
|
||||
MyGUI::WidgetPtr avatar;
|
||||
getWidget(avatar, "Avatar");
|
||||
|
||||
// Adjust armor rating text to bottom of avatar widget
|
||||
MyGUI::TextBox* armor_rating;
|
||||
getWidget(armor_rating, "ArmorRating");
|
||||
armor_rating->setCaption("Armor: 11");
|
||||
MyGUI::IntCoord coord = armor_rating->getCoord();
|
||||
coord.top = avatar->getCoord().height - 4 - coord.height;
|
||||
armor_rating->setCoord(coord);
|
||||
|
||||
names[0] = "All";
|
||||
names[1] = "Weapon";
|
||||
names[2] = "Apparel";
|
||||
names[3] = "Magic";
|
||||
names[4] = "Misc";
|
||||
|
||||
boost::array<CategoryMode, 5> categories = { {
|
||||
CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc
|
||||
} };
|
||||
|
||||
// Initialize buttons with text and adjust sizes, also mark All as active button
|
||||
int margin = 2;
|
||||
int last_x = 0;
|
||||
for (int i = 0; i < categories.size(); ++i)
|
||||
{
|
||||
CategoryMode mode = categories[i];
|
||||
std::string name = names[mode];
|
||||
name += "Button";
|
||||
setText(name, names[mode]);
|
||||
getWidget(buttons[mode], name);
|
||||
|
||||
MyGUI::ButtonPtr &button_pt = buttons[mode];
|
||||
if (mode == CM_All)
|
||||
button_pt->setTextColour(activeColor);
|
||||
else
|
||||
button_pt->setTextColour(inactiveColor);
|
||||
MyGUI::IntCoord coord = button_pt->getCoord();
|
||||
coord.left = last_x;
|
||||
last_x += coord.width + margin;
|
||||
button_pt->setCoord(coord);
|
||||
|
||||
button_pt->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onCategorySelected);
|
||||
}
|
||||
}
|
||||
|
||||
void setCategory(CategoryMode mode)
|
||||
{
|
||||
MyGUI::ButtonPtr pt = getCategoryButton(categoryMode);
|
||||
pt->setTextColour(inactiveColor);
|
||||
|
||||
pt = getCategoryButton(mode);
|
||||
pt->setTextColour(activeColor);
|
||||
categoryMode = mode;
|
||||
}
|
||||
|
||||
MyGUI::ButtonPtr getCategoryButton(CategoryMode mode)
|
||||
{
|
||||
return buttons[mode];
|
||||
}
|
||||
|
||||
void onCategorySelected(MyGUI::Widget *widget)
|
||||
{
|
||||
boost::array<CategoryMode, 5> categories = { {
|
||||
CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc
|
||||
} };
|
||||
|
||||
for (int i = 0; i < categories.size(); ++i)
|
||||
{
|
||||
CategoryMode mode = categories[i];
|
||||
if (widget == buttons[mode])
|
||||
{
|
||||
setCategory(mode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CategoryMode categoryMode; // Current category filter
|
||||
MyGUI::ButtonPtr buttons[5]; // Button pointers
|
||||
std::string names[5]; // Names of category buttons
|
||||
|
||||
MyGUI::Colour activeColor;
|
||||
MyGUI::Colour inactiveColor;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
#endif
|
131
apps/openmw/mwgui/list.cpp
Normal file
131
apps/openmw/mwgui/list.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
#include "list.hpp"
|
||||
|
||||
#include <MyGUI.h>
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace MWGui::Widgets;
|
||||
|
||||
MWList::MWList() :
|
||||
mClient(0)
|
||||
, mScrollView(0)
|
||||
, mItemHeight(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MWList::initialiseOverride()
|
||||
{
|
||||
Base::initialiseOverride();
|
||||
|
||||
assignWidget(mClient, "Client");
|
||||
if (mClient == 0)
|
||||
mClient = this;
|
||||
|
||||
mScrollView = mClient->createWidgetReal<MyGUI::ScrollView>(
|
||||
"MW_ScrollView", MyGUI::FloatCoord(0.0, 0.0, 1.0, 1.0),
|
||||
MyGUI::Align::Top | MyGUI::Align::Left | MyGUI::Align::Stretch, getName() + "_ScrollView");
|
||||
}
|
||||
|
||||
void MWList::addItem(const std::string& name)
|
||||
{
|
||||
mItems.push_back(name);
|
||||
}
|
||||
|
||||
void MWList::addSeparator()
|
||||
{
|
||||
mItems.push_back("");
|
||||
}
|
||||
|
||||
void MWList::adjustSize()
|
||||
{
|
||||
redraw();
|
||||
}
|
||||
|
||||
void MWList::redraw(bool scrollbarShown)
|
||||
{
|
||||
const int _scrollBarWidth = 24; // fetch this from skin?
|
||||
const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0;
|
||||
const int spacing = 3;
|
||||
|
||||
while (mScrollView->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0));
|
||||
}
|
||||
|
||||
mItemHeight = 0;
|
||||
for (std::vector<std::string>::const_iterator it=mItems.begin();
|
||||
it!=mItems.end(); ++it)
|
||||
{
|
||||
if (*it != "")
|
||||
{
|
||||
MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
|
||||
"MW_ListLine", MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + (*it));
|
||||
button->setCaption((*it));
|
||||
button->getSubWidgetText()->setWordWrap(true);
|
||||
button->getSubWidgetText()->setTextAlign(MyGUI::Align::Left);
|
||||
button->eventMouseWheel += MyGUI::newDelegate(this, &MWList::onMouseWheel);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWList::onItemSelected);
|
||||
|
||||
int height = button->getTextSize().height;
|
||||
button->setSize(MyGUI::IntSize(button->getSize().width, height));
|
||||
|
||||
mItemHeight += height + spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
MyGUI::ImageBox* separator = mScrollView->createWidget<MyGUI::ImageBox>("MW_HLine",
|
||||
MyGUI::IntCoord(2, mItemHeight, mScrollView->getWidth()-4, 18),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||
separator->setNeedMouseFocus(false);
|
||||
|
||||
mItemHeight += 18 + spacing;
|
||||
}
|
||||
}
|
||||
mScrollView->setCanvasSize(mClient->getSize().width + (_scrollBarWidth-scrollBarWidth), std::max(mItemHeight, mClient->getSize().height));
|
||||
|
||||
if (!scrollbarShown && mItemHeight > mClient->getSize().height)
|
||||
redraw(true);
|
||||
}
|
||||
|
||||
bool MWList::hasItem(const std::string& name)
|
||||
{
|
||||
return (std::find(mItems.begin(), mItems.end(), name) != mItems.end());
|
||||
}
|
||||
|
||||
unsigned int MWList::getItemCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
std::string MWList::getItemNameAt(unsigned int at)
|
||||
{
|
||||
assert(at < mItems.size() && "List item out of bounds");
|
||||
return mItems[at];
|
||||
}
|
||||
|
||||
void MWList::removeItem(const std::string& name)
|
||||
{
|
||||
assert( std::find(mItems.begin(), mItems.end(), name) != mItems.end() );
|
||||
mItems.erase( std::find(mItems.begin(), mItems.end(), name) );
|
||||
}
|
||||
|
||||
void MWList::clear()
|
||||
{
|
||||
mItems.clear();
|
||||
}
|
||||
|
||||
void MWList::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
//NB view offset is negative
|
||||
if (mScrollView->getViewOffset().top + _rel*0.3 > 0)
|
||||
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||
else
|
||||
mScrollView->setViewOffset(MyGUI::IntPoint(0, mScrollView->getViewOffset().top + _rel*0.3));
|
||||
}
|
||||
|
||||
void MWList::onItemSelected(MyGUI::Widget* _sender)
|
||||
{
|
||||
std::string name = static_cast<MyGUI::Button*>(_sender)->getCaption();
|
||||
|
||||
eventItemSelected(name);
|
||||
}
|
60
apps/openmw/mwgui/list.hpp
Normal file
60
apps/openmw/mwgui/list.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef MWGUI_LIST_HPP
|
||||
#define MWGUI_LIST_HPP
|
||||
|
||||
#include <MyGUI.h>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
namespace Widgets
|
||||
{
|
||||
/**
|
||||
* \brief a very simple list widget that supports word-wrapping entries
|
||||
* \note if the width or height of the list changes, you must call adjustSize() method
|
||||
*/
|
||||
class MWList : public MyGUI::Widget
|
||||
{
|
||||
MYGUI_RTTI_DERIVED(MWList)
|
||||
public:
|
||||
MWList();
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate1<std::string> EventHandle_String;
|
||||
|
||||
/**
|
||||
* Event: Item selected with the mouse.
|
||||
* signature: void method(std::string itemName)
|
||||
*/
|
||||
EventHandle_String eventItemSelected;
|
||||
|
||||
/**
|
||||
* Call after the size of the list changed, or items were inserted/removed
|
||||
*/
|
||||
void adjustSize();
|
||||
|
||||
void addItem(const std::string& name);
|
||||
void addSeparator(); ///< add a seperator between the current and the next item.
|
||||
void removeItem(const std::string& name);
|
||||
bool hasItem(const std::string& name);
|
||||
unsigned int getItemCount();
|
||||
std::string getItemNameAt(unsigned int at); ///< \attention if there are separators, this method will return "" at the place where the separator is
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
void initialiseOverride();
|
||||
|
||||
void redraw(bool scrollbarShown = false);
|
||||
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
void onItemSelected(MyGUI::Widget* _sender);
|
||||
|
||||
private:
|
||||
MyGUI::ScrollView* mScrollView;
|
||||
MyGUI::Widget* mClient;
|
||||
|
||||
std::vector<std::string> mItems;
|
||||
|
||||
int mItemHeight; // height of all items
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
16
apps/openmw/mwgui/mainmenu.hpp
Normal file
16
apps/openmw/mwgui/mainmenu.hpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include <openengine/gui/layout.hpp>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class MainMenu : public OEngine::GUI::Layout
|
||||
{
|
||||
public:
|
||||
MainMenu(int w, int h)
|
||||
: Layout("openmw_mainmenu_layout.xml")
|
||||
{
|
||||
setCoord(0,0,w,h);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,67 +1,148 @@
|
|||
#include "map_window.hpp"
|
||||
#include "window_manager.hpp"
|
||||
/*
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
*/
|
||||
using namespace MWGui;
|
||||
|
||||
MapWindow::MapWindow(WindowManager& parWindowManager) :
|
||||
MWGui::WindowPinnableBase("openmw_map_window_layout.xml", parWindowManager),
|
||||
mGlobal(false)
|
||||
LocalMapBase::LocalMapBase()
|
||||
: mCurX(0)
|
||||
, mCurY(0)
|
||||
, mInterior(false)
|
||||
, mFogOfWar(true)
|
||||
, mLocalMap(NULL)
|
||||
, mMapDragAndDrop(false)
|
||||
, mPrefix()
|
||||
, mChanged(true)
|
||||
, mLayout(NULL)
|
||||
, mLastPositionX(0.0f)
|
||||
, mLastPositionY(0.0f)
|
||||
, mLastDirectionX(0.0f)
|
||||
, mLastDirectionY(0.0f)
|
||||
, mCompass(NULL)
|
||||
{
|
||||
setCoord(500,0,320,300);
|
||||
setText("WorldButton", "World");
|
||||
setImage("Compass", "textures\\compass.dds");
|
||||
|
||||
// Obviously you should override this later on
|
||||
setCellName("No Cell Loaded");
|
||||
|
||||
getWidget(mLocalMap, "LocalMap");
|
||||
getWidget(mGlobalMap, "GlobalMap");
|
||||
getWidget(mPlayerArrow, "Compass");
|
||||
|
||||
getWidget(mButton, "WorldButton");
|
||||
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
||||
|
||||
MyGUI::Button* eventbox;
|
||||
getWidget(eventbox, "EventBox");
|
||||
eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||
eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||
|
||||
LocalMapBase::init(mLocalMap, this);
|
||||
}
|
||||
|
||||
void MapWindow::setCellName(const std::string& cellName)
|
||||
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop)
|
||||
{
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName);
|
||||
adjustWindowCaption();
|
||||
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 MapWindow::setPlayerPos(const float x, const float y)
|
||||
void LocalMapBase::setCellPrefix(const std::string& prefix)
|
||||
{
|
||||
if (mGlobal || !mVisible || (x == mLastPositionX && y == mLastPositionY)) return;
|
||||
mPrefix = prefix;
|
||||
mChanged = true;
|
||||
}
|
||||
|
||||
void LocalMapBase::toggleFogOfWar()
|
||||
{
|
||||
mFogOfWar = !mFogOfWar;
|
||||
applyFogOfWar();
|
||||
}
|
||||
|
||||
void LocalMapBase::applyFogOfWar()
|
||||
{
|
||||
for (int mx=0; mx<3; ++mx)
|
||||
{
|
||||
for (int my=0; my<3; ++my)
|
||||
{
|
||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||
+ boost::lexical_cast<std::string>(my);
|
||||
|
||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
|
||||
+ boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1)));
|
||||
MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx];
|
||||
fog->setImageTexture(mFogOfWar ?
|
||||
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
|
||||
: "black.png" )
|
||||
: "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
||||
{
|
||||
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
|
||||
for (int mx=0; mx<3; ++mx)
|
||||
{
|
||||
for (int my=0; my<3; ++my)
|
||||
{
|
||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
|
||||
+ boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1)));
|
||||
|
||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||
+ boost::lexical_cast<std::string>(my);
|
||||
|
||||
MyGUI::ImageBox* box = mMapWidgets[my + 3*mx];
|
||||
|
||||
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
|
||||
box->setImageTexture(image);
|
||||
else
|
||||
box->setImageTexture("black.png");
|
||||
}
|
||||
}
|
||||
mInterior = interior;
|
||||
mCurX = x;
|
||||
mCurY = y;
|
||||
mChanged = false;
|
||||
applyFogOfWar();
|
||||
|
||||
// set the compass texture again, because MyGUI determines sorting of ImageBox widgets
|
||||
// based on the last setImageTexture call
|
||||
std::string tex = "textures\\compass.dds";
|
||||
mCompass->setImageTexture("");
|
||||
mCompass->setImageTexture(tex);
|
||||
}
|
||||
|
||||
|
||||
void LocalMapBase::setPlayerPos(const float x, const float y)
|
||||
{
|
||||
if (x == mLastPositionX && y == mLastPositionY)
|
||||
return;
|
||||
MyGUI::IntSize size = mLocalMap->getCanvasSize();
|
||||
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
||||
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
|
||||
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
|
||||
mLocalMap->setViewOffset(pos);
|
||||
|
||||
mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
|
||||
mCompass->setPosition(MyGUI::IntPoint(512+x*512-16, 512+y*512-16));
|
||||
mLastPositionX = x;
|
||||
mLastPositionY = y;
|
||||
}
|
||||
|
||||
void MapWindow::setPlayerDir(const float x, const float y)
|
||||
void LocalMapBase::setPlayerDir(const float x, const float y)
|
||||
{
|
||||
if (!mVisible || (x == mLastDirectionX && y == mLastDirectionY)) return;
|
||||
MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain();
|
||||
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);
|
||||
|
@ -71,6 +152,37 @@ void MapWindow::setPlayerDir(const float x, const float y)
|
|||
mLastDirectionY = y;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
MapWindow::MapWindow(WindowManager& parWindowManager) :
|
||||
MWGui::WindowPinnableBase("openmw_map_window_layout.xml", parWindowManager),
|
||||
mGlobal(false)
|
||||
{
|
||||
setCoord(500,0,320,300);
|
||||
|
||||
getWidget(mLocalMap, "LocalMap");
|
||||
getWidget(mGlobalMap, "GlobalMap");
|
||||
getWidget(mPlayerArrow, "Compass");
|
||||
|
||||
getWidget(mButton, "WorldButton");
|
||||
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
||||
mButton->setCaptionWithReplacing("#{sWorld}");
|
||||
int width = mButton->getTextSize().width + 24;
|
||||
mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22);
|
||||
|
||||
MyGUI::Button* eventbox;
|
||||
getWidget(eventbox, "EventBox");
|
||||
eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||
eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||
|
||||
LocalMapBase::init(mLocalMap, mPlayerArrow, this);
|
||||
}
|
||||
|
||||
void MapWindow::setCellName(const std::string& cellName)
|
||||
{
|
||||
setTitle(cellName);
|
||||
}
|
||||
|
||||
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
||||
{
|
||||
if (_id!=MyGUI::MouseButton::Left) return;
|
||||
|
@ -97,7 +209,10 @@ void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
|
|||
mGlobalMap->setVisible(mGlobal);
|
||||
mLocalMap->setVisible(!mGlobal);
|
||||
|
||||
mButton->setCaption( mGlobal ? "Local" : "World" );
|
||||
mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" :
|
||||
"#{sWorld}");
|
||||
int width = mButton->getTextSize().width + 24;
|
||||
mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22);
|
||||
}
|
||||
|
||||
void MapWindow::onPinToggled()
|
||||
|
|
|
@ -1,19 +1,53 @@
|
|||
#ifndef MWGUI_MAPWINDOW_H
|
||||
#define MWGUI_MAPWINDOW_H
|
||||
|
||||
#include "layouts.hpp"
|
||||
#include "window_pinnable_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class LocalMapBase
|
||||
{
|
||||
public:
|
||||
LocalMapBase();
|
||||
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop=false);
|
||||
|
||||
void setCellPrefix(const std::string& prefix);
|
||||
void setActiveCell(const int x, const int y, bool interior=false);
|
||||
void setPlayerDir(const float x, const float y);
|
||||
void setPlayerPos(const float x, const float y);
|
||||
|
||||
void toggleFogOfWar();
|
||||
|
||||
protected:
|
||||
int mCurX, mCurY;
|
||||
bool mInterior;
|
||||
MyGUI::ScrollView* mLocalMap;
|
||||
MyGUI::ImageBox* mCompass;
|
||||
std::string mPrefix;
|
||||
bool mChanged;
|
||||
bool mFogOfWar;
|
||||
|
||||
std::vector<MyGUI::ImageBox*> mMapWidgets;
|
||||
std::vector<MyGUI::ImageBox*> mFogWidgets;
|
||||
|
||||
void applyFogOfWar();
|
||||
|
||||
OEngine::GUI::Layout* mLayout;
|
||||
|
||||
bool mMapDragAndDrop;
|
||||
|
||||
float mLastPositionX;
|
||||
float mLastPositionY;
|
||||
float mLastDirectionX;
|
||||
float mLastDirectionY;
|
||||
};
|
||||
|
||||
class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase
|
||||
{
|
||||
public:
|
||||
MapWindow(WindowManager& parWindowManager);
|
||||
virtual ~MapWindow(){}
|
||||
|
||||
void setPlayerPos(const float x, const float y);
|
||||
void setPlayerDir(const float x, const float y);
|
||||
void setCellName(const std::string& cellName);
|
||||
|
||||
private:
|
||||
|
|
|
@ -15,6 +15,13 @@ void MessageBoxManager::onFrame (float frameDuration)
|
|||
std::vector<MessageBoxManagerTimer>::iterator it;
|
||||
for(it = mTimers.begin(); it != mTimers.end();)
|
||||
{
|
||||
// if this messagebox is already deleted, remove the timer and move on
|
||||
if (std::find(mMessageBoxes.begin(), mMessageBoxes.end(), it->messageBox) == mMessageBoxes.end())
|
||||
{
|
||||
it = mTimers.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
it->current += frameDuration;
|
||||
if(it->current >= it->max)
|
||||
{
|
||||
|
@ -51,7 +58,7 @@ void MessageBoxManager::onFrame (float frameDuration)
|
|||
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
|
||||
delete mInterMessageBoxe;
|
||||
mInterMessageBoxe = NULL;
|
||||
mWindowManager->setNextMode(GM_Game);
|
||||
mWindowManager->popGuiMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,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,19 +5,21 @@ namespace MWGui
|
|||
{
|
||||
enum GuiMode
|
||||
{
|
||||
GM_Game, // Game mode, only HUD
|
||||
GM_Settings, // Settings window
|
||||
GM_Inventory, // Inventory mode
|
||||
GM_Container,
|
||||
GM_MainMenu, // Main menu mode
|
||||
|
||||
GM_Console, // Console mode
|
||||
GM_Journal, // Journal mode
|
||||
|
||||
// None of the following are implemented yet
|
||||
GM_Scroll, // Read scroll
|
||||
GM_Book, // Read book
|
||||
GM_Alchemy, // Make potions
|
||||
|
||||
GM_Dialogue, // NPC interaction
|
||||
GM_Barter,
|
||||
GM_Rest,
|
||||
// .. more here ..
|
||||
|
||||
// Startup character creation dialogs
|
||||
GM_Name,
|
||||
|
|
|
@ -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);
|
||||
|
@ -69,13 +72,13 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager)
|
|||
setText("SpellPowerT", mWindowManager.getGameSettingString("sRaceMenu7", "Specials"));
|
||||
getWidget(spellPowerList, "SpellPowerList");
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked);
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
|
||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked);
|
||||
|
||||
updateRaces();
|
||||
|
@ -91,21 +94,16 @@ void RaceDialog::setNextButtonShow(bool shown)
|
|||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
|
||||
// TODO: All hardcoded coords for buttons are temporary, will be replaced with a dynamic system.
|
||||
if (shown)
|
||||
{
|
||||
okButton->setCaption("Next");
|
||||
|
||||
// Adjust back button when next is shown
|
||||
backButton->setCoord(MyGUI::IntCoord(471 - 18, 397, 53, 23));
|
||||
okButton->setCoord(MyGUI::IntCoord(532 - 18, 397, 42 + 18, 23));
|
||||
}
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sNext", ""));
|
||||
else
|
||||
{
|
||||
okButton->setCaption("OK");
|
||||
backButton->setCoord(MyGUI::IntCoord(471, 397, 53, 23));
|
||||
okButton->setCoord(MyGUI::IntCoord(532, 397, 42, 23));
|
||||
}
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
|
||||
|
||||
int okButtonWidth = okButton->getTextSize().width + 24;
|
||||
int backButtonWidth = backButton->getTextSize().width + 24;
|
||||
|
||||
okButton->setCoord(574 - okButtonWidth, 397, okButtonWidth, 23);
|
||||
backButton->setCoord(574 - okButtonWidth - backButtonWidth - 6, 397, backButtonWidth, 23);
|
||||
}
|
||||
|
||||
void RaceDialog::open()
|
||||
|
@ -260,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);
|
||||
|
||||
|
@ -293,6 +293,8 @@ void RaceDialog::updateSpellPowers()
|
|||
spellPowerWidget = spellPowerList->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i));
|
||||
spellPowerWidget->setWindowManager(&mWindowManager);
|
||||
spellPowerWidget->setSpellId(spellpower);
|
||||
spellPowerWidget->setUserString("ToolTipType", "Spell");
|
||||
spellPowerWidget->setUserString("Spell", spellpower);
|
||||
|
||||
spellPowerItems.push_back(spellPowerWidget);
|
||||
|
||||
|
|
28
apps/openmw/mwgui/referenceinterface.cpp
Normal file
28
apps/openmw/mwgui/referenceinterface.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "referenceinterface.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
ReferenceInterface::ReferenceInterface()
|
||||
: mCurrentPlayerCell(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void ReferenceInterface::checkReferenceAvailable()
|
||||
{
|
||||
if (mPtr.isEmpty())
|
||||
return;
|
||||
|
||||
MWWorld::Ptr::CellStore* playerCell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell();
|
||||
|
||||
// check if player has changed cell, or count of the reference has become 0
|
||||
if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL)
|
||||
|| mPtr.getRefData().getCount() == 0)
|
||||
onReferenceUnavailable();
|
||||
|
||||
mCurrentPlayerCell = playerCell;
|
||||
}
|
||||
}
|
29
apps/openmw/mwgui/referenceinterface.hpp
Normal file
29
apps/openmw/mwgui/referenceinterface.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef MWGUI_REFERENCEINTERFACE_H
|
||||
#define MWGUI_REFERENCEINTERFACE_H
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
/// \brief this class is intended for GUI interfaces that access an MW-Reference
|
||||
/// for example dialogue window accesses an NPC, or Container window accesses a Container
|
||||
/// these classes have to be automatically closed if the reference becomes unavailable
|
||||
/// make sure that checkReferenceAvailable() is called every frame and that onReferenceUnavailable() has been overridden
|
||||
class ReferenceInterface
|
||||
{
|
||||
public:
|
||||
ReferenceInterface();
|
||||
|
||||
void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable
|
||||
|
||||
protected:
|
||||
virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable
|
||||
|
||||
MWWorld::Ptr mPtr;
|
||||
|
||||
private:
|
||||
MWWorld::Ptr::CellStore* mCurrentPlayerCell;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,12 +1,15 @@
|
|||
#include "review.hpp"
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "components/esm_store/store.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
@ -27,22 +30,22 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
|
|||
ButtonPtr button;
|
||||
getWidget(nameWidget, "NameText");
|
||||
getWidget(button, "NameButton");
|
||||
button->setCaption(mWindowManager.getGameSettingString("sName", ""));
|
||||
adjustButtonSize(button);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);;
|
||||
|
||||
getWidget(raceWidget, "RaceText");
|
||||
getWidget(button, "RaceButton");
|
||||
button->setCaption(mWindowManager.getGameSettingString("sRace", ""));
|
||||
adjustButtonSize(button);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);;
|
||||
|
||||
getWidget(classWidget, "ClassText");
|
||||
getWidget(button, "ClassButton");
|
||||
button->setCaption(mWindowManager.getGameSettingString("sClass", ""));
|
||||
adjustButtonSize(button);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);;
|
||||
|
||||
getWidget(birthSignWidget, "SignText");
|
||||
getWidget(button, "SignButton");
|
||||
button->setCaption(mWindowManager.getGameSettingString("sBirthSign", ""));
|
||||
adjustButtonSize(button);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);;
|
||||
|
||||
// Setup dynamic stats
|
||||
|
@ -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();
|
||||
|
||||
|
@ -86,14 +89,19 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
|
|||
|
||||
static_cast<MyGUI::WindowPtr>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ReviewDialog::onWindowResize);
|
||||
|
||||
// TODO: These buttons should be managed by a Dialog class
|
||||
MyGUI::ButtonPtr backButton;
|
||||
getWidget(backButton, "BackButton");
|
||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked);
|
||||
|
||||
MyGUI::ButtonPtr okButton;
|
||||
getWidget(okButton, "OKButton");
|
||||
okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
|
||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
|
||||
|
||||
int backButtonWidth = backButton->getTextSize().width + 24;
|
||||
int okButtonWidth = okButton->getTextSize().width + 24;
|
||||
okButton->setCoord(502 - okButtonWidth, 372, okButtonWidth, 23);
|
||||
backButton->setCoord(502 - okButtonWidth - backButtonWidth - 6, 372, backButtonWidth, 23);
|
||||
}
|
||||
|
||||
void ReviewDialog::open()
|
||||
|
@ -132,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)
|
||||
|
@ -146,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)
|
||||
|
@ -181,14 +202,16 @@ void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanic
|
|||
{
|
||||
float modified = value.getModified(), base = value.getBase();
|
||||
std::string text = boost::lexical_cast<std::string>(std::floor(modified));
|
||||
ColorStyle style = CS_Normal;
|
||||
std::string state = "normal";
|
||||
if (modified > base)
|
||||
style = CS_Super;
|
||||
state = "increased";
|
||||
else if (modified < base)
|
||||
style = CS_Sub;
|
||||
state = "decreased";
|
||||
|
||||
setStyledText(widget, style, text);
|
||||
widget->setCaption(text);
|
||||
widget->_setWidgetState(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor)
|
||||
|
@ -208,22 +231,15 @@ void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vec
|
|||
if (skillSet.find(skill) == skillSet.end())
|
||||
miscSkills.push_back(skill);
|
||||
}
|
||||
}
|
||||
|
||||
void ReviewDialog::setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value)
|
||||
{
|
||||
widget->setCaption(value);
|
||||
if (style == CS_Super)
|
||||
widget->setTextColour(MyGUI::Colour(0, 1, 0));
|
||||
else if (style == CS_Sub)
|
||||
widget->setTextColour(MyGUI::Colour(1, 0, 0));
|
||||
else
|
||||
widget->setTextColour(MyGUI::Colour(1, 1, 1));
|
||||
updateSkillArea();
|
||||
}
|
||||
|
||||
void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
|
||||
separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||
|
||||
skillWidgets.push_back(separator);
|
||||
|
||||
coord1.top += separator->getHeight();
|
||||
|
@ -233,6 +249,7 @@ void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2
|
|||
void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::TextBox* groupWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default);
|
||||
groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||
groupWidget->setCaption(label);
|
||||
skillWidgets.push_back(groupWidget);
|
||||
|
||||
|
@ -240,16 +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, ColorStyle style, 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::Default);
|
||||
setStyledText(skillValueWidget, style, value);
|
||||
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);
|
||||
|
@ -260,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);
|
||||
|
||||
|
@ -295,12 +316,18 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId
|
|||
float base = stat.getBase();
|
||||
float modified = stat.getModified();
|
||||
|
||||
ColorStyle style = CS_Normal;
|
||||
std::string state = "normal";
|
||||
if (modified > base)
|
||||
style = CS_Super;
|
||||
state = "increased";
|
||||
else if (modified < base)
|
||||
style = CS_Sub;
|
||||
MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), style, coord1, coord2);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -334,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
|
||||
|
@ -367,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,19 +68,14 @@ namespace MWGui
|
|||
void onClassClicked(MyGUI::Widget* _sender);
|
||||
void onBirthSignClicked(MyGUI::Widget* _sender);
|
||||
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
|
||||
private:
|
||||
enum ColorStyle
|
||||
{
|
||||
CS_Sub,
|
||||
CS_Normal,
|
||||
CS_Super
|
||||
};
|
||||
void setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value);
|
||||
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, ColorStyle style, 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();
|
||||
|
||||
|
|
70
apps/openmw/mwgui/scrollwindow.cpp
Normal file
70
apps/openmw/mwgui/scrollwindow.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "scrollwindow.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) :
|
||||
WindowBase("openmw_scroll_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mTextView, "TextView");
|
||||
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onCloseButtonClicked);
|
||||
|
||||
getWidget(mTakeButton, "TakeButton");
|
||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked);
|
||||
|
||||
center();
|
||||
}
|
||||
|
||||
void ScrollWindow::open (MWWorld::Ptr scroll)
|
||||
{
|
||||
// no 3d sounds because the object could be in a container.
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
||||
|
||||
mScroll = scroll;
|
||||
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
mScroll.get<ESM::Book>();
|
||||
|
||||
BookTextParser parser;
|
||||
MyGUI::IntSize size = parser.parse(ref->base->text, mTextView, 390);
|
||||
|
||||
if (size.height > mTextView->getSize().height)
|
||||
mTextView->setCanvasSize(MyGUI::IntSize(410, size.height));
|
||||
else
|
||||
mTextView->setCanvasSize(410, mTextView->getSize().height);
|
||||
|
||||
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
|
||||
|
||||
setTakeButtonShow(true);
|
||||
}
|
||||
|
||||
void ScrollWindow::setTakeButtonShow(bool show)
|
||||
{
|
||||
mTakeButton->setVisible(show);
|
||||
}
|
||||
|
||||
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
||||
|
||||
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
|
||||
|
||||
MWWorld::ActionTake take(mScroll);
|
||||
take.execute();
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
}
|
32
apps/openmw/mwgui/scrollwindow.hpp
Normal file
32
apps/openmw/mwgui/scrollwindow.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef MWGUI_SCROLLWINDOW_H
|
||||
#define MWGUI_SCROLLWINDOW_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class ScrollWindow : public WindowBase
|
||||
{
|
||||
public:
|
||||
ScrollWindow (WindowManager& parWindowManager);
|
||||
|
||||
void open (MWWorld::Ptr scroll);
|
||||
void setTakeButtonShow(bool show);
|
||||
|
||||
protected:
|
||||
void onCloseButtonClicked (MyGUI::Widget* _sender);
|
||||
void onTakeButtonClicked (MyGUI::Widget* _sender);
|
||||
|
||||
private:
|
||||
MyGUI::Button* mCloseButton;
|
||||
MyGUI::Button* mTakeButton;
|
||||
MyGUI::ScrollView* mTextView;
|
||||
|
||||
MWWorld::Ptr mScroll;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
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 const float sFovMin = 30;
|
||||
static const float sFovMax = 140;
|
||||
static const float sViewDistMin = 2000;
|
||||
static const float 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
|
|
@ -1,13 +1,20 @@
|
|||
#include "stats_window.hpp"
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include "window_manager.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
|
||||
using namespace MWGui;
|
||||
const int StatsWindow::lineHeight = 18;
|
||||
|
||||
|
@ -24,11 +31,12 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
|
|||
, skillValues()
|
||||
, skillWidgetMap()
|
||||
, factionWidgetMap()
|
||||
, factions()
|
||||
, mFactions()
|
||||
, birthSignId()
|
||||
, reputation(0)
|
||||
, bounty(0)
|
||||
, skillWidgets()
|
||||
, mChanged(true)
|
||||
{
|
||||
setCoord(0,0,498, 342);
|
||||
|
||||
|
@ -42,12 +50,6 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
|
|||
{ "Attrib6", "sAttributeEndurance" },
|
||||
{ "Attrib7", "sAttributePersonality" },
|
||||
{ "Attrib8", "sAttributeLuck" },
|
||||
{ "Health_str", "sHealth" },
|
||||
{ "Magicka_str", "sMagic" },
|
||||
{ "Fatigue_str", "sFatigue" },
|
||||
{ "Level_str", "sLevel" },
|
||||
{ "Race_str", "sRace" },
|
||||
{ "Class_str", "sClass" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -60,6 +62,10 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
|
|||
getWidget(skillAreaWidget, "Skills");
|
||||
getWidget(skillClientWidget, "SkillClient");
|
||||
getWidget(skillScrollerWidget, "SkillScroller");
|
||||
getWidget(mLeftPane, "LeftPane");
|
||||
getWidget(mRightPane, "RightPane");
|
||||
|
||||
skillClientWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
|
||||
skillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &StatsWindow::onScrollChangePosition);
|
||||
updateScroller();
|
||||
|
@ -89,8 +95,22 @@ void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos)
|
|||
}
|
||||
}
|
||||
|
||||
void StatsWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (skillScrollerWidget->getScrollPosition() - _rel*0.3 < 0)
|
||||
skillScrollerWidget->setScrollPosition(0);
|
||||
else if (skillScrollerWidget->getScrollPosition() - _rel*0.3 > skillScrollerWidget->getScrollRange()-1)
|
||||
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollRange()-1);
|
||||
else
|
||||
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollPosition() - _rel*0.3);
|
||||
|
||||
onScrollChangePosition(skillScrollerWidget, skillScrollerWidget->getScrollPosition());
|
||||
}
|
||||
|
||||
void StatsWindow::onWindowResize(MyGUI::Window* window)
|
||||
{
|
||||
mLeftPane->setCoord( MyGUI::IntCoord(0, 0, 0.44*window->getSize().width, window->getSize().height) );
|
||||
mRightPane->setCoord( MyGUI::IntCoord(0.44*window->getSize().width, 0, 0.56*window->getSize().width, window->getSize().height) );
|
||||
updateScroller();
|
||||
}
|
||||
|
||||
|
@ -109,17 +129,7 @@ void StatsWindow::setBar(const std::string& name, const std::string& tname, int
|
|||
void StatsWindow::setPlayerName(const std::string& playerName)
|
||||
{
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(playerName);
|
||||
}
|
||||
|
||||
void StatsWindow::setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value)
|
||||
{
|
||||
widget->setCaption(value);
|
||||
if (style == CS_Super)
|
||||
widget->setTextColour(MyGUI::Colour(0, 1, 0));
|
||||
else if (style == CS_Sub)
|
||||
widget->setTextColour(MyGUI::Colour(1, 0, 0));
|
||||
else
|
||||
widget->setTextColour(MyGUI::Colour(1, 1, 1));
|
||||
adjustWindowCaption();
|
||||
}
|
||||
|
||||
void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
|
||||
|
@ -138,12 +148,15 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>&
|
|||
valueString << value.getModified();
|
||||
setText (id, valueString.str());
|
||||
|
||||
MyGUI::TextBox* box;
|
||||
getWidget(box, id);
|
||||
|
||||
if (value.getModified()>value.getBase())
|
||||
setTextColor (id, 0, 1, 0);
|
||||
box->_setWidgetState("increased");
|
||||
else if (value.getModified()<value.getBase())
|
||||
setTextColor (id, 1, 0, 0);
|
||||
box->_setWidgetState("decreased");
|
||||
else
|
||||
setTextColor (id, 1, 1, 1);
|
||||
box->_setWidgetState("normal");
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -158,10 +171,31 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicSta
|
|||
};
|
||||
|
||||
for (int i=0; ids[i]; ++i)
|
||||
{
|
||||
if (ids[i]==id)
|
||||
{
|
||||
std::string id (ids[i]);
|
||||
setBar (id, id + "T", value.getCurrent(), value.getModified());
|
||||
|
||||
// health, magicka, fatigue tooltip
|
||||
MyGUI::Widget* w;
|
||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||
if (i==0)
|
||||
{
|
||||
getWidget(w, "Health");
|
||||
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||
}
|
||||
else if (i==1)
|
||||
{
|
||||
getWidget(w, "Magicka");
|
||||
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||
}
|
||||
else if (i==2)
|
||||
{
|
||||
getWidget(w, "Fatigue");
|
||||
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,13 +227,14 @@ void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechani
|
|||
{
|
||||
float modified = value.getModified(), base = value.getBase();
|
||||
std::string text = boost::lexical_cast<std::string>(std::floor(modified));
|
||||
ColorStyle style = CS_Normal;
|
||||
std::string state = "normal";
|
||||
if (modified > base)
|
||||
style = CS_Super;
|
||||
state = "increased";
|
||||
else if (modified < base)
|
||||
style = CS_Sub;
|
||||
state = "decreased";
|
||||
|
||||
setStyledText(widget, style, text);
|
||||
widget->setCaption(text);
|
||||
widget->_setWidgetState(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,21 +255,50 @@ void StatsWindow::configureSkills (const std::vector<int>& major, const std::vec
|
|||
if (skillSet.find(skill) == skillSet.end())
|
||||
miscSkills.push_back(skill);
|
||||
}
|
||||
|
||||
updateSkillArea();
|
||||
}
|
||||
|
||||
void StatsWindow::setFactions (const std::vector<Faction>& factions)
|
||||
void StatsWindow::onFrame ()
|
||||
{
|
||||
this->factions = factions;
|
||||
if (mMainWidget->getVisible())
|
||||
return;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWMechanics::NpcStats PCstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||
|
||||
setFactions(PCstats.mFactionRank);
|
||||
|
||||
setBirthSign(MWBase::Environment::get().getWorld()->getPlayer().getBirthsign());
|
||||
|
||||
if (mChanged)
|
||||
updateSkillArea();
|
||||
}
|
||||
|
||||
void StatsWindow::setFactions (const FactionList& factions)
|
||||
{
|
||||
if (mFactions != factions)
|
||||
{
|
||||
mFactions = factions;
|
||||
mChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void StatsWindow::setBirthSign (const std::string& signId)
|
||||
{
|
||||
if (signId != birthSignId)
|
||||
{
|
||||
birthSignId = signId;
|
||||
mChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
|
||||
MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine",
|
||||
MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||
separator->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
skillWidgets.push_back(separator);
|
||||
|
||||
coord1.top += separator->getHeight();
|
||||
|
@ -243,23 +307,29 @@ void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
|||
|
||||
void StatsWindow::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);
|
||||
MyGUI::TextBox* groupWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText",
|
||||
MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||
groupWidget->setCaption(label);
|
||||
groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
skillWidgets.push_back(groupWidget);
|
||||
|
||||
coord1.top += lineHeight;
|
||||
coord2.top += lineHeight;
|
||||
}
|
||||
|
||||
MyGUI::TextBox* StatsWindow::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::TextBox *skillNameWidget, *skillValueWidget;
|
||||
|
||||
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default);
|
||||
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||
skillNameWidget->setCaption(text);
|
||||
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
|
||||
skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Default);
|
||||
setStyledText(skillValueWidget, style, value);
|
||||
skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Right | MyGUI::Align::Top);
|
||||
skillValueWidget->setCaption(value);
|
||||
skillValueWidget->_setWidgetState(state);
|
||||
skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
|
||||
skillWidgets.push_back(skillNameWidget);
|
||||
skillWidgets.push_back(skillValueWidget);
|
||||
|
@ -270,17 +340,20 @@ MyGUI::TextBox* StatsWindow::addValueItem(const std::string text, const std::str
|
|||
return skillValueWidget;
|
||||
}
|
||||
|
||||
void StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
{
|
||||
MyGUI::TextBox* skillNameWidget;
|
||||
|
||||
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
|
||||
skillNameWidget->setCaption(text);
|
||||
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
|
||||
|
||||
skillWidgets.push_back(skillNameWidget);
|
||||
|
||||
coord1.top += lineHeight;
|
||||
coord2.top += lineHeight;
|
||||
|
||||
return skillNameWidget;
|
||||
}
|
||||
|
||||
void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||
|
@ -304,25 +377,55 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId,
|
|||
const MWMechanics::Stat<float> &stat = skillValues.find(skillId)->second;
|
||||
float base = stat.getBase();
|
||||
float modified = stat.getModified();
|
||||
int progressPercent = (modified - float(static_cast<int>(modified))) * 100;
|
||||
|
||||
ColorStyle style = CS_Normal;
|
||||
const ESM::Skill* skill = mWindowManager.getStore().skills.search(skillId);
|
||||
assert(skill);
|
||||
|
||||
std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId];
|
||||
|
||||
const ESM::Attribute* attr = mWindowManager.getStore().attributes.search(skill->data.attribute);
|
||||
assert(attr);
|
||||
|
||||
std::string state = "normal";
|
||||
if (modified > base)
|
||||
style = CS_Super;
|
||||
state = "increased";
|
||||
else if (modified < base)
|
||||
style = CS_Sub;
|
||||
MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), style, coord1, coord2);
|
||||
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)
|
||||
{
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "SkillToolTip");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillName", "#{"+skillNameId+"}");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillDescription", skill->description);
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillAttribute", "#{sGoverningAttribute}: #{" + attr->name + "}");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ImageTexture_SkillImage", icon);
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillProgressText", boost::lexical_cast<std::string>(progressPercent)+"/100");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Range_SkillProgress", "100");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("RangePosition_SkillProgress", boost::lexical_cast<std::string>(progressPercent));
|
||||
}
|
||||
|
||||
skillWidgetMap[skillId] = widget;
|
||||
}
|
||||
}
|
||||
|
||||
void StatsWindow::updateSkillArea()
|
||||
{
|
||||
mChanged = false;
|
||||
|
||||
for (std::vector<MyGUI::WidgetPtr>::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it)
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(*it);
|
||||
}
|
||||
skillWidgets.clear();
|
||||
|
||||
skillScrollerWidget->setScrollPosition(0);
|
||||
onScrollChangePosition(skillScrollerWidget, 0);
|
||||
clientHeight = 0;
|
||||
|
||||
const int valueSize = 40;
|
||||
MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18);
|
||||
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
|
||||
|
@ -338,19 +441,75 @@ void StatsWindow::updateSkillArea()
|
|||
|
||||
const ESMS::ESMStore &store = mWindowManager.getStore();
|
||||
|
||||
if (!factions.empty())
|
||||
// race tooltip
|
||||
const ESM::Race* playerRace = store.races.find (MWBase::Environment::get().getWorld()->getPlayer().getRace());
|
||||
MyGUI::Widget* raceWidget;
|
||||
getWidget(raceWidget, "RaceText");
|
||||
ToolTips::createRaceToolTip(raceWidget, playerRace);
|
||||
getWidget(raceWidget, "Race_str");
|
||||
ToolTips::createRaceToolTip(raceWidget, playerRace);
|
||||
|
||||
// class tooltip
|
||||
MyGUI::Widget* classWidget;
|
||||
const ESM::Class& playerClass = MWBase::Environment::get().getWorld()->getPlayer().getClass();
|
||||
getWidget(classWidget, "ClassText");
|
||||
ToolTips::createClassToolTip(classWidget, playerClass);
|
||||
getWidget(classWidget, "Class_str");
|
||||
ToolTips::createClassToolTip(classWidget, playerClass);
|
||||
|
||||
if (!mFactions.empty())
|
||||
{
|
||||
// Add a line separator if there are items above
|
||||
if (!skillWidgets.empty())
|
||||
addSeparator(coord1, coord2);
|
||||
|
||||
addGroup(mWindowManager.getGameSettingString("sFaction", "Faction"), coord1, coord2);
|
||||
FactionList::const_iterator end = factions.end();
|
||||
for (FactionList::const_iterator it = factions.begin(); it != end; ++it)
|
||||
FactionList::const_iterator end = mFactions.end();
|
||||
for (FactionList::const_iterator it = mFactions.begin(); it != end; ++it)
|
||||
{
|
||||
const ESM::Faction *faction = store.factions.find(it->first);
|
||||
addItem(faction->name, coord1, coord2);
|
||||
// TODO: Faction rank should be placed in tooltip
|
||||
MyGUI::Widget* w = addItem(faction->name, coord1, coord2);
|
||||
|
||||
std::string text;
|
||||
|
||||
text += std::string("#DDC79E") + faction->name;
|
||||
text += std::string("\n#BF9959") + faction->ranks[it->second];
|
||||
|
||||
if (it->second < 9)
|
||||
{
|
||||
// player doesn't have max rank yet
|
||||
text += std::string("\n\n#DDC79E#{sNextRank} ") + faction->ranks[it->second+1];
|
||||
|
||||
ESM::RankData rankData = faction->data.rankData[it->second+1];
|
||||
const ESM::Attribute* attr1 = mWindowManager.getStore().attributes.search(faction->data.attribute1);
|
||||
const ESM::Attribute* attr2 = mWindowManager.getStore().attributes.search(faction->data.attribute2);
|
||||
assert(attr1 && attr2);
|
||||
|
||||
text += "\n#BF9959#{" + attr1->name + "}: " + boost::lexical_cast<std::string>(rankData.attribute1)
|
||||
+ ", #{" + attr2->name + "}: " + boost::lexical_cast<std::string>(rankData.attribute2);
|
||||
|
||||
text += "\n\n#DDC79E#{sFavoriteSkills}";
|
||||
text += "\n#BF9959";
|
||||
for (int i=0; i<6; ++i)
|
||||
{
|
||||
const ESM::Skill* skill = mWindowManager.getStore().skills.search(faction->data.skillID[i]);
|
||||
assert(skill);
|
||||
text += "#{"+ESM::Skill::sSkillNameIds[faction->data.skillID[i]]+"}";
|
||||
if (i<5)
|
||||
text += ", ";
|
||||
}
|
||||
|
||||
text += "\n";
|
||||
|
||||
if (rankData.skill1 > 0)
|
||||
text += "\n#{sNeedOneSkill} " + boost::lexical_cast<std::string>(rankData.skill1);
|
||||
if (rankData.skill2 > 0)
|
||||
text += "\n#{sNeedTwoSkills} " + boost::lexical_cast<std::string>(rankData.skill2);
|
||||
}
|
||||
|
||||
w->setUserString("ToolTipType", "Layout");
|
||||
w->setUserString("ToolTipLayout", "TextToolTip");
|
||||
w->setUserString("Caption_Text", text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,17 +519,36 @@ void StatsWindow::updateSkillArea()
|
|||
if (!skillWidgets.empty())
|
||||
addSeparator(coord1, coord2);
|
||||
|
||||
addGroup(mWindowManager.getGameSettingString("sSign", "Sign"), coord1, coord2);
|
||||
addGroup(mWindowManager.getGameSettingString("sBirthSign", "Sign"), coord1, coord2);
|
||||
const ESM::BirthSign *sign = store.birthSigns.find(birthSignId);
|
||||
addItem(sign->name, coord1, coord2);
|
||||
MyGUI::Widget* w = addItem(sign->name, coord1, coord2);
|
||||
|
||||
ToolTips::createBirthsignToolTip(w, birthSignId);
|
||||
}
|
||||
|
||||
// Add a line separator if there are items above
|
||||
if (!skillWidgets.empty())
|
||||
addSeparator(coord1, coord2);
|
||||
|
||||
addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"), boost::lexical_cast<std::string>(static_cast<int>(reputation)), CS_Normal, coord1, coord2);
|
||||
addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"), boost::lexical_cast<std::string>(static_cast<int>(bounty)), CS_Normal, coord1, coord2);
|
||||
addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"),
|
||||
boost::lexical_cast<std::string>(static_cast<int>(reputation)), "normal", coord1, coord2);
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sSkillsMenuReputationHelp}");
|
||||
}
|
||||
|
||||
addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"),
|
||||
boost::lexical_cast<std::string>(static_cast<int>(bounty)), "normal", coord1, coord2);
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip");
|
||||
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sCrimeHelp}");
|
||||
}
|
||||
|
||||
clientHeight = coord1.top;
|
||||
updateScroller();
|
||||
|
@ -380,6 +558,8 @@ void StatsWindow::updateScroller()
|
|||
{
|
||||
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
|
||||
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
|
||||
if (clientHeight != 0)
|
||||
skillScrollerWidget->setTrackSize( (skillAreaWidget->getHeight() / float(clientHeight)) * skillScrollerWidget->getLineSize() );
|
||||
}
|
||||
|
||||
void StatsWindow::onPinToggled()
|
||||
|
|
|
@ -18,13 +18,15 @@ namespace MWGui
|
|||
class StatsWindow : public WindowPinnableBase
|
||||
{
|
||||
public:
|
||||
typedef std::pair<std::string, int> Faction;
|
||||
typedef std::vector<Faction> FactionList;
|
||||
typedef std::map<std::string, int> FactionList;
|
||||
|
||||
typedef std::vector<int> SkillList;
|
||||
|
||||
StatsWindow(WindowManager& parWindowManager);
|
||||
|
||||
/// automatically updates all the data in the stats window, but only if it has changed.
|
||||
void onFrame();
|
||||
|
||||
void setBar(const std::string& name, const std::string& tname, int val, int max);
|
||||
void setPlayerName(const std::string& playerName);
|
||||
|
||||
|
@ -36,32 +38,30 @@ namespace MWGui
|
|||
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
||||
|
||||
void configureSkills (const SkillList& major, const SkillList& minor);
|
||||
void setFactions (const std::vector<Faction>& factions);
|
||||
void setBirthSign (const std::string &signId);
|
||||
void setReputation (int reputation) { this->reputation = reputation; }
|
||||
void setBounty (int bounty) { this->bounty = bounty; }
|
||||
void updateSkillArea();
|
||||
|
||||
private:
|
||||
enum ColorStyle
|
||||
{
|
||||
CS_Sub,
|
||||
CS_Normal,
|
||||
CS_Super
|
||||
};
|
||||
void setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value);
|
||||
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, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
MyGUI::TextBox* addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
MyGUI::Widget* addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void updateScroller();
|
||||
|
||||
void setFactions (const FactionList& factions);
|
||||
void setBirthSign (const std::string &signId);
|
||||
|
||||
void onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos);
|
||||
void onWindowResize(MyGUI::Window* window);
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
|
||||
static const int lineHeight;
|
||||
|
||||
MyGUI::Widget* mLeftPane;
|
||||
MyGUI::Widget* mRightPane;
|
||||
|
||||
MyGUI::WidgetPtr skillAreaWidget, skillClientWidget;
|
||||
MyGUI::ScrollBar* skillScrollerWidget;
|
||||
int lastPos, clientHeight;
|
||||
|
@ -70,11 +70,13 @@ namespace MWGui
|
|||
std::map<int, MWMechanics::Stat<float> > skillValues;
|
||||
std::map<int, MyGUI::TextBox*> skillWidgetMap;
|
||||
std::map<std::string, MyGUI::WidgetPtr> factionWidgetMap;
|
||||
FactionList factions; ///< Stores a list of factions and the current rank
|
||||
FactionList mFactions; ///< Stores a list of factions and the current rank
|
||||
std::string birthSignId;
|
||||
int reputation, bounty;
|
||||
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information
|
||||
|
||||
bool mChanged;
|
||||
|
||||
protected:
|
||||
virtual void onPinToggled();
|
||||
};
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue