1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-23 20:53:54 +00:00

Merge branch 'AI' of git@github.com:gugus/openmw.git into AI

This commit is contained in:
gus 2013-03-31 09:25:14 +00:00
commit e150e22652
157 changed files with 2561 additions and 871 deletions

1
.gitignore vendored
View file

@ -17,3 +17,4 @@ data
CMakeLists.txt.user CMakeLists.txt.user
*.swp *.swp
*.swo *.swo
*.kate-swp

View file

@ -15,7 +15,7 @@ include (OpenMWMacros)
# Version # Version
set (OPENMW_VERSION_MAJOR 0) set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 21) set (OPENMW_VERSION_MINOR 22)
set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
@ -257,10 +257,10 @@ set_directory_properties(PROPERTIES COMPILE_DEFINITIONS_DEBUG DEBUG=1)
# Set up Ogre plugin folder & debug suffix # Set up Ogre plugin folder & debug suffix
if (APPLE) if (APPLE)
# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) # Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt)
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="") add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="")
else () else ()
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d") add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d")
endif() endif()
add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}") add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}")
@ -278,9 +278,9 @@ add_subdirectory(files/mygui)
# Specify build paths # Specify build paths
if (APPLE) if (APPLE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${APP_BUNDLE_DIR}/Contents/MacOS") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${APP_BUNDLE_DIR}/Contents/MacOS")
else (APPLE) else (APPLE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}")
endif (APPLE) endif (APPLE)
# Other files # Other files
@ -334,7 +334,7 @@ if(DPKG_PROGRAM)
#Install icon and desktop file #Install icon and desktop file
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
#Install global configuration files #Install global configuration files
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
@ -355,7 +355,7 @@ if(DPKG_PROGRAM)
Data files from the original game is required to run it.") Data files from the original game is required to run it.")
SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") SET(CPACK_DEBIAN_PACKAGE_NAME "openmw")
SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}")
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)")
SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") SET(CPACK_DEBIAN_PACKAGE_SECTION "Games")
@ -384,6 +384,7 @@ if(WIN32)
"${OpenMW_SOURCE_DIR}/Daedric Font License.txt" "${OpenMW_SOURCE_DIR}/Daedric Font License.txt"
"${OpenMW_BINARY_DIR}/settings-default.cfg" "${OpenMW_BINARY_DIR}/settings-default.cfg"
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg" "${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
"${OpenMW_BINARY_DIR}/Release/mwiniimport.exe"
"${OpenMW_BINARY_DIR}/Release/omwlauncher.exe" "${OpenMW_BINARY_DIR}/Release/omwlauncher.exe"
"${OpenMW_BINARY_DIR}/Release/openmw.exe" "${OpenMW_BINARY_DIR}/Release/openmw.exe"
DESTINATION ".") DESTINATION ".")
@ -409,8 +410,8 @@ if(WIN32)
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org") SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org") SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe") SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.ico") SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.ico")
SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.ico") SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.ico")
SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp") SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp")
SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe") SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe")
@ -510,10 +511,10 @@ if (WIN32)
4986 # Undocumented warning that occurs in the crtdbg.h file 4986 # Undocumented warning that occurs in the crtdbg.h file
4996 # Function was declared deprecated 4996 # Function was declared deprecated
# cause by ogre extensivly # cause by ogre extensivly
4193 # #pragma warning(pop) : no matching '#pragma warning(push)' 4193 # #pragma warning(pop) : no matching '#pragma warning(push)'
4251 # class 'XXXX' needs to have dll-interface to be used by clients of class 'YYYY' 4251 # class 'XXXX' needs to have dll-interface to be used by clients of class 'YYYY'
4275 # non dll-interface struct 'XXXX' used as base for dll-interface class 'YYYY' 4275 # non dll-interface struct 'XXXX' used as base for dll-interface class 'YYYY'
# OpenMW specific warnings # OpenMW specific warnings
4099 # Type mismatch, declared class or struct is defined with other type 4099 # Type mismatch, declared class or struct is defined with other type
@ -525,7 +526,7 @@ if (WIN32)
4309 # Variable overflow, trying to store 128 in a signed char for example 4309 # Variable overflow, trying to store 128 in a signed char for example
4355 # Using 'this' in member initialization list 4355 # Using 'this' in member initialization list
4701 # Potentially uninitialized local variable used 4701 # Potentially uninitialized local variable used
4800 # Boolean optimization warning, e.g. myBool = (myInt != 0) instead of myBool = myInt 4800 # Boolean optimization warning, e.g. myBool = (myInt != 0) instead of myBool = myInt
) )
foreach(d ${WARNINGS_DISABLE}) foreach(d ${WARNINGS_DISABLE})
@ -536,12 +537,12 @@ if (WIN32)
set_target_properties(shiny.OgrePlatform PROPERTIES COMPILE_FLAGS ${WARNINGS}) set_target_properties(shiny.OgrePlatform PROPERTIES COMPILE_FLAGS ${WARNINGS})
set_target_properties(components PROPERTIES COMPILE_FLAGS ${WARNINGS}) set_target_properties(components PROPERTIES COMPILE_FLAGS ${WARNINGS})
if (BUILD_LAUNCHER) if (BUILD_LAUNCHER)
set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS ${WARNINGS}) set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS ${WARNINGS})
endif (BUILD_LAUNCHER) endif (BUILD_LAUNCHER)
set_target_properties(openmw PROPERTIES COMPILE_FLAGS ${WARNINGS}) set_target_properties(openmw PROPERTIES COMPILE_FLAGS ${WARNINGS})
if (BUILD_BSATOOL) if (BUILD_BSATOOL)
set_target_properties(bsatool PROPERTIES COMPILE_FLAGS ${WARNINGS}) set_target_properties(bsatool PROPERTIES COMPILE_FLAGS ${WARNINGS})
endif (BUILD_BSATOOL) endif (BUILD_BSATOOL)
if (BUILD_ESMTOOL) if (BUILD_ESMTOOL)
set_target_properties(esmtool PROPERTIES COMPILE_FLAGS ${WARNINGS}) set_target_properties(esmtool PROPERTIES COMPILE_FLAGS ${WARNINGS})
endif (BUILD_ESMTOOL) endif (BUILD_ESMTOOL)
@ -666,9 +667,9 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
IF(BUILD_LAUNCHER) IF(BUILD_LAUNCHER)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" ) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
ENDIF(BUILD_LAUNCHER) ENDIF(BUILD_LAUNCHER)
IF(BUILD_BSATOOL) IF(BUILD_BSATOOL)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" ) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" )
ENDIF(BUILD_BSATOOL) ENDIF(BUILD_BSATOOL)
IF(BUILD_ESMTOOL) IF(BUILD_ESMTOOL)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" ) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
ENDIF(BUILD_ESMTOOL) ENDIF(BUILD_ESMTOOL)
@ -680,7 +681,7 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
ENDIF(BUILD_OPENCS) ENDIF(BUILD_OPENCS)
# Install icon and .desktop # Install icon and .desktop
INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "${ICONDIR}") INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "${ICONDIR}")
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications")
# Install global configuration files # Install global configuration files

View file

@ -227,7 +227,7 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
std::cout << " Refnum: " << ref.mRefnum << std::endl; std::cout << " Refnum: " << ref.mRefnum << std::endl;
std::cout << " ID: '" << ref.mRefID << "'\n"; std::cout << " ID: '" << ref.mRefID << "'\n";
std::cout << " Owner: '" << ref.mOwner << "'\n"; std::cout << " Owner: '" << ref.mOwner << "'\n";
std::cout << " INTV: " << ref.mIntv << " NAM9: " << ref.mIntv << std::endl; std::cout << " Uses/health: " << ref.mCharge << " NAM9: " << ref.mNam9 << std::endl;
} }
} }

View file

@ -275,7 +275,7 @@ RecordBase::create(ESM::NAME type)
} }
case ESM::REC_LOCK: case ESM::REC_LOCK:
{ {
record = new EsmTool::Record<ESM::Tool>; record = new EsmTool::Record<ESM::Lockpick>;
break; break;
} }
case ESM::REC_LTEX: case ESM::REC_LTEX:
@ -864,14 +864,13 @@ void Record<ESM::Light>::print()
} }
template<> template<>
void Record<ESM::Tool>::print() void Record<ESM::Lockpick>::print()
{ {
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (mData.mScript != "")
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Type: " << mData.mType << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
std::cout << " Quality: " << mData.mData.mQuality << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl;
@ -886,8 +885,6 @@ void Record<ESM::Probe>::print()
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (mData.mScript != "")
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
// BUG? No Type Label?
std::cout << " Type: " << mData.mType << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
std::cout << " Quality: " << mData.mData.mQuality << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl;
@ -902,7 +899,6 @@ void Record<ESM::Repair>::print()
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (mData.mScript != "")
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Type: " << mData.mType << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
std::cout << " Quality: " << mData.mData.mQuality << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl;

View file

@ -104,7 +104,7 @@ namespace EsmTool
template<> void Record<ESM::CreatureLevList>::print(); template<> void Record<ESM::CreatureLevList>::print();
template<> void Record<ESM::ItemLevList>::print(); template<> void Record<ESM::ItemLevList>::print();
template<> void Record<ESM::Light>::print(); template<> void Record<ESM::Light>::print();
template<> void Record<ESM::Tool>::print(); template<> void Record<ESM::Lockpick>::print();
template<> void Record<ESM::Probe>::print(); template<> void Record<ESM::Probe>::print();
template<> void Record<ESM::Repair>::print(); template<> void Record<ESM::Repair>::print();
template<> void Record<ESM::LandTexture>::print(); template<> void Record<ESM::LandTexture>::print();

View file

@ -12,7 +12,7 @@ set(LAUNCHER
utils/checkablemessagebox.cpp utils/checkablemessagebox.cpp
utils/textinputdialog.cpp utils/textinputdialog.cpp
launcher.rc ${CMAKE_SOURCE_DIR}/files/launcher/launcher.rc
) )
set(LAUNCHER_HEADER set(LAUNCHER_HEADER
@ -43,10 +43,10 @@ set(LAUNCHER_HEADER_MOC
) )
set(LAUNCHER_UI set(LAUNCHER_UI
../../files/ui/datafilespage.ui ${CMAKE_SOURCE_DIR}/files/ui/datafilespage.ui
../../files/ui/graphicspage.ui ${CMAKE_SOURCE_DIR}/files/ui/graphicspage.ui
../../files/ui/mainwindow.ui ${CMAKE_SOURCE_DIR}/files/ui/mainwindow.ui
../../files/ui/playpage.ui ${CMAKE_SOURCE_DIR}/files/ui/playpage.ui
) )
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER}) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER})

View file

@ -1,6 +1,9 @@
#include "datafilespage.hpp" #include "datafilespage.hpp"
#include <QtGui> #include <QPushButton>
#include <QMessageBox>
#include <QCheckBox>
#include <QMenu>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
@ -144,7 +147,7 @@ void DataFilesPage::setupDataFiles()
profilesComboBox->addItems(profiles); profilesComboBox->addItems(profiles);
// Add the current profile if empty // Add the current profile if empty
if (profilesComboBox->findText(profile) == -1) if (profilesComboBox->findText(profile) == -1 && !profile.isEmpty())
profilesComboBox->addItem(profile); profilesComboBox->addItem(profile);
if (profilesComboBox->findText(QString("Default")) == -1) if (profilesComboBox->findText(QString("Default")) == -1)

View file

@ -1,6 +1,8 @@
#include "graphicspage.hpp" #include "graphicspage.hpp"
#include <QtGui> #include <QDesktopWidget>
#include <QMessageBox>
#include <QDir>
#include <cstdlib> #include <cstdlib>
@ -257,7 +259,7 @@ QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer)
for (opt_it = i->second.possibleValues.begin (); for (opt_it = i->second.possibleValues.begin ();
opt_it != i->second.possibleValues.end (); opt_it++, idx++) opt_it != i->second.possibleValues.end (); opt_it++, idx++)
{ {
QRegExp resolutionRe(QString("(\\d+) x (\\d+)")); QRegExp resolutionRe(QString("(\\d+) x (\\d+).*"));
QString resolution = QString::fromStdString(*opt_it).simplified(); QString resolution = QString::fromStdString(*opt_it).simplified();
if (resolutionRe.exactMatch(resolution)) { if (resolutionRe.exactMatch(resolution)) {
@ -266,16 +268,17 @@ QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer)
int height = resolutionRe.cap(2).toInt(); int height = resolutionRe.cap(2).toInt();
QString aspect = getAspect(width, height); QString aspect = getAspect(width, height);
QString cleanRes = resolutionRe.cap(1) + QString(" x ") + resolutionRe.cap(2);
if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) { if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) {
resolution.append(tr("\t(Wide ") + aspect + ")"); cleanRes.append(tr("\t(Wide ") + aspect + ")");
} else if (aspect == QLatin1String("4:3")) { } else if (aspect == QLatin1String("4:3")) {
resolution.append(tr("\t(Standard 4:3)")); cleanRes.append(tr("\t(Standard 4:3)"));
} }
// do not add duplicate resolutions // do not add duplicate resolutions
if (!result.contains(resolution)) if (!result.contains(cleanRes))
result.append(resolution); result.append(cleanRes);
} }
} }
} }

View file

@ -1 +0,0 @@
IDI_ICON1 ICON DISCARDABLE "resources/images/openmw.ico"

View file

@ -1,6 +1,15 @@
#include "maindialog.hpp" #include "maindialog.hpp"
#include <QtGui> #include <QFontDatabase>
#include <QInputDialog>
#include <QFileDialog>
#include <QCloseEvent>
#include <QTextCodec>
#include <QProcess>
#include <QFile>
#include <QDir>
#include <QDebug>
#include "utils/checkablemessagebox.hpp" #include "utils/checkablemessagebox.hpp"
@ -113,6 +122,51 @@ void MainDialog::createPages()
bool MainDialog::showFirstRunDialog() bool MainDialog::showFirstRunDialog()
{ {
QStringList iniPaths;
foreach (const QString &path, mGameSettings.getDataDirs()) {
QDir dir(path);
dir.setPath(dir.canonicalPath()); // Resolve symlinks
if (!dir.cdUp())
continue; // Cannot move from Data Files
if (dir.exists(QString("Morrowind.ini")))
iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini")));
}
// Ask the user where the Morrowind.ini is
if (iniPaths.empty()) {
QMessageBox msgBox;
msgBox.setWindowTitle(tr("Error detecting Morrowind configuration"));
msgBox.setIcon(QMessageBox::Warning);
msgBox.setStandardButtons(QMessageBox::Cancel);
msgBox.setText(QObject::tr("<br><b>Could not find Morrowind.ini</b><br><br> \
OpenMW needs to import settings from this file.<br><br> \
Press \"Browse...\" to specify the location manually.<br>"));
QAbstractButton *dirSelectButton =
msgBox.addButton(QObject::tr("B&rowse..."), QMessageBox::ActionRole);
msgBox.exec();
QString iniFile;
if (msgBox.clickedButton() == dirSelectButton) {
iniFile = QFileDialog::getOpenFileName(
NULL,
QObject::tr("Select configuration file"),
QDir::currentPath(),
QString(tr("Morrowind configuration file (*.ini)")));
}
if (iniFile.isEmpty())
return false; // Cancel was clicked;
QFileInfo info(iniFile);
iniPaths.clear();
iniPaths.append(info.absoluteFilePath());
}
CheckableMessageBox msgBox(this); CheckableMessageBox msgBox(this);
msgBox.setWindowTitle(tr("Morrowind installation detected")); msgBox.setWindowTitle(tr("Morrowind installation detected"));
@ -120,7 +174,6 @@ bool MainDialog::showFirstRunDialog()
int size = QApplication::style()->pixelMetric(QStyle::PM_MessageBoxIconSize); int size = QApplication::style()->pixelMetric(QStyle::PM_MessageBoxIconSize);
msgBox.setIconPixmap(icon.pixmap(size, size)); msgBox.setIconPixmap(icon.pixmap(size, size));
QAbstractButton *importerButton = QAbstractButton *importerButton =
msgBox.addButton(tr("Import"), QDialogButtonBox::AcceptRole); // ActionRole doesn't work?! msgBox.addButton(tr("Import"), QDialogButtonBox::AcceptRole); // ActionRole doesn't work?!
QAbstractButton *skipButton = QAbstractButton *skipButton =
@ -129,54 +182,28 @@ bool MainDialog::showFirstRunDialog()
Q_UNUSED(skipButton); // Surpress compiler unused warning Q_UNUSED(skipButton); // Surpress compiler unused warning
msgBox.setStandardButtons(QDialogButtonBox::NoButton); msgBox.setStandardButtons(QDialogButtonBox::NoButton);
msgBox.setText(tr("<br><b>An existing Morrowind configuration was detected</b><br> \
msgBox.setText(tr("<br><b>An existing Morrowind installation was detected</b><br><br> \ <br>Would you like to import settings from Morrowind.ini?<br> \
Would you like to import settings from Morrowind.ini?<br>")); <br><b>Warning: In most cases OpenMW needs these settings to run properly</b><br>"));
msgBox.setCheckBoxText(tr("Include selected masters and plugins (creates a new profile)")); msgBox.setCheckBoxText(tr("Include selected masters and plugins (creates a new profile)"));
msgBox.exec(); msgBox.exec();
if (msgBox.clickedButton() == importerButton) { if (msgBox.clickedButton() == importerButton) {
QStringList iniPaths;
foreach (const QString &path, mGameSettings.getDataDirs()) {
QDir dir(path);
dir.setPath(dir.canonicalPath()); // Resolve symlinks
if (!dir.cdUp())
continue; // Cannot move from Data Files
if (dir.exists(QString("Morrowind.ini")))
iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini")));
}
if (iniPaths.isEmpty()) {
QMessageBox msgBox;
msgBox.setWindowTitle(tr("Error reading Morrowind configuration file"));
msgBox.setIcon(QMessageBox::Warning);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setText(QObject::tr("<br><b>Could not find Morrowind.ini</b><br><br> \
The problem may be due to an incomplete installation of Morrowind.<br> \
Reinstalling Morrowind may resolve the problem."));
msgBox.exec();
return false;
}
if (iniPaths.count() > 1) { if (iniPaths.count() > 1) {
// Multiple Morrowind.ini files found // Multiple Morrowind.ini files found
bool ok; bool ok;
QString path = QInputDialog::getItem(this, tr("Multiple configurations found"), QString path = QInputDialog::getItem(this, tr("Multiple configurations found"),
tr("<br><b>There are multiple Morrowind.ini files found.</b><br><br> \ tr("<br><b>There are multiple Morrowind.ini files found.</b><br><br> \
Please select the one you wish to import from:"), iniPaths, 0, false, &ok); Please select the one you wish to import from:"), iniPaths, 0, false, &ok);
if (ok && !path.isEmpty()) { if (ok && !path.isEmpty()) {
iniPaths.clear(); iniPaths.clear();
iniPaths.append(path); iniPaths.append(path);
} else { } else {
// Cancel was clicked TODO: should we abort here? // Cancel was clicked
return false; return false;
} }
} }
// Create the file if it doesn't already exist, else the importer will fail // Create the file if it doesn't already exist, else the importer will fail
@ -204,9 +231,13 @@ bool MainDialog::showFirstRunDialog()
QStringList arguments; QStringList arguments;
if (msgBox.isChecked()) if (msgBox.isChecked())
arguments.append(QString("-g")); arguments.append(QString("--game-files"));
arguments.append(QString("--encoding"));
arguments.append(mGameSettings.value(QString("encoding"), QString("win1252")));
arguments.append(QString("--ini"));
arguments.append(iniPaths.first()); arguments.append(iniPaths.first());
arguments.append(QString("--cfg"));
arguments.append(path); arguments.append(path);
if (!startProgram(QString("mwiniimport"), arguments, false)) if (!startProgram(QString("mwiniimport"), arguments, false))
@ -218,7 +249,7 @@ bool MainDialog::showFirstRunDialog()
// Add a new profile // Add a new profile
if (msgBox.isChecked()) { if (msgBox.isChecked()) {
mLauncherSettings.setValue(QString("Profiles/CurrentProfile"), QString("Imported")); mLauncherSettings.setValue(QString("Profiles/currentprofile"), QString("Imported"));
mLauncherSettings.remove(QString("Profiles/Imported/master")); mLauncherSettings.remove(QString("Profiles/Imported/master"));
mLauncherSettings.remove(QString("Profiles/Imported/plugin")); mLauncherSettings.remove(QString("Profiles/Imported/plugin"));
@ -659,7 +690,7 @@ bool MainDialog::startProgram(const QString &name, const QStringList &arguments,
return false; return false;
} }
if (process.exitCode() != 0) { if (process.exitCode() != 0 || process.exitStatus() == QProcess::CrashExit) {
QString error(process.readAllStandardError()); QString error(process.readAllStandardError());
error.append(tr("\nArguments:\n")); error.append(tr("\nArguments:\n"));
error.append(arguments.join(" ")); error.append(arguments.join(" "));

View file

@ -1,6 +1,10 @@
#include "playpage.hpp" #include "playpage.hpp"
#include <QtGui> #include <QListView>
#ifdef Q_OS_MAC
#include <QPlastiqueStyle>
#endif
PlayPage::PlayPage(QWidget *parent) : QWidget(parent) PlayPage::PlayPage(QWidget *parent) : QWidget(parent)
{ {

View file

@ -22,3 +22,8 @@ if (BUILD_WITH_CODE_COVERAGE)
add_definitions (--coverage) add_definitions (--coverage)
target_link_libraries(mwiniimport gcov) target_link_libraries(mwiniimport gcov)
endif() endif()
if(DPKG_PROGRAM)
INSTALL(TARGETS mwiniimport RUNTIME DESTINATION games COMPONENT mwiniimport)
endif()

View file

@ -35,7 +35,7 @@ opencs_units (model/tools
) )
opencs_units_noqt (model/tools opencs_units_noqt (model/tools
stage verifier mandatoryid stage verifier mandatoryid skillcheck
) )

View file

@ -2,7 +2,7 @@
#include "document.hpp" #include "document.hpp"
#include <cassert> #include <cassert>
#include <QDebug>
void CSMDoc::Document::load (const std::vector<boost::filesystem::path>::const_iterator& begin, void CSMDoc::Document::load (const std::vector<boost::filesystem::path>::const_iterator& begin,
const std::vector<boost::filesystem::path>::const_iterator& end, bool lastAsModified) const std::vector<boost::filesystem::path>::const_iterator& end, bool lastAsModified)
{ {
@ -150,6 +150,10 @@ void CSMDoc::Document::addOptionalGlobals()
ESM::Global global; ESM::Global global;
global.mId = sGlobals[i]; global.mId = sGlobals[i];
global.mValue.setType (ESM::VT_Long); global.mValue.setType (ESM::VT_Long);
if (i==0)
global.mValue.setInteger (1); // dayspassed starts counting at 1
addOptionalGlobal (global); addOptionalGlobal (global);
} }
} }
@ -189,15 +193,25 @@ void CSMDoc::Document::createBase()
record.mId = sGlobals[i]; record.mId = sGlobals[i];
record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Int); record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Long);
if (i==0) if (i==0 || i==1)
record.mValue.setInteger (1); record.mValue.setInteger (1);
getData().getGlobals().add (record); getData().getGlobals().add (record);
} }
/// \todo add GMSTs /// \todo add GMSTs
for (int i=0; i<27; ++i)
{
ESM::Skill record;
record.mIndex = i;
record.mId = ESM::Skill::getIndexToId (record.mIndex);
record.blank();
getData().getSkills().add (record);
}
} }
CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files, bool new_) CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files, bool new_)
@ -214,7 +228,7 @@ CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files, b
if (new_ && files.size()==1) if (new_ && files.size()==1)
createBase(); createBase();
else if (files.size()>1) else
{ {
std::vector<boost::filesystem::path>::const_iterator end = files.end(); std::vector<boost::filesystem::path>::const_iterator end = files.end();

View file

@ -0,0 +1,37 @@
#include "skillcheck.hpp"
#include <sstream>
#include <components/esm/loadskil.hpp>
#include "../world/universalid.hpp"
CSMTools::SkillCheckStage::SkillCheckStage (const CSMWorld::IdCollection<ESM::Skill>& skills)
: mSkills (skills)
{}
int CSMTools::SkillCheckStage::setup()
{
return mSkills.getSize();
}
void CSMTools::SkillCheckStage::perform (int stage, std::vector<std::string>& messages)
{
const ESM::Skill& skill = mSkills.getRecord (stage).get();
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Skill, skill.mId);
for (int i=0; i<4; ++i)
if (skill.mData.mUseValue[i]<0)
{
std::ostringstream stream;
stream << id.toString() << "|Use value #" << i << " of " << skill.mId << " is negative";
messages.push_back (stream.str());
}
if (skill.mDescription.empty())
messages.push_back (id.toString() + "|" + skill.mId + " has an empty description");
}

View file

@ -0,0 +1,29 @@
#ifndef CSM_TOOLS_SKILLCHECK_H
#define CSM_TOOLS_SKILLCHECK_H
#include <components/esm/loadskil.hpp>
#include "../world/idcollection.hpp"
#include "stage.hpp"
namespace CSMTools
{
/// \brief VerifyStage: make sure that skill records are internally consistent
class SkillCheckStage : public Stage
{
const CSMWorld::IdCollection<ESM::Skill>& mSkills;
public:
SkillCheckStage (const CSMWorld::IdCollection<ESM::Skill>& skills);
virtual int setup();
///< \return number of steps
virtual void perform (int stage, std::vector<std::string>& messages);
///< Messages resulting from this tage will be appended to \a messages.
};
}
#endif

View file

@ -12,6 +12,7 @@
#include "reportmodel.hpp" #include "reportmodel.hpp"
#include "mandatoryid.hpp" #include "mandatoryid.hpp"
#include "skillcheck.hpp"
CSMTools::Operation *CSMTools::Tools::get (int type) CSMTools::Operation *CSMTools::Tools::get (int type)
{ {
@ -51,6 +52,8 @@ CSMTools::Verifier *CSMTools::Tools::getVerifier()
mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(), mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(),
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds)); CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
mVerifier->appendStage (new SkillCheckStage (mData.getSkills()));
} }
return mVerifier; return mVerifier;

View file

@ -31,7 +31,9 @@ namespace CSMWorld
Display_Float, Display_Float,
Display_Var, Display_Var,
Display_GmstVarType, Display_GmstVarType,
Display_GlobalVarType Display_GlobalVarType,
Display_Specialisation,
Display_Attribute
}; };
std::string mTitle; std::string mTitle;

View file

@ -1,6 +1,8 @@
#ifndef CSM_WOLRD_COLUMNS_H #ifndef CSM_WOLRD_COLUMNS_H
#define CSM_WOLRD_COLUMNS_H #define CSM_WOLRD_COLUMNS_H
#include <boost/lexical_cast.hpp>
#include "columnbase.hpp" #include "columnbase.hpp"
namespace CSMWorld namespace CSMWorld
@ -35,7 +37,7 @@ namespace CSMWorld
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
return record.get().mId.c_str(); return QString::fromUtf8 (record.get().mId.c_str());
} }
virtual bool isEditable() const virtual bool isEditable() const
@ -127,17 +129,17 @@ namespace CSMWorld
{ {
case ESM::VT_String: case ESM::VT_String:
return record.get().mValue.getString().c_str(); break; return QString::fromUtf8 (record.get().mValue.getString().c_str());
case ESM::VT_Int: case ESM::VT_Int:
case ESM::VT_Short: case ESM::VT_Short:
case ESM::VT_Long: case ESM::VT_Long:
return record.get().mValue.getInteger(); break; return record.get().mValue.getInteger();
case ESM::VT_Float: case ESM::VT_Float:
return record.get().mValue.getFloat(); break; return record.get().mValue.getFloat();
default: return QVariant(); default: return QVariant();
} }
@ -177,6 +179,112 @@ namespace CSMWorld
return true; return true;
} }
}; };
template<typename ESXRecordT>
struct DescriptionColumn : public Column<ESXRecordT>
{
DescriptionColumn() : Column<ESXRecordT> ("Description", ColumnBase::Display_String) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return QString::fromUtf8 (record.get().mDescription.c_str());
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mDescription = data.toString().toUtf8().constData();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct SpecialisationColumn : public Column<ESXRecordT>
{
SpecialisationColumn() : Column<ESXRecordT> ("Specialisation", ColumnBase::Display_Specialisation) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mData.mSpecialization;
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mSpecialization = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct UseValueColumn : public Column<ESXRecordT>
{
int mIndex;
UseValueColumn (int index)
: Column<ESXRecordT> ("Use value #" + boost::lexical_cast<std::string> (index),
ColumnBase::Display_Float), mIndex (index)
{}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mData.mUseValue[mIndex];
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mUseValue[mIndex] = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct AttributeColumn : public Column<ESXRecordT>
{
AttributeColumn() : Column<ESXRecordT> ("Attribute", ColumnBase::Display_Attribute) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mData.mAttribute;
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mAttribute = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
} }
#endif #endif

View file

@ -1,7 +1,7 @@
#include "commands.hpp" #include "commands.hpp"
#include <QAbstractTableModel> #include <QAbstractItemModel>
#include "idtableproxymodel.hpp" #include "idtableproxymodel.hpp"
#include "idtable.hpp" #include "idtable.hpp"

View file

@ -3,7 +3,7 @@
#include <stdexcept> #include <stdexcept>
#include <QAbstractTableModel> #include <QAbstractItemModel>
#include <components/esm/esmreader.hpp> #include <components/esm/esmreader.hpp>
#include <components/esm/defs.hpp> #include <components/esm/defs.hpp>
@ -12,7 +12,7 @@
#include "idtable.hpp" #include "idtable.hpp"
#include "columns.hpp" #include "columns.hpp"
void CSMWorld::Data::addModel (QAbstractTableModel *model, UniversalId::Type type1, void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1,
UniversalId::Type type2) UniversalId::Type type2)
{ {
mModels.push_back (model); mModels.push_back (model);
@ -36,13 +36,22 @@ CSMWorld::Data::Data()
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType)); mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>); mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
mSkills.addColumn (new StringIdColumn<ESM::Skill>);
mSkills.addColumn (new RecordStateColumn<ESM::Skill>);
mSkills.addColumn (new AttributeColumn<ESM::Skill>);
mSkills.addColumn (new SpecialisationColumn<ESM::Skill>);
for (int i=0; i<4; ++i)
mSkills.addColumn (new UseValueColumn<ESM::Skill> (i));
mSkills.addColumn (new DescriptionColumn<ESM::Skill>);
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
} }
CSMWorld::Data::~Data() CSMWorld::Data::~Data()
{ {
for (std::vector<QAbstractTableModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter) for (std::vector<QAbstractItemModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
delete *iter; delete *iter;
} }
@ -66,9 +75,19 @@ CSMWorld::IdCollection<ESM::GameSetting>& CSMWorld::Data::getGmsts()
return mGmsts; return mGmsts;
} }
QAbstractTableModel *CSMWorld::Data::getTableModel (const UniversalId& id) const CSMWorld::IdCollection<ESM::Skill>& CSMWorld::Data::getSkills() const
{ {
std::map<UniversalId::Type, QAbstractTableModel *>::iterator iter = mModelIndex.find (id.getType()); return mSkills;
}
CSMWorld::IdCollection<ESM::Skill>& CSMWorld::Data::getSkills()
{
return mSkills;
}
QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
{
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
if (iter==mModelIndex.end()) if (iter==mModelIndex.end())
throw std::logic_error ("No table model available for " + id.toString()); throw std::logic_error ("No table model available for " + id.toString());
@ -102,7 +121,7 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base)
{ {
case ESM::REC_GLOB: mGlobals.load (reader, base); break; case ESM::REC_GLOB: mGlobals.load (reader, base); break;
case ESM::REC_GMST: mGmsts.load (reader, base); break; case ESM::REC_GMST: mGmsts.load (reader, base); break;
case ESM::REC_SKIL: mSkills.load (reader, base); break;
default: default:

View file

@ -8,11 +8,12 @@
#include <components/esm/loadglob.hpp> #include <components/esm/loadglob.hpp>
#include <components/esm/loadgmst.hpp> #include <components/esm/loadgmst.hpp>
#include <components/esm/loadskil.hpp>
#include "idcollection.hpp" #include "idcollection.hpp"
#include "universalid.hpp" #include "universalid.hpp"
class QAbstractTableModel; class QAbstractItemModel;
namespace CSMWorld namespace CSMWorld
{ {
@ -20,14 +21,15 @@ namespace CSMWorld
{ {
IdCollection<ESM::Global> mGlobals; IdCollection<ESM::Global> mGlobals;
IdCollection<ESM::GameSetting> mGmsts; IdCollection<ESM::GameSetting> mGmsts;
std::vector<QAbstractTableModel *> mModels; IdCollection<ESM::Skill> mSkills;
std::map<UniversalId::Type, QAbstractTableModel *> mModelIndex; std::vector<QAbstractItemModel *> mModels;
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
// not implemented // not implemented
Data (const Data&); Data (const Data&);
Data& operator= (const Data&); Data& operator= (const Data&);
void addModel (QAbstractTableModel *model, UniversalId::Type type1, void addModel (QAbstractItemModel *model, UniversalId::Type type1,
UniversalId::Type type2 = UniversalId::Type_None); UniversalId::Type type2 = UniversalId::Type_None);
public: public:
@ -44,7 +46,11 @@ namespace CSMWorld
IdCollection<ESM::GameSetting>& getGmsts(); IdCollection<ESM::GameSetting>& getGmsts();
QAbstractTableModel *getTableModel (const UniversalId& id); const IdCollection<ESM::Skill>& getSkills() const;
IdCollection<ESM::Skill>& getSkills();
QAbstractItemModel *getTableModel (const UniversalId& id);
///< If no table model is available for \a id, an exception is thrown. ///< If no table model is available for \a id, an exception is thrown.
/// ///
/// \note The returned table may either be the model for the ID itself or the model that /// \note The returned table may either be the model for the ID itself or the model that

View file

@ -74,6 +74,8 @@ namespace CSMWorld
virtual const RecordBase& getRecord (const std::string& id) const = 0; virtual const RecordBase& getRecord (const std::string& id) const = 0;
virtual const RecordBase& getRecord (int index) const = 0;
virtual void load (ESM::ESMReader& reader, bool base) = 0; virtual void load (ESM::ESMReader& reader, bool base) = 0;
}; };
@ -139,7 +141,9 @@ namespace CSMWorld
/// ///
/// \attention Throw san exception, if the type of \a record does not match. /// \attention Throw san exception, if the type of \a record does not match.
virtual const RecordBase& getRecord (const std::string& id) const; virtual const Record<ESXRecordT>& getRecord (const std::string& id) const;
virtual const Record<ESXRecordT>& getRecord (int index) const;
virtual void load (ESM::ESMReader& reader, bool base); virtual void load (ESM::ESMReader& reader, bool base);
@ -373,11 +377,18 @@ namespace CSMWorld
} }
template<typename ESXRecordT> template<typename ESXRecordT>
const RecordBase& IdCollection<ESXRecordT>::getRecord (const std::string& id) const const Record<ESXRecordT>& IdCollection<ESXRecordT>::getRecord (const std::string& id) const
{ {
int index = getIndex (id); int index = getIndex (id);
return mRecords.at (index); return mRecords.at (index);
} }
template<typename ESXRecordT>
const Record<ESXRecordT>& IdCollection<ESXRecordT>::getRecord (int index) const
{
return mRecords.at (index);
}
} }
#endif #endif

View file

@ -96,6 +96,25 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren
return true; return true;
} }
QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const
{
if (parent.isValid())
return QModelIndex();
if (row<0 || row>=mIdCollection->getSize())
return QModelIndex();
if (column<0 || column>=mIdCollection->getColumns())
return QModelIndex();
return createIndex (row, column);
}
QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const
{
return QModelIndex();
}
void CSMWorld::IdTable::addRecord (const std::string& id) void CSMWorld::IdTable::addRecord (const std::string& id)
{ {
int index = mIdCollection->getSize(); int index = mIdCollection->getSize();

View file

@ -1,14 +1,14 @@
#ifndef CSM_WOLRD_IDTABLE_H #ifndef CSM_WOLRD_IDTABLE_H
#define CSM_WOLRD_IDTABLE_H #define CSM_WOLRD_IDTABLE_H
#include <QAbstractTableModel> #include <QAbstractItemModel>
namespace CSMWorld namespace CSMWorld
{ {
class IdCollectionBase; class IdCollectionBase;
class RecordBase; class RecordBase;
class IdTable : public QAbstractTableModel class IdTable : public QAbstractItemModel
{ {
Q_OBJECT Q_OBJECT
@ -39,6 +39,11 @@ namespace CSMWorld
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex())
const;
virtual QModelIndex parent (const QModelIndex& index) const;
void addRecord (const std::string& id); void addRecord (const std::string& id);
QModelIndex getModelIndex (const std::string& id, int column) const; QModelIndex getModelIndex (const std::string& id, int column) const;

View file

@ -62,7 +62,7 @@ namespace CSMWorld
if (mState==State_Erased) if (mState==State_Erased)
throw std::logic_error ("attempt to access a deleted record"); throw std::logic_error ("attempt to access a deleted record");
return mState==State_BaseOnly ? mBase : mModified; return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified;
} }
template <typename ESXRecordT> template <typename ESXRecordT>
@ -81,9 +81,7 @@ namespace CSMWorld
throw std::logic_error ("attempt to modify a deleted record"); throw std::logic_error ("attempt to modify a deleted record");
mModified = modified; mModified = modified;
mState = State_Modified;
if (mState!=State_ModifiedOnly)
mState = mBase==mModified ? State_BaseOnly : State_Modified;
} }
template <typename ESXRecordT> template <typename ESXRecordT>

View file

@ -19,6 +19,7 @@ namespace
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
}; };
@ -27,6 +28,7 @@ namespace
{ {
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
}; };
@ -43,7 +45,7 @@ CSMWorld::UniversalId::UniversalId (const std::string& universalId)
{ {
std::string::size_type index = universalId.find (':'); std::string::size_type index = universalId.find (':');
if (index==std::string::npos) if (index!=std::string::npos)
{ {
std::string type = universalId.substr (0, index); std::string type = universalId.substr (0, index);

View file

@ -37,8 +37,9 @@ namespace CSMWorld
Type_Global, Type_Global,
Type_VerificationResults, Type_VerificationResults,
Type_Gmsts, Type_Gmsts,
Type_Gmst Type_Gmst,
Type_Skills,
Type_Skill
}; };
private: private:

View file

@ -86,6 +86,10 @@ void CSVDoc::View::setupWorldMenu()
connect (gmsts, SIGNAL (triggered()), this, SLOT (addGmstsSubView())); connect (gmsts, SIGNAL (triggered()), this, SLOT (addGmstsSubView()));
world->addAction (gmsts); world->addAction (gmsts);
QAction *skills = new QAction (tr ("Skills"), this);
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
world->addAction (skills);
mVerify = new QAction (tr ("&Verify"), this); mVerify = new QAction (tr ("&Verify"), this);
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify())); connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
world->addAction (mVerify); world->addAction (mVerify);
@ -244,6 +248,11 @@ void CSVDoc::View::addGmstsSubView()
addSubView (CSMWorld::UniversalId::Type_Gmsts); addSubView (CSMWorld::UniversalId::Type_Gmsts);
} }
void CSVDoc::View::addSkillsSubView()
{
addSubView (CSMWorld::UniversalId::Type_Skills);
}
void CSVDoc::View::abortOperation (int type) void CSVDoc::View::abortOperation (int type)
{ {
mDocument->abortOperation (type); mDocument->abortOperation (type);

View file

@ -116,6 +116,7 @@ namespace CSVDoc
void addGmstsSubView(); void addGmstsSubView();
void addSkillsSubView();
}; };
} }

View file

@ -38,6 +38,17 @@ void CSVDoc::ViewManager::updateIndices()
CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
: mDocumentManager (documentManager), mExitOnSaveStateChange(false), mUserWarned(false) : mDocumentManager (documentManager), mExitOnSaveStateChange(false), mUserWarned(false)
{ {
static const char *sSpecialisations[] =
{
"Combat", "Magic", "Stealth", 0
};
static const char *sAttributes[] =
{
"Strength", "Intelligence", "Willpower", "Agility", "Speed", "Endurance", "Personality",
"Luck", 0
};
mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection;
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType,
@ -45,6 +56,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType, mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType,
new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float)); new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float));
mDelegateFactories->add (CSMWorld::ColumnBase::Display_Specialisation,
new CSVWorld::EnumDelegateFactory (sSpecialisations));
mDelegateFactories->add (CSMWorld::ColumnBase::Display_Attribute,
new CSVWorld::EnumDelegateFactory (sAttributes));
} }
CSVDoc::ViewManager::~ViewManager() CSVDoc::ViewManager::~ViewManager()

View file

@ -3,7 +3,7 @@
#include <QGridLayout> #include <QGridLayout>
#include <QLabel> #include <QLabel>
#include <QAbstractTableModel> #include <QAbstractItemModel>
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include <QSpinBox> #include <QSpinBox>
#include <QLineEdit> #include <QLineEdit>
@ -24,7 +24,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
widget->setLayout (layout); widget->setLayout (layout);
QAbstractTableModel *model = document.getData().getTableModel (id); QAbstractItemModel *model = document.getData().getTableModel (id);
int columns = model->columnCount(); int columns = model->columnCount();

View file

@ -1,6 +1,7 @@
#include "enumdelegate.hpp" #include "enumdelegate.hpp"
#include <cassert>
#include <stdexcept> #include <stdexcept>
#include <QComboBox> #include <QComboBox>
@ -89,6 +90,16 @@ void CSVWorld::EnumDelegate::paint (QPainter *painter, const QStyleOptionViewIte
} }
CSVWorld::EnumDelegateFactory::EnumDelegateFactory() {}
CSVWorld::EnumDelegateFactory::EnumDelegateFactory (const char **names)
{
assert (names);
for (int i=0; names[i]; ++i)
add (i, names[i]);
}
CSVWorld::CommandDelegate *CSVWorld::EnumDelegateFactory::makeDelegate (QUndoStack& undoStack, CSVWorld::CommandDelegate *CSVWorld::EnumDelegateFactory::makeDelegate (QUndoStack& undoStack,
QObject *parent) const QObject *parent) const
{ {

View file

@ -45,6 +45,11 @@ namespace CSVWorld
public: public:
EnumDelegateFactory();
EnumDelegateFactory (const char **names);
///< \param names Array of char pointer with a 0-pointer as end mark
virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const; virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const;
///< The ownership of the returned CommandDelegate is transferred to the caller. ///< The ownership of the returned CommandDelegate is transferred to the caller.

View file

@ -14,6 +14,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
manager.add (CSMWorld::UniversalId::Type_Gmsts, manager.add (CSMWorld::UniversalId::Type_Gmsts,
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false)); new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
manager.add (CSMWorld::UniversalId::Type_Skills,
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
manager.add (CSMWorld::UniversalId::Type_Global, manager.add (CSMWorld::UniversalId::Type_Global,
new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true)); new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
} }

View file

@ -31,6 +31,7 @@ add_openmw_dir (mwgui
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
merchantrepair repair
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue
@ -53,7 +54,7 @@ add_openmw_dir (mwworld
containerstore actiontalk actiontake manualref player cellfunctors failedaction containerstore actiontalk actiontake manualref player cellfunctors failedaction
cells localscripts customdata weather inventorystore ptr actionopen actionread cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp esmstore store recordcmp fallback actionrepair
) )
add_openmw_dir (mwclass add_openmw_dir (mwclass
@ -64,7 +65,7 @@ add_openmw_dir (mwclass
add_openmw_dir (mwmechanics add_openmw_dir (mwmechanics
mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators
drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
aiescort aiactivate aiescort aiactivate repair
) )
add_openmw_dir (mwbase add_openmw_dir (mwbase

View file

@ -41,6 +41,8 @@ namespace MWBase
virtual void goodbyeSelected() = 0; virtual void goodbyeSelected() = 0;
virtual void questionAnswered (const std::string& answer) = 0; virtual void questionAnswered (const std::string& answer) = 0;
virtual bool checkServiceRefused () = 0;
virtual void persuade (int type) = 0; virtual void persuade (int type) = 0;
virtual int getTemporaryDispositionChange () const = 0; virtual int getTemporaryDispositionChange () const = 0;
virtual void applyTemporaryDispositionChange (int delta) = 0; virtual void applyTemporaryDispositionChange (int delta) = 0;

View file

@ -91,6 +91,8 @@ namespace MWBase
virtual bool isGuiMode() const = 0; virtual bool isGuiMode() const = 0;
virtual bool isConsoleMode() const = 0;
virtual void toggleVisible (MWGui::GuiWindow wnd) = 0; virtual void toggleVisible (MWGui::GuiWindow wnd) = 0;
/// Disallow all inventory mode windows /// Disallow all inventory mode windows
@ -236,6 +238,8 @@ namespace MWBase
virtual void startSpellMaking(MWWorld::Ptr actor) = 0; virtual void startSpellMaking(MWWorld::Ptr actor) = 0;
virtual void startEnchanting(MWWorld::Ptr actor) = 0; virtual void startEnchanting(MWWorld::Ptr actor) = 0;
virtual void startTraining(MWWorld::Ptr actor) = 0; virtual void startTraining(MWWorld::Ptr actor) = 0;
virtual void startRepair(MWWorld::Ptr actor) = 0;
virtual void startRepairItem(MWWorld::Ptr item) = 0;
virtual void changePointer (const std::string& name) = 0; virtual void changePointer (const std::string& name) = 0;

View file

@ -46,6 +46,7 @@ namespace MWRender
namespace MWWorld namespace MWWorld
{ {
class Fallback;
class CellStore; class CellStore;
class Player; class Player;
class LocalScripts; class LocalScripts;
@ -103,11 +104,7 @@ namespace MWBase
virtual void getTriangleBatchCount(unsigned int &triangles, unsigned int &batches) = 0; virtual void getTriangleBatchCount(unsigned int &triangles, unsigned int &batches) = 0;
virtual void setFallbackValues (const std::map<std::string, std::string>& fallbackMap) = 0; virtual const MWWorld::Fallback *getFallback () const = 0;
virtual std::string getFallback (const std::string& key) const = 0;
virtual std::string getFallback (const std::string& key, const std::string& def) const = 0;
virtual MWWorld::Player& getPlayer() = 0; virtual MWWorld::Player& getPlayer() = 0;

View file

@ -247,8 +247,9 @@ namespace MWClass
text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor); text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor);
/// \todo store the current armor health somewhere int remainingHealth = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mHealth;
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/"
+ MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")"; text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")";
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");

View file

@ -191,6 +191,12 @@ namespace MWClass
return info; return info;
} }
float Creature::getArmorRating (const MWWorld::Ptr& ptr) const
{
/// \todo add Shield magic effect magnitude here, controlled by a GMST (Vanilla vs MCP behaviour)
return 0.f;
}
float Creature::getCapacity (const MWWorld::Ptr& ptr) const float Creature::getCapacity (const MWWorld::Ptr& ptr) const
{ {
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
@ -203,9 +209,9 @@ namespace MWClass
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (8)).mMagnitude; // feather weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Feather)).mMagnitude;
weight += stats.getMagicEffects().get (MWMechanics::EffectKey (7)).mMagnitude; // burden weight += stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Burden)).mMagnitude;
if (weight<0) if (weight<0)
weight = 0; weight = 0;

View file

@ -54,6 +54,9 @@ namespace MWClass
///< Returns total weight of objects inside this object (including modifications from magic ///< Returns total weight of objects inside this object (including modifications from magic
/// effects). Throws an exception, if the object can't hold other objects. /// effects). Throws an exception, if the object can't hold other objects.
virtual float getArmorRating (const MWWorld::Ptr& ptr) const;
///< @return combined armor rating of this actor
virtual bool isEssential (const MWWorld::Ptr& ptr) const; virtual bool isEssential (const MWWorld::Ptr& ptr) const;
///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable)

View file

@ -1,7 +1,7 @@
#include "lockpick.hpp" #include "lockpick.hpp"
#include <components/esm/loadlocks.hpp> #include <components/esm/loadlock.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -41,8 +41,8 @@ namespace MWClass
std::string Lockpick::getModel(const MWWorld::Ptr &ptr) const std::string Lockpick::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Lockpick>();
assert(ref->mBase != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->mBase->mModel; const std::string &model = ref->mBase->mModel;
@ -54,8 +54,8 @@ namespace MWClass
std::string Lockpick::getName (const MWWorld::Ptr& ptr) const std::string Lockpick::getName (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Lockpick>();
return ref->mBase->mName; return ref->mBase->mName;
} }
@ -75,8 +75,8 @@ namespace MWClass
std::string Lockpick::getScript (const MWWorld::Ptr& ptr) const std::string Lockpick::getScript (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Lockpick>();
return ref->mBase->mScript; return ref->mBase->mScript;
} }
@ -92,8 +92,8 @@ namespace MWClass
int Lockpick::getValue (const MWWorld::Ptr& ptr) const int Lockpick::getValue (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Lockpick>();
return ref->mBase->mData.mValue; return ref->mBase->mData.mValue;
} }
@ -102,7 +102,7 @@ namespace MWClass
{ {
boost::shared_ptr<Class> instance (new Lockpick); boost::shared_ptr<Class> instance (new Lockpick);
registerClass (typeid (ESM::Tool).name(), instance); registerClass (typeid (ESM::Lockpick).name(), instance);
} }
std::string Lockpick::getUpSoundId (const MWWorld::Ptr& ptr) const std::string Lockpick::getUpSoundId (const MWWorld::Ptr& ptr) const
@ -117,24 +117,24 @@ namespace MWClass
std::string Lockpick::getInventoryIcon (const MWWorld::Ptr& ptr) const std::string Lockpick::getInventoryIcon (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Lockpick>();
return ref->mBase->mIcon; return ref->mBase->mIcon;
} }
bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Lockpick>();
return (ref->mBase->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Lockpick>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
@ -142,9 +142,9 @@ namespace MWClass
std::string text; std::string text;
/// \todo store remaining uses somewhere int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses;
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
@ -171,8 +171,8 @@ namespace MWClass
MWWorld::Ptr MWWorld::Ptr
Lockpick::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const Lockpick::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Lockpick>();
return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell); return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell);
} }

View file

@ -471,9 +471,9 @@ namespace MWClass
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (8)).mMagnitude; // feather weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Feather)).mMagnitude;
weight += stats.getMagicEffects().get (MWMechanics::EffectKey (7)).mMagnitude; // burden weight += stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Burden)).mMagnitude;
if (weight<0) if (weight<0)
weight = 0; weight = 0;
@ -505,12 +505,75 @@ namespace MWClass
stats.useSkill (skill, *class_, usageType); stats.useSkill (skill, *class_, usageType);
} }
float Npc::getArmorRating (const MWWorld::Ptr& ptr) const
{
MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore(ptr);
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
int ratings[MWWorld::InventoryStore::Slots];
int iBaseArmorSkill = gmst.find("iBaseArmorSkill")->getInt();
float fUnarmoredBase1 = gmst.find("fUnarmoredBase1")->getFloat();
float fUnarmoredBase2 = gmst.find("fUnarmoredBase2")->getFloat();
int unarmoredSkill = MWWorld::Class::get(ptr).getNpcStats(ptr).getSkill(ESM::Skill::Unarmored).getModified();
for (int i = 0; i < MWWorld::InventoryStore::Slots; ++i)
{
MWWorld::ContainerStoreIterator it = invStore.getSlot(i);
if (it == invStore.end() || it->getTypeName() != typeid(ESM::Armor).name())
{
// unarmored
ratings[i] = (fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill);
}
else
{
MWWorld::LiveCellRef<ESM::Armor> *ref =
it->get<ESM::Armor>();
int armorSkillType = MWWorld::Class::get(*it).getEquipmentSkill(*it);
int armorSkill = MWWorld::Class::get(ptr).getNpcStats(ptr).getSkill(armorSkillType).getModified();
if (ref->mBase->mData.mWeight == 0)
ratings[i] = ref->mBase->mData.mArmor;
else
ratings[i] = ref->mBase->mData.mArmor * armorSkill / iBaseArmorSkill;
}
}
float shield = MWWorld::Class::get(ptr).getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).mMagnitude;
return ratings[MWWorld::InventoryStore::Slot_Cuirass] * 0.3
+ (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet]
+ ratings[MWWorld::InventoryStore::Slot_Greaves] + ratings[MWWorld::InventoryStore::Slot_Boots]
+ ratings[MWWorld::InventoryStore::Slot_LeftPauldron] + ratings[MWWorld::InventoryStore::Slot_RightPauldron]
) * 0.1
+ (ratings[MWWorld::InventoryStore::Slot_LeftGauntlet] + MWWorld::InventoryStore::Slot_RightGauntlet)
* 0.05
+ shield;
}
void Npc::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const void Npc::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const
{ {
y = 0; y = 0;
x = 0; x = 0;
} }
void Npc::adjustScale(const MWWorld::Ptr &ptr, float &scale) const
{
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
const ESM::Race* race =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(ref->mBase->mRace);
if (ref->mBase->isMale())
scale *= race->mData.mHeight.mMale;
else
scale *= race->mData.mHeight.mFemale;
}
MWWorld::Ptr MWWorld::Ptr
Npc::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const Npc::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{ {

View file

@ -81,7 +81,7 @@ namespace MWClass
virtual bool getStance (const MWWorld::Ptr& ptr, Stance stance, bool ignoreForce = false) virtual bool getStance (const MWWorld::Ptr& ptr, Stance stance, bool ignoreForce = false)
const; const;
////< Check if a stance is active or not. ///< Check if a stance is active or not.
virtual float getSpeed (const MWWorld::Ptr& ptr) const; virtual float getSpeed (const MWWorld::Ptr& ptr) const;
///< Return movement speed. ///< Return movement speed.
@ -104,12 +104,17 @@ namespace MWClass
///< Returns total weight of objects inside this object (including modifications from magic ///< Returns total weight of objects inside this object (including modifications from magic
/// effects). Throws an exception, if the object can't hold other objects. /// effects). Throws an exception, if the object can't hold other objects.
virtual float getArmorRating (const MWWorld::Ptr& ptr) const;
///< @return combined armor rating of this actor
virtual bool apply (const MWWorld::Ptr& ptr, const std::string& id, virtual bool apply (const MWWorld::Ptr& ptr, const std::string& id,
const MWWorld::Ptr& actor) const; const MWWorld::Ptr& actor) const;
///< Apply \a id on \a ptr. ///< Apply \a id on \a ptr.
/// \param actor Actor that is resposible for the ID being applied to \a ptr. /// \param actor Actor that is resposible for the ID being applied to \a ptr.
/// \return Any effect? /// \return Any effect?
virtual void adjustScale (const MWWorld::Ptr &ptr, float &scale) const;
virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const; virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const;
///< Inform actor \a ptr that a skill use has succeeded. ///< Inform actor \a ptr that a skill use has succeeded.

View file

@ -1,7 +1,7 @@
#include "probe.hpp" #include "probe.hpp"
#include <components/esm/loadlocks.hpp> #include <components/esm/loadprob.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -141,9 +141,9 @@ namespace MWClass
std::string text; std::string text;
/// \todo store remaining uses somewhere int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses;
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");

View file

@ -1,7 +1,7 @@
#include "repair.hpp" #include "repair.hpp"
#include <components/esm/loadlocks.hpp> #include <components/esm/loadrepa.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -12,6 +12,7 @@
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp" #include "../mwworld/physicssystem.hpp"
#include "../mwworld/nullaction.hpp" #include "../mwworld/nullaction.hpp"
#include "../mwworld/actionrepair.hpp"
#include "../mwgui/tooltips.hpp" #include "../mwgui/tooltips.hpp"
@ -120,6 +121,19 @@ namespace MWClass
return (ref->mBase->mName != ""); return (ref->mBase->mName != "");
} }
bool Repair::hasItemHealth (const MWWorld::Ptr& ptr) const
{
return true;
}
int Repair::getItemMaxHealth (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return ref->mBase->mData.mUses;
}
MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
@ -131,9 +145,9 @@ namespace MWClass
std::string text; std::string text;
/// \todo store remaining uses somewhere int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses;
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
@ -156,4 +170,9 @@ namespace MWClass
return MWWorld::Ptr(&cell.mRepairs.insert(*ref), &cell); return MWWorld::Ptr(&cell.mRepairs.insert(*ref), &cell);
} }
boost::shared_ptr<MWWorld::Action> Repair::use (const MWWorld::Ptr& ptr) const
{
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRepair(ptr));
}
} }

View file

@ -49,6 +49,18 @@ namespace MWClass
///< Return name of inventory icon. ///< Return name of inventory icon.
virtual std::string getModel(const MWWorld::Ptr &ptr) const; virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const;
///< Generate action for using via inventory menu (default implementation: return a
/// null action).
virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const;
///< \return Item health data available? (default implementation: false)
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
///< Return item max health or throw an exception, if class does not have item health
/// (default implementation: throw an exceoption)
}; };
} }

View file

@ -75,7 +75,10 @@ namespace MWClass
bool Weapon::hasItemHealth (const MWWorld::Ptr& ptr) const bool Weapon::hasItemHealth (const MWWorld::Ptr& ptr) const
{ {
return true; MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return (ref->mBase->mData.mType < 11); // thrown weapons and arrows/bolts don't have health, only quantity
} }
int Weapon::getItemMaxHealth (const MWWorld::Ptr& ptr) const int Weapon::getItemMaxHealth (const MWWorld::Ptr& ptr) const
@ -334,9 +337,12 @@ namespace MWClass
} }
} }
/// \todo store the current weapon health somewhere
if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); {
int remainingHealth = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mHealth;
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/"
+ MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
}
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");

View file

@ -241,7 +241,7 @@ namespace MWDialogue
} }
} }
void DialogueManager::executeTopic (const std::string& topic) void DialogueManager::executeTopic (const std::string& topic, bool randomResponse)
{ {
Filter filter (mActor, mChoice, mTalkedTo); Filter filter (mActor, mChoice, mTalkedTo);
@ -256,7 +256,7 @@ namespace MWDialogue
if (!infos.empty()) if (!infos.empty())
{ {
const ESM::DialInfo* info = infos[std::rand() % infos.size()]; const ESM::DialInfo* info = infos[randomResponse ? std::rand() % infos.size() : 0];
parseText (info->mResponse); parseText (info->mResponse);
@ -367,6 +367,9 @@ namespace MWDialogue
if (services & ESM::NPC::Enchanting) if (services & ESM::NPC::Enchanting)
windowServices |= MWGui::DialogueWindow::Service_Enchant; windowServices |= MWGui::DialogueWindow::Service_Enchant;
if (services & ESM::NPC::Repair)
windowServices |= MWGui::DialogueWindow::Service_Repair;
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->setServices (windowServices); win->setServices (windowServices);
@ -505,7 +508,7 @@ namespace MWDialogue
text = "Bribe"; text = "Bribe";
} }
executeTopic (text + (success ? " Success" : " Fail")); executeTopic (text + (success ? " Success" : " Fail"), true);
} }
int DialogueManager::getTemporaryDispositionChange() const int DialogueManager::getTemporaryDispositionChange() const
@ -518,6 +521,37 @@ namespace MWDialogue
mTemporaryDispositionChange += delta; mTemporaryDispositionChange += delta;
} }
bool DialogueManager::checkServiceRefused()
{
Filter filter (mActor, mChoice, mTalkedTo);
const MWWorld::Store<ESM::Dialogue> &dialogues =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
const ESM::Dialogue& dialogue = *dialogues.find ("Service Refusal");
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
std::vector<const ESM::DialInfo *> infos = filter.list (dialogue, false, false, true);
if (!infos.empty())
{
const ESM::DialInfo* info = infos[0];
parseText (info->mResponse);
const MWWorld::Store<ESM::GameSetting>& gmsts =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
win->addTitle (gmsts.find ("sServiceRefusal")->getString());
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
executeScript (info->mResultScript);
return true;
}
return false;
}
std::vector<HyperTextToken> ParseHyperText(const std::string& text) std::vector<HyperTextToken> ParseHyperText(const std::string& text)
{ {
std::vector<HyperTextToken> result; std::vector<HyperTextToken> result;

View file

@ -48,7 +48,7 @@ namespace MWDialogue
void printError (const std::string& error); void printError (const std::string& error);
void executeTopic (const std::string& topic); void executeTopic (const std::string& topic, bool randomResponse=false);
public: public:
@ -65,6 +65,8 @@ namespace MWDialogue
virtual MWWorld::Ptr getActor() const; virtual MWWorld::Ptr getActor() const;
///< Return the actor the player is currently talking to. ///< Return the actor the player is currently talking to.
virtual bool checkServiceRefused ();
//calbacks for the GUI //calbacks for the GUI
virtual void keywordSelected (const std::string& keyword); virtual void keywordSelected (const std::string& keyword);
virtual void goodbyeSelected(); virtual void goodbyeSelected();

View file

@ -121,7 +121,7 @@ bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const
return true; return true;
} }
bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info) const bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info, bool invert) const
{ {
bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name()); bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name());
@ -129,14 +129,19 @@ bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info) const
return true; return true;
int actorDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor); int actorDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor);
// For service refusal, the disposition check is inverted. However, a value of 0 still means "always succeed".
return actorDisposition >= info.mData.mDisposition; return invert ? (info.mData.mDisposition == 0 || actorDisposition < info.mData.mDisposition)
: (actorDisposition >= info.mData.mDisposition);
} }
bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
{ {
if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name()) if (select.isNpcOnly() && (mActor.getTypeName() != typeid (ESM::NPC).name()))
return select.isInverted(); // If the actor is a creature, we do not test the conditions applicable
// only to NPCs. Such conditions can never be satisfied, apart
// inverted ones (NotClass, NotRace, NotFaction return true
// because creatures are not of any race, class or faction).
return select.getType() == SelectWrapper::Type_Inverted;
switch (select.getType()) switch (select.getType())
{ {
@ -144,6 +149,9 @@ bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
case SelectWrapper::Type_Integer: return select.selectCompare (getSelectStructInteger (select)); case SelectWrapper::Type_Integer: return select.selectCompare (getSelectStructInteger (select));
case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select); case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select);
case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select)); case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select));
// We must not do the comparison for inverted functions (eg. Function_NotClass)
case SelectWrapper::Type_Inverted: return getSelectStructBoolean (select);
} }
return true; return true;
@ -412,25 +420,49 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
return false; return false;
case SelectWrapper::Function_Id: case SelectWrapper::Function_NotId:
return select.getName()==Misc::StringUtils::lowerCase (MWWorld::Class::get (mActor).getId (mActor)); return select.getName()!=Misc::StringUtils::lowerCase (MWWorld::Class::get (mActor).getId (mActor));
case SelectWrapper::Function_Faction: case SelectWrapper::Function_NotFaction:
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mFaction)==select.getName(); return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mFaction)!=select.getName();
case SelectWrapper::Function_Class: case SelectWrapper::Function_NotClass:
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mClass)==select.getName(); return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mClass)!=select.getName();
case SelectWrapper::Function_Race: case SelectWrapper::Function_NotRace:
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mRace)==select.getName(); return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mRace)!=select.getName();
case SelectWrapper::Function_Cell: case SelectWrapper::Function_NotCell:
return Misc::StringUtils::lowerCase (mActor.getCell()->mCell->mName)==select.getName(); return Misc::StringUtils::lowerCase (mActor.getCell()->mCell->mName)!=select.getName();
case SelectWrapper::Function_NotLocal:
{
std::string scriptName = MWWorld::Class::get (mActor).getScript (mActor);
if (scriptName.empty())
// This actor has no attached script, so there is no local variable
return true;
const ESM::Script *script =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (scriptName);
std::string name = select.getName();
int i = 0;
for (; i < static_cast<int> (script->mVarNames.size()); ++i)
if (Misc::StringUtils::lowerCase(script->mVarNames[i]) == name)
break;
if (i >= static_cast<int> (script->mVarNames.size()))
return true; // script does not have a variable of this name
return false;
}
case SelectWrapper::Function_SameGender: case SelectWrapper::Function_SameGender:
@ -458,7 +490,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
case SelectWrapper::Function_PcCorprus: case SelectWrapper::Function_PcCorprus:
return MWWorld::Class::get (player).getCreatureStats (player). return MWWorld::Class::get (player).getCreatureStats (player).
getMagicEffects().get (132).mMagnitude!=0; getMagicEffects().get (ESM::MagicEffect::Corprus).mMagnitude!=0;
case SelectWrapper::Function_PcExpelled: case SelectWrapper::Function_PcExpelled:
{ {
@ -570,7 +602,7 @@ const ESM::DialInfo* MWDialogue::Filter::search (const ESM::Dialogue& dialogue,
} }
std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue& dialogue, std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue& dialogue,
bool fallbackToInfoRefusal, bool searchAll) const bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const
{ {
std::vector<const ESM::DialInfo *> infos; std::vector<const ESM::DialInfo *> infos;
@ -582,7 +614,7 @@ std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue
{ {
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter)) if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
{ {
if (testDisposition (*iter)) { if (testDisposition (*iter, invertDisposition)) {
infos.push_back(&*iter); infos.push_back(&*iter);
if (!searchAll) if (!searchAll)
break; break;
@ -604,7 +636,7 @@ std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue
for (std::vector<ESM::DialInfo>::const_iterator iter = infoRefusalDialogue.mInfo.begin(); for (std::vector<ESM::DialInfo>::const_iterator iter = infoRefusalDialogue.mInfo.begin();
iter!=infoRefusalDialogue.mInfo.end(); ++iter) iter!=infoRefusalDialogue.mInfo.end(); ++iter)
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter)) { if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter, invertDisposition)) {
infos.push_back(&*iter); infos.push_back(&*iter);
if (!searchAll) if (!searchAll)
break; break;

View file

@ -30,8 +30,8 @@ namespace MWDialogue
bool testSelectStructs (const ESM::DialInfo& info) const; bool testSelectStructs (const ESM::DialInfo& info) const;
///< Are all select structs matching? ///< Are all select structs matching?
bool testDisposition (const ESM::DialInfo& info) const; bool testDisposition (const ESM::DialInfo& info, bool invert=false) const;
///< Is the actor disposition toward the player high enough? ///< Is the actor disposition toward the player high enough (or low enough, if \a invert is true)?
bool testSelectStruct (const SelectWrapper& select) const; bool testSelectStruct (const SelectWrapper& select) const;
@ -54,7 +54,7 @@ namespace MWDialogue
Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer); Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
std::vector<const ESM::DialInfo *> list (const ESM::Dialogue& dialogue, std::vector<const ESM::DialInfo *> list (const ESM::Dialogue& dialogue,
bool fallbackToInfoRefusal, bool searchAll) const; bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition=false) const;
const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const; const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
///< Get a matching response for the requested dialogue. ///< Get a matching response for the requested dialogue.

View file

@ -112,12 +112,12 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con
case '4': return Function_Journal; case '4': return Function_Journal;
case '5': return Function_Item; case '5': return Function_Item;
case '6': return Function_Dead; case '6': return Function_Dead;
case '7': return Function_Id; case '7': return Function_NotId;
case '8': return Function_Faction; case '8': return Function_NotFaction;
case '9': return Function_Class; case '9': return Function_NotClass;
case 'A': return Function_Race; case 'A': return Function_NotRace;
case 'B': return Function_Cell; case 'B': return Function_NotCell;
case 'C': return Function_Local; case 'C': return Function_NotLocal;
} }
return Function_None; return Function_None;
@ -219,7 +219,6 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
static const Function booleanFunctions[] = static const Function booleanFunctions[] =
{ {
Function_False, Function_False,
Function_Id, Function_Faction, Function_Class, Function_Race, Function_Cell,
Function_SameGender, Function_SameRace, Function_SameFaction, Function_SameGender, Function_SameRace, Function_SameFaction,
Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus,
Function_PcExpelled, Function_PcExpelled,
@ -231,6 +230,13 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
Function_None // end marker Function_None // end marker
}; };
static const Function invertedBooleanFunctions[] =
{
Function_NotId, Function_NotFaction, Function_NotClass,
Function_NotRace, Function_NotCell, Function_NotLocal,
Function_None // end marker
};
Function function = getFunction(); Function function = getFunction();
for (int i=0; integerFunctions[i]!=Function_None; ++i) for (int i=0; integerFunctions[i]!=Function_None; ++i)
@ -245,21 +251,18 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
if (booleanFunctions[i]==function) if (booleanFunctions[i]==function)
return Type_Boolean; return Type_Boolean;
for (int i=0; invertedBooleanFunctions[i]!=Function_None; ++i)
if (invertedBooleanFunctions[i]==function)
return Type_Inverted;
return Type_None; return Type_None;
} }
bool MWDialogue::SelectWrapper::isInverted() const
{
char type = mSelect.mSelectRule[1];
return type=='7' || type=='8' || type=='9' || type=='A' || type=='B' || type=='C';
}
bool MWDialogue::SelectWrapper::isNpcOnly() const bool MWDialogue::SelectWrapper::isNpcOnly() const
{ {
static const Function functions[] = static const Function functions[] =
{ {
Function_Faction, SelectWrapper::Function_Class, SelectWrapper::Function_Race, Function_NotFaction, Function_NotClass, Function_NotRace,
Function_SameGender, Function_SameRace, Function_SameFaction, Function_SameGender, Function_SameRace, Function_SameFaction,
Function_PcSkill, Function_PcSkill,
Function_PcExpelled, Function_PcExpelled,
@ -283,17 +286,17 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const
bool MWDialogue::SelectWrapper::selectCompare (int value) const bool MWDialogue::SelectWrapper::selectCompare (int value) const
{ {
return selectCompareImp (mSelect, value)!=isInverted(); // logic XOR return selectCompareImp (mSelect, value);
} }
bool MWDialogue::SelectWrapper::selectCompare (float value) const bool MWDialogue::SelectWrapper::selectCompare (float value) const
{ {
return selectCompareImp (mSelect, value)!=isInverted(); // logic XOR return selectCompareImp (mSelect, value);
} }
bool MWDialogue::SelectWrapper::selectCompare (bool value) const bool MWDialogue::SelectWrapper::selectCompare (bool value) const
{ {
return selectCompareImp (mSelect, static_cast<int> (value))!=isInverted(); // logic XOR return selectCompareImp (mSelect, static_cast<int> (value));
} }
std::string MWDialogue::SelectWrapper::getName() const std::string MWDialogue::SelectWrapper::getName() const

View file

@ -17,11 +17,12 @@ namespace MWDialogue
Function_Journal, Function_Journal,
Function_Item, Function_Item,
Function_Dead, Function_Dead,
Function_Id, Function_NotId,
Function_Faction, Function_NotFaction,
Function_Class, Function_NotClass,
Function_Race, Function_NotRace,
Function_Cell, Function_NotCell,
Function_NotLocal,
Function_Local, Function_Local,
Function_Global, Function_Global,
Function_SameGender, Function_SameRace, Function_SameFaction, Function_SameGender, Function_SameRace, Function_SameFaction,
@ -50,7 +51,8 @@ namespace MWDialogue
Type_None, Type_None,
Type_Integer, Type_Integer,
Type_Numeric, Type_Numeric,
Type_Boolean Type_Boolean,
Type_Inverted
}; };
private: private:
@ -67,8 +69,6 @@ namespace MWDialogue
Type getType() const; Type getType() const;
bool isInverted() const;
bool isNpcOnly() const; bool isNpcOnly() const;
///< \attention Do not call any of the select functions for this select struct! ///< \attention Do not call any of the select functions for this select struct!

View file

@ -12,6 +12,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/fallback.hpp"
namespace namespace
{ {
@ -23,14 +24,13 @@ namespace
}; };
const ESM::Class::Specialization mSpecializations[3]={ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}; // The specialization for each answer const ESM::Class::Specialization mSpecializations[3]={ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}; // The specialization for each answer
Step sGenerateClassSteps(int number) { Step sGenerateClassSteps(int number) {
MWBase::World *world = MWBase::Environment::get().getWorld();
number++; number++;
Step step = {world->getFallback("Question_"+boost::lexical_cast<std::string>(number)+"_Question"), const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback();
{world->getFallback("Question_"+boost::lexical_cast<std::string>(number)+"_AnswerOne"), Step step = {fallback->getFallbackString("Question_"+boost::lexical_cast<std::string>(number)+"_Question"),
world->getFallback("Question_"+boost::lexical_cast<std::string>(number)+"_AnswerTwo"), {fallback->getFallbackString("Question_"+boost::lexical_cast<std::string>(number)+"_AnswerOne"),
world->getFallback("Question_"+boost::lexical_cast<std::string>(number)+"_AnswerThree")}, fallback->getFallbackString("Question_"+boost::lexical_cast<std::string>(number)+"_AnswerTwo"),
fallback->getFallbackString("Question_"+boost::lexical_cast<std::string>(number)+"_AnswerThree")},
"vo\\misc\\chargen qa"+boost::lexical_cast<std::string>(number)+".wav" "vo\\misc\\chargen qa"+boost::lexical_cast<std::string>(number)+".wav"
}; };
return step; return step;
@ -674,9 +674,6 @@ void CharacterCreation::showClassQuestionDialog()
void CharacterCreation::onGenerateClassBack() void CharacterCreation::onGenerateClassBack()
{ {
if(mCreationStage < CSE_ClassChosen)
mCreationStage = CSE_ClassChosen;
mWM->removeDialog(mGenerateClassResultDialog); mWM->removeDialog(mGenerateClassResultDialog);
mGenerateClassResultDialog = 0; mGenerateClassResultDialog = 0;

View file

@ -45,7 +45,7 @@ namespace
mapping.push_back( typeid(ESM::Book).name() ); mapping.push_back( typeid(ESM::Book).name() );
mapping.push_back( typeid(ESM::Light).name() ); mapping.push_back( typeid(ESM::Light).name() );
mapping.push_back( typeid(ESM::Miscellaneous).name() ); mapping.push_back( typeid(ESM::Miscellaneous).name() );
mapping.push_back( typeid(ESM::Tool).name() ); mapping.push_back( typeid(ESM::Lockpick).name() );
mapping.push_back( typeid(ESM::Repair).name() ); mapping.push_back( typeid(ESM::Repair).name() );
mapping.push_back( typeid(ESM::Probe).name() ); mapping.push_back( typeid(ESM::Probe).name() );
@ -683,12 +683,18 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
// transfer everything into the player's inventory // transfer everything into the player's inventory
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
std::vector<MWWorld::Ptr> equippedItems = getEquippedItems();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player); MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);
int i=0; int i=0;
for (MWWorld::ContainerStoreIterator iter (containerStore.begin()); iter!=containerStore.end(); ++iter) for (MWWorld::ContainerStoreIterator iter (containerStore.begin()); iter!=containerStore.end(); ++iter)
{ {
if (std::find(equippedItems.begin(), equippedItems.end(), *iter) != equippedItems.end()
&& !mDisplayEquippedItems)
continue;
playerStore.add(*iter); playerStore.add(*iter);
if (i==0) if (i==0)
@ -698,11 +704,11 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
} }
iter->getRefData().setCount(0);
++i; ++i;
} }
containerStore.clear();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
} }
} }

View file

@ -175,6 +175,9 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
if (!mEnabled && color == "#572D21") if (!mEnabled && color == "#572D21")
MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
if (!mEnabled)
return;
if(color != "#B29154") if(color != "#B29154")
{ {
MyGUI::UString key = mHistory->getColorTextAt(cursorPosition); MyGUI::UString key = mHistory->getColorTextAt(cursorPosition);
@ -227,54 +230,61 @@ void DialogueWindow::onSelectTopic(const std::string& topic, int id)
{ {
if (!mEnabled) return; if (!mEnabled) return;
int separatorPos = mTopicsList->getItemCount(); int separatorPos = 0;
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i) for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
{ {
if (mTopicsList->getItemNameAt(i) == "") if (mTopicsList->getItemNameAt(i) == "")
separatorPos = i; separatorPos = i;
} }
if (id > separatorPos) if (id >= separatorPos)
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
else else
{ {
const MWWorld::Store<ESM::GameSetting> &gmst = const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>(); MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
if (topic == gmst.find("sBarter")->getString())
{
/// \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);
}
if (topic == gmst.find("sPersuasion")->getString()) if (topic == gmst.find("sPersuasion")->getString())
{ {
mPersuasionDialog.setVisible(true); mPersuasionDialog.setVisible(true);
} }
else if (topic == gmst.find("sSpells")->getString()) else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused())
{ {
mWindowManager.pushGuiMode(GM_SpellBuying); if (topic == gmst.find("sBarter")->getString())
mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); {
} mWindowManager.pushGuiMode(GM_Barter);
else if (topic == gmst.find("sTravel")->getString()) mWindowManager.getTradeWindow()->startTrade(mPtr);
{ }
mWindowManager.pushGuiMode(GM_Travel); else if (topic == gmst.find("sSpells")->getString())
mWindowManager.getTravelWindow()->startTravel(mPtr); {
} mWindowManager.pushGuiMode(GM_SpellBuying);
else if (topic == gmst.find("sSpellMakingMenuTitle")->getString()) mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr);
{ }
mWindowManager.pushGuiMode(GM_SpellCreation); else if (topic == gmst.find("sTravel")->getString())
mWindowManager.startSpellMaking (mPtr); {
} mWindowManager.pushGuiMode(GM_Travel);
else if (topic == gmst.find("sEnchanting")->getString()) mWindowManager.getTravelWindow()->startTravel(mPtr);
{ }
mWindowManager.pushGuiMode(GM_Enchanting); else if (topic == gmst.find("sSpellMakingMenuTitle")->getString())
mWindowManager.startEnchanting (mPtr); {
} mWindowManager.pushGuiMode(GM_SpellCreation);
else if (topic == gmst.find("sServiceTrainingTitle")->getString()) mWindowManager.startSpellMaking (mPtr);
{ }
mWindowManager.pushGuiMode(GM_Training); else if (topic == gmst.find("sEnchanting")->getString())
mWindowManager.startTraining (mPtr); {
mWindowManager.pushGuiMode(GM_Enchanting);
mWindowManager.startEnchanting (mPtr);
}
else if (topic == gmst.find("sServiceTrainingTitle")->getString())
{
mWindowManager.pushGuiMode(GM_Training);
mWindowManager.startTraining (mPtr);
}
else if (topic == gmst.find("sRepair")->getString())
{
mWindowManager.pushGuiMode(GM_MerchantRepair);
mWindowManager.startRepair (mPtr);
}
} }
} }
} }
@ -322,6 +332,9 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
if (mServices & Service_Training) if (mServices & Service_Training)
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString()); mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
if (mServices & Service_Repair)
mTopicsList->addItem(gmst.find("sRepair")->getString());
if (anyService || mPtr.getTypeName() == typeid(ESM::NPC).name()) if (anyService || mPtr.getTypeName() == typeid(ESM::NPC).name())
mTopicsList->addSeparator(); mTopicsList->addSeparator();
@ -376,10 +389,17 @@ std::string DialogueWindow::parseText(const std::string& text)
std::vector<std::string> topics; std::vector<std::string> topics;
bool hasSeparator = false;
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
{
if (mTopicsList->getItemNameAt(i) == "")
hasSeparator = true;
}
for(unsigned int i = 0;i<mTopicsList->getItemCount();i++) for(unsigned int i = 0;i<mTopicsList->getItemCount();i++)
{ {
std::string keyWord = mTopicsList->getItemNameAt(i); std::string keyWord = mTopicsList->getItemNameAt(i);
if (separatorReached) if (separatorReached || !hasSeparator)
topics.push_back(keyWord); topics.push_back(keyWord);
else if (keyWord == "") else if (keyWord == "")
separatorReached = true; separatorReached = true;

View file

@ -81,7 +81,8 @@ namespace MWGui
Service_CreateSpells = 0x04, Service_CreateSpells = 0x04,
Service_Enchant = 0x08, Service_Enchant = 0x08,
Service_Training = 0x10, Service_Training = 0x10,
Service_Travel = 0x20 Service_Travel = 0x20,
Service_Repair = 0x40
}; };
protected: protected:

View file

@ -13,6 +13,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
@ -50,6 +51,7 @@ namespace MWGui
getWidget(mFilterMisc, "MiscButton"); getWidget(mFilterMisc, "MiscButton");
getWidget(mLeftPane, "LeftPane"); getWidget(mLeftPane, "LeftPane");
getWidget(mRightPane, "RightPane"); getWidget(mRightPane, "RightPane");
getWidget(mArmorRating, "ArmorRating");
mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked); mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
@ -288,6 +290,9 @@ namespace MWGui
mPreview.update (size.width, size.height); mPreview.update (size.width, size.height);
mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024))); mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024)));
mAvatarImage->setImageTexture("CharacterPreview"); mAvatarImage->setImageTexture("CharacterPreview");
mArmorRating->setCaptionWithReplacing ("#{sArmor}: "
+ boost::lexical_cast<std::string>(static_cast<int>(MWWorld::Class::get(mPtr).getArmorRating(mPtr))));
} }
void InventoryWindow::pickUpObject (MWWorld::Ptr object) void InventoryWindow::pickUpObject (MWWorld::Ptr object)
@ -303,7 +308,7 @@ namespace MWGui
&& (type != typeid(ESM::Ingredient).name()) && (type != typeid(ESM::Ingredient).name())
&& (type != typeid(ESM::Light).name()) && (type != typeid(ESM::Light).name())
&& (type != typeid(ESM::Miscellaneous).name()) && (type != typeid(ESM::Miscellaneous).name())
&& (type != typeid(ESM::Tool).name()) && (type != typeid(ESM::Lockpick).name())
&& (type != typeid(ESM::Probe).name()) && (type != typeid(ESM::Probe).name())
&& (type != typeid(ESM::Repair).name()) && (type != typeid(ESM::Repair).name())
&& (type != typeid(ESM::Weapon).name()) && (type != typeid(ESM::Weapon).name())

View file

@ -9,6 +9,7 @@
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "../mwworld/fallback.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
@ -138,9 +139,9 @@ namespace MWGui
std::string levelupdescription; std::string levelupdescription;
if(level>20) if(level>20)
levelupdescription=world->getFallback("Level_Up_Default"); levelupdescription=world->getFallback()->getFallbackString("Level_Up_Default");
else else
levelupdescription=world->getFallback("Level_Up_Level"+boost::lexical_cast<std::string>(level)); levelupdescription=world->getFallback()->getFallbackString("Level_Up_Level"+boost::lexical_cast<std::string>(level));
mLevelDescription->setCaption (levelupdescription); mLevelDescription->setCaption (levelupdescription);

View file

@ -190,8 +190,8 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(counter)); widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(counter));
markerWidget->setImageResource("DoorMarker"); markerWidget->setImageResource("DoorMarker");
markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTip"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_Text", marker.name); markerWidget->setUserString("Caption_TextOneLine", marker.name);
markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserString("IsMarker", "true");
markerWidget->eventMouseSetFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerFocused); markerWidget->eventMouseSetFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerFocused);
markerWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerUnfocused); markerWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerUnfocused);
@ -323,16 +323,16 @@ void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(_counter)); widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(_counter));
markerWidget->setImageResource("DoorMarker"); markerWidget->setImageResource("DoorMarker");
markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTip"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_Text", name); markerWidget->setUserString("Caption_TextOneLine", name);
++_counter; ++_counter;
markerWidget = mEventBoxGlobal->createWidget<MyGUI::Button>("", markerWidget = mEventBoxGlobal->createWidget<MyGUI::Button>("",
widgetCoord, MyGUI::Align::Default); widgetCoord, MyGUI::Align::Default);
markerWidget->setNeedMouseFocus (true); markerWidget->setNeedMouseFocus (true);
markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTip"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_Text", name); markerWidget->setUserString("Caption_TextOneLine", name);
} }
void MapWindow::cellExplored(int x, int y) void MapWindow::cellExplored(int x, int y)

View file

@ -0,0 +1,132 @@
#include "merchantrepair.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "list.hpp"
#include "inventorywindow.hpp"
#include "tradewindow.hpp"
namespace MWGui
{
MerchantRepair::MerchantRepair(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_merchantrepair.layout", parWindowManager)
{
getWidget(mList, "RepairView");
getWidget(mOkButton, "OkButton");
getWidget(mGoldLabel, "PlayerGold");
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onOkButtonClick);
}
void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
{
mActor = actor;
while (mList->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mList->getChildAt(0));
int currentY = 0;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
for (MWWorld::ContainerStoreIterator iter (store.begin());
iter!=store.end(); ++iter)
{
if (MWWorld::Class::get(*iter).hasItemHealth(*iter))
{
int maxDurability = MWWorld::Class::get(*iter).getItemMaxHealth(*iter);
int durability = (iter->getCellRef().mCharge == -1) ? maxDurability : iter->getCellRef().mCharge;
if (maxDurability == durability)
continue;
int basePrice = MWWorld::Class::get(*iter).getValue(*iter);
float fRepairMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("fRepairMult")->getFloat();
float p = std::max(1, basePrice);
float r = std::max(1, static_cast<int>(maxDurability / p));
int x = ((maxDurability - durability) / r);
x = (fRepairMult * x);
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mActor, x, true);
std::string name = MWWorld::Class::get(*iter).getName(*iter)
+ " - " + boost::lexical_cast<std::string>(price)
+ MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("sgp")->getString();;
MyGUI::Button* button =
mList->createWidget<MyGUI::Button>(
(price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton",
0,
currentY,
0,
18,
MyGUI::Align::Default
);
currentY += 18;
button->setEnabled(price<=mWindowManager.getInventoryWindow()->getPlayerGold());
button->setUserString("Price", boost::lexical_cast<std::string>(price));
button->setUserData(*iter);
button->setCaptionWithReplacing(name);
button->setSize(button->getTextSize().width,18);
button->eventMouseWheel += MyGUI::newDelegate(this, &MerchantRepair::onMouseWheel);
button->setUserString("ToolTipType", "ItemPtr");
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onRepairButtonClick);
}
}
mList->setCanvasSize (MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY)));
mGoldLabel->setCaptionWithReplacing("#{sGold}: "
+ boost::lexical_cast<std::string>(mWindowManager.getInventoryWindow()->getPlayerGold()));
}
void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mList->getViewOffset().top + _rel*0.3 > 0)
mList->setViewOffset(MyGUI::IntPoint(0, 0));
else
mList->setViewOffset(MyGUI::IntPoint(0, mList->getViewOffset().top + _rel*0.3));
}
void MerchantRepair::open()
{
center();
}
void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
{
// repair
MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>();
item.getCellRef().mCharge = MWWorld::Class::get(item).getItemMaxHealth(item);
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);
int price = boost::lexical_cast<int>(sender->getUserString("Price"));
mWindowManager.getTradeWindow()->addOrRemoveGold(-price);
startRepair(mActor);
}
void MerchantRepair::onOkButtonClick(MyGUI::Widget *sender)
{
mWindowManager.removeGuiMode(GM_MerchantRepair);
}
}

View file

@ -0,0 +1,37 @@
#ifndef OPENMW_MWGUI_MERCHANTREPAIR_H
#define OPENMW_MWGUI_MERCHANTREPAIR_H
#include "window_base.hpp"
#include "../mwworld/ptr.hpp"
namespace MWGui
{
class MerchantRepair : public WindowBase
{
public:
MerchantRepair(MWBase::WindowManager &parWindowManager);
virtual void open();
void startRepair(const MWWorld::Ptr& actor);
private:
MyGUI::ScrollView* mList;
MyGUI::Button* mOkButton;
MyGUI::TextBox* mGoldLabel;
MWWorld::Ptr mActor;
protected:
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
void onRepairButtonClick(MyGUI::Widget* sender);
void onOkButtonClick(MyGUI::Widget* sender);
};
}
#endif

View file

@ -16,6 +16,7 @@ namespace MWGui
GM_Scroll, // Read scroll GM_Scroll, // Read scroll
GM_Book, // Read book GM_Book, // Read book
GM_Alchemy, // Make potions GM_Alchemy, // Make potions
GM_Repair,
GM_Dialogue, // NPC interaction GM_Dialogue, // NPC interaction
GM_Barter, GM_Barter,
@ -26,6 +27,7 @@ namespace MWGui
GM_SpellCreation, GM_SpellCreation,
GM_Enchanting, GM_Enchanting,
GM_Training, GM_Training,
GM_MerchantRepair,
GM_Levelup, GM_Levelup,

View file

@ -0,0 +1,157 @@
#include "repair.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "widgets.hpp"
namespace MWGui
{
Repair::Repair(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_repair.layout", parWindowManager)
{
getWidget(mRepairBox, "RepairBox");
getWidget(mRepairView, "RepairView");
getWidget(mToolBox, "ToolBox");
getWidget(mToolIcon, "ToolIcon");
getWidget(mUsesLabel, "UsesLabel");
getWidget(mQualityLabel, "QualityLabel");
getWidget(mCancelButton, "CancelButton");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onCancel);
}
void Repair::open()
{
center();
}
void Repair::startRepairItem(const MWWorld::Ptr &item)
{
mRepair.setTool(item);
std::string path = std::string("icons\\");
path += MWWorld::Class::get(item).getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
mToolIcon->setImageTexture (path);
mToolIcon->setUserString("ToolTipType", "ItemPtr");
mToolIcon->setUserData(item);
updateRepairView();
}
void Repair::updateRepairView()
{
MWWorld::LiveCellRef<ESM::Repair> *ref =
mRepair.getTool().get<ESM::Repair>();
int uses = (mRepair.getTool().getCellRef().mCharge != -1) ? mRepair.getTool().getCellRef().mCharge : ref->mBase->mData.mUses;
float quality = ref->mBase->mData.mQuality;
std::stringstream qualityStr;
qualityStr << std::setprecision(3) << quality;
mUsesLabel->setCaptionWithReplacing("#{sUses} " + boost::lexical_cast<std::string>(uses));
mQualityLabel->setCaptionWithReplacing("#{sQuality} " + qualityStr.str());
bool toolBoxVisible = (mRepair.getTool().getRefData().getCount() != 0);
mToolBox->setVisible(toolBoxVisible);
bool toolBoxWasVisible = (mRepairBox->getPosition().top != mToolBox->getPosition().top);
if (toolBoxVisible && !toolBoxWasVisible)
{
// shrink
mRepairBox->setPosition(mRepairBox->getPosition() + MyGUI::IntPoint(0,mToolBox->getSize().height));
mRepairBox->setSize(mRepairBox->getSize() - MyGUI::IntSize(0,mToolBox->getSize().height));
}
else if (!toolBoxVisible && toolBoxWasVisible)
{
// expand
mRepairBox->setPosition(MyGUI::IntPoint (mRepairBox->getPosition().left, mToolBox->getPosition().top));
mRepairBox->setSize(mRepairBox->getSize() + MyGUI::IntSize(0,mToolBox->getSize().height));
}
while (mRepairView->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mRepairView->getChildAt(0));
int currentY = 0;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
iter!=store.end(); ++iter)
{
if (MWWorld::Class::get(*iter).hasItemHealth(*iter))
{
int maxDurability = MWWorld::Class::get(*iter).getItemMaxHealth(*iter);
int durability = (iter->getCellRef().mCharge == -1) ? maxDurability : iter->getCellRef().mCharge;
if (maxDurability == durability)
continue;
MyGUI::TextBox* text = mRepairView->createWidget<MyGUI::TextBox> (
"SandText", MyGUI::IntCoord(8, currentY, mRepairView->getWidth()-8, 18), MyGUI::Align::Default);
text->setCaption(MWWorld::Class::get(*iter).getName(*iter));
text->setNeedMouseFocus(false);
currentY += 19;
MyGUI::ImageBox* icon = mRepairView->createWidget<MyGUI::ImageBox> (
"ImageBox", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += MWWorld::Class::get(*iter).getInventoryIcon(*iter);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
icon->setImageTexture (path);
icon->setUserString("ToolTipType", "ItemPtr");
icon->setUserData(*iter);
icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onRepairItem);
icon->eventMouseWheel += MyGUI::newDelegate(this, &Repair::onMouseWheel);
Widgets::MWDynamicStatPtr chargeWidget = mRepairView->createWidget<Widgets::MWDynamicStat>
("MW_ChargeBar", MyGUI::IntCoord(72, currentY+2, 199, 20), MyGUI::Align::Default);
chargeWidget->setValue(durability, maxDurability);
chargeWidget->setNeedMouseFocus(false);
currentY += 32 + 4;
}
}
mRepairView->setCanvasSize (MyGUI::IntSize(mRepairView->getWidth(), std::max(mRepairView->getHeight(), currentY)));
}
void Repair::onCancel(MyGUI::Widget *sender)
{
mWindowManager.removeGuiMode(GM_Repair);
}
void Repair::onRepairItem(MyGUI::Widget *sender)
{
if (!mRepair.getTool().getRefData().getCount())
return;
mRepair.repair(*sender->getUserData<MWWorld::Ptr>());
updateRepairView();
}
void Repair::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mRepairView->getViewOffset().top + _rel*0.3 > 0)
mRepairView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mRepairView->setViewOffset(MyGUI::IntPoint(0, mRepairView->getViewOffset().top + _rel*0.3));
}
}

View file

@ -0,0 +1,46 @@
#ifndef OPENMW_MWGUI_REPAIR_H
#define OPENMW_MWGUI_REPAIR_H
#include "window_base.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwmechanics/repair.hpp"
namespace MWGui
{
class Repair : public WindowBase
{
public:
Repair(MWBase::WindowManager &parWindowManager);
virtual void open();
void startRepairItem (const MWWorld::Ptr& item);
protected:
MyGUI::Widget* mRepairBox;
MyGUI::ScrollView* mRepairView;
MyGUI::Widget* mToolBox;
MyGUI::ImageBox* mToolIcon;
MyGUI::TextBox* mUsesLabel;
MyGUI::TextBox* mQualityLabel;
MyGUI::Button* mCancelButton;
MWMechanics::Repair mRepair;
void updateRepairView();
void onRepairItem (MyGUI::Widget* sender);
void onCancel (MyGUI::Widget* sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
};
}
#endif

View file

@ -32,20 +32,9 @@ namespace MWGui
getWidget(mCancelButton, "CancelButton"); getWidget(mCancelButton, "CancelButton");
getWidget(mPlayerGold, "PlayerGold"); getWidget(mPlayerGold, "PlayerGold");
getWidget(mSelect, "Select");
getWidget(mSpells, "Spells");
getWidget(mSpellsView, "SpellsView"); getWidget(mSpellsView, "SpellsView");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onCancelButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onCancelButtonClicked);
mSpells->setCoord(450/2-mSpells->getTextSize().width/2,
mSpells->getTop(),
mSpells->getTextSize().width,
mSpells->getHeight());
mSelect->setCoord(8,
mSelect->getTop(),
mSelect->getTextSize().width,
mSelect->getHeight());
} }
void SpellBuyingWindow::addSpell(const std::string& spellId) void SpellBuyingWindow::addSpell(const std::string& spellId)

View file

@ -28,8 +28,6 @@ namespace MWGui
protected: protected:
MyGUI::Button* mCancelButton; MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPlayerGold; MyGUI::TextBox* mPlayerGold;
MyGUI::TextBox* mSpells;
MyGUI::TextBox* mSelect;
MyGUI::ScrollView* mSpellsView; MyGUI::ScrollView* mSpellsView;

View file

@ -454,10 +454,13 @@ namespace MWGui
mAvailableEffectsList->clear (); mAvailableEffectsList->clear ();
int i=0;
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
{ {
mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find( mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find(
ESM::MagicEffect::effectIdToString (*it))->getString()); ESM::MagicEffect::effectIdToString (*it))->getString());
mButtonMapping[i] = *it;
++i;
} }
mAvailableEffectsList->adjustSize (); mAvailableEffectsList->adjustSize ();
@ -466,7 +469,6 @@ namespace MWGui
std::string name = MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find( std::string name = MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find(
ESM::MagicEffect::effectIdToString (*it))->getString(); ESM::MagicEffect::effectIdToString (*it))->getString();
MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name); MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name);
w->setUserData(*it);
ToolTips::createMagicEffectToolTip (w, *it); ToolTips::createMagicEffectToolTip (w, *it);
} }
@ -518,7 +520,8 @@ namespace MWGui
return; return;
} }
short effectId = *sender->getUserData<short>(); int buttonId = *sender->getUserData<int>();
short effectId = mButtonMapping[buttonId];
for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it) for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
{ {

View file

@ -88,6 +88,8 @@ namespace MWGui
protected: protected:
std::map<int, short> mButtonMapping; // maps button ID to effect ID
Widgets::MWList* mAvailableEffectsList; Widgets::MWList* mAvailableEffectsList;
MyGUI::ScrollView* mUsedEffectsView; MyGUI::ScrollView* mUsedEffectsView;

View file

@ -90,7 +90,20 @@ void ToolTips::onFrame(float frameDuration)
if (mFocusObject.isEmpty ()) if (mFocusObject.isEmpty ())
return; return;
MyGUI::IntSize tooltipSize = getToolTipViaPtr(true); const MWWorld::Class& objectclass = MWWorld::Class::get (mFocusObject);
IntSize tooltipSize;
if ((!objectclass.hasToolTip(mFocusObject))&&(mWindowManager->getMode() == GM_Console))
{
setCoord(0, 0, 300, 300);
mDynamicToolTipBox->setVisible(true);
ToolTipInfo info;
info.caption=mFocusObject.getCellRef().mRefID;
info.icon="";
tooltipSize = createToolTip(info);
}
else
tooltipSize = getToolTipViaPtr(true);
IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24); IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24);

View file

@ -368,7 +368,7 @@ namespace MWGui
return services & ESM::NPC::Books; return services & ESM::NPC::Books;
else if (item.getTypeName() == typeid(ESM::Ingredient).name()) else if (item.getTypeName() == typeid(ESM::Ingredient).name())
return services & ESM::NPC::Ingredients; return services & ESM::NPC::Ingredients;
else if (item.getTypeName() == typeid(ESM::Tool).name()) else if (item.getTypeName() == typeid(ESM::Lockpick).name())
return services & ESM::NPC::Picks; return services & ESM::NPC::Picks;
else if (item.getTypeName() == typeid(ESM::Probe).name()) else if (item.getTypeName() == typeid(ESM::Probe).name())
return services & ESM::NPC::Probes; return services & ESM::NPC::Probes;

View file

@ -142,7 +142,7 @@ namespace MWGui
std::string dateTimeText = std::string dateTimeText =
boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getDay ()) + " " boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getDay ()) + " "
+ month + " (#{sDay} " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getTimeStamp ().getDay ()+1) + month + " (#{sDay} " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getTimeStamp ().getDay())
+ ") " + boost::lexical_cast<std::string>(hour) + " " + (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}"); + ") " + boost::lexical_cast<std::string>(hour) + " " + (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}");
mDateTimeText->setCaptionWithReplacing (dateTimeText); mDateTimeText->setCaptionWithReplacing (dateTimeText);
@ -159,7 +159,7 @@ namespace MWGui
float hourlyHealthDelta = stats.getAttribute(ESM::Attribute::Endurance).getModified() * 0.1; float hourlyHealthDelta = stats.getAttribute(ESM::Attribute::Endurance).getModified() * 0.1;
bool stunted = (stats.getMagicEffects().get(MWMechanics::EffectKey(136)).mMagnitude > 0); bool stunted = (stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0);
float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat(); float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat();
float hourlyMagickaDelta = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); float hourlyMagickaDelta = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();

View file

@ -55,6 +55,8 @@
#include "exposedwindow.hpp" #include "exposedwindow.hpp"
#include "cursor.hpp" #include "cursor.hpp"
#include "spellicons.hpp" #include "spellicons.hpp"
#include "merchantrepair.hpp"
#include "repair.hpp"
using namespace MWGui; using namespace MWGui;
@ -90,6 +92,8 @@ WindowManager::WindowManager(
, mSpellCreationDialog(NULL) , mSpellCreationDialog(NULL)
, mEnchantingDialog(NULL) , mEnchantingDialog(NULL)
, mTrainingWindow(NULL) , mTrainingWindow(NULL)
, mMerchantRepair(NULL)
, mRepair(NULL)
, mPlayerName() , mPlayerName()
, mPlayerRaceId() , mPlayerRaceId()
, mPlayerAttributes() , mPlayerAttributes()
@ -180,6 +184,8 @@ WindowManager::WindowManager(
mSpellCreationDialog = new SpellCreationDialog(*this); mSpellCreationDialog = new SpellCreationDialog(*this);
mEnchantingDialog = new EnchantingDialog(*this); mEnchantingDialog = new EnchantingDialog(*this);
mTrainingWindow = new TrainingWindow(*this); mTrainingWindow = new TrainingWindow(*this);
mMerchantRepair = new MerchantRepair(*this);
mRepair = new Repair(*this);
mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this); mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this);
mLoadingScreen->onResChange (w,h); mLoadingScreen->onResChange (w,h);
@ -245,6 +251,8 @@ WindowManager::~WindowManager()
delete mTrainingWindow; delete mTrainingWindow;
delete mCountDialog; delete mCountDialog;
delete mQuickKeysMenu; delete mQuickKeysMenu;
delete mMerchantRepair;
delete mRepair;
delete mCursor; delete mCursor;
cleanupGarbage(); cleanupGarbage();
@ -303,6 +311,8 @@ void WindowManager::updateVisible()
mSpellCreationDialog->setVisible(false); mSpellCreationDialog->setVisible(false);
mEnchantingDialog->setVisible(false); mEnchantingDialog->setVisible(false);
mTrainingWindow->setVisible(false); mTrainingWindow->setVisible(false);
mMerchantRepair->setVisible(false);
mRepair->setVisible(false);
mHud->setVisible(mHudEnabled); mHud->setVisible(mHudEnabled);
@ -428,6 +438,12 @@ void WindowManager::updateVisible()
case GM_Training: case GM_Training:
mTrainingWindow->setVisible(true); mTrainingWindow->setVisible(true);
break; break;
case GM_MerchantRepair:
mMerchantRepair->setVisible(true);
break;
case GM_Repair:
mRepair->setVisible(true);
break;
case GM_InterMessageBox: case GM_InterMessageBox:
break; break;
case GM_Journal: case GM_Journal:
@ -1020,6 +1036,13 @@ bool WindowManager::isGuiMode() const
return !mGuiModes.empty(); return !mGuiModes.empty();
} }
bool WindowManager::isConsoleMode() const
{
if (mGuiModes.back()==GM_Console)
return true;
return false;
}
MWGui::GuiMode WindowManager::getMode() const MWGui::GuiMode WindowManager::getMode() const
{ {
if (mGuiModes.empty()) if (mGuiModes.empty())
@ -1125,6 +1148,16 @@ void WindowManager::startTraining(MWWorld::Ptr actor)
mTrainingWindow->startTraining(actor); mTrainingWindow->startTraining(actor);
} }
void WindowManager::startRepair(MWWorld::Ptr actor)
{
mMerchantRepair->startRepair(actor);
}
void WindowManager::startRepairItem(MWWorld::Ptr item)
{
mRepair->startRepairItem(item);
}
const Translation::Storage& WindowManager::getTranslationDataStorage() const const Translation::Storage& WindowManager::getTranslationDataStorage() const
{ {
return mTranslationDataStorage; return mTranslationDataStorage;

View file

@ -74,6 +74,8 @@ namespace MWGui
class TrainingWindow; class TrainingWindow;
class Cursor; class Cursor;
class SpellIcons; class SpellIcons;
class MerchantRepair;
class Repair;
class WindowManager : public MWBase::WindowManager class WindowManager : public MWBase::WindowManager
{ {
@ -102,6 +104,8 @@ namespace MWGui
virtual bool isGuiMode() const; virtual bool isGuiMode() const;
virtual bool isConsoleMode() const;
virtual void toggleVisible(GuiWindow wnd); virtual void toggleVisible(GuiWindow wnd);
// Disallow all inventory mode windows // Disallow all inventory mode windows
@ -227,6 +231,8 @@ namespace MWGui
virtual void startSpellMaking(MWWorld::Ptr actor); virtual void startSpellMaking(MWWorld::Ptr actor);
virtual void startEnchanting(MWWorld::Ptr actor); virtual void startEnchanting(MWWorld::Ptr actor);
virtual void startTraining(MWWorld::Ptr actor); virtual void startTraining(MWWorld::Ptr actor);
virtual void startRepair(MWWorld::Ptr actor);
virtual void startRepairItem(MWWorld::Ptr item);
virtual void changePointer (const std::string& name); virtual void changePointer (const std::string& name);
@ -264,6 +270,9 @@ namespace MWGui
SpellCreationDialog* mSpellCreationDialog; SpellCreationDialog* mSpellCreationDialog;
EnchantingDialog* mEnchantingDialog; EnchantingDialog* mEnchantingDialog;
TrainingWindow* mTrainingWindow; TrainingWindow* mTrainingWindow;
MerchantRepair* mMerchantRepair;
Repair* mRepair;
Translation::Storage& mTranslationDataStorage; Translation::Storage& mTranslationDataStorage;
Cursor* mCursor; Cursor* mCursor;

View file

@ -55,6 +55,7 @@ namespace MWInput
, mPreviewPOVDelay(0.f) , mPreviewPOVDelay(0.f)
, mTimeIdle(0.f) , mTimeIdle(0.f)
, mOverencumberedMessageDelay(0.f) , mOverencumberedMessageDelay(0.f)
, mAlwaysRunActive(false)
{ {
Ogre::RenderWindow* window = mOgre.getWindow (); Ogre::RenderWindow* window = mOgre.getWindow ();
size_t windowHnd; size_t windowHnd;
@ -180,12 +181,12 @@ namespace MWInput
break; break;
case A_Activate: case A_Activate:
resetIdleTime(); resetIdleTime();
activate();
if( MWBase::Environment::get().getWindowManager()->isGuiMode() if( MWBase::Environment::get().getWindowManager()->isGuiMode()
&& MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_InterMessageBox ) { && MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_InterMessageBox ) {
// Pressing the activation key when a messagebox is prompting for "ok" will activate the ok button // Pressing the activation key when a messagebox is prompting for "ok" will activate the ok button
MWBase::Environment::get().getWindowManager()->enterPressed(); MWBase::Environment::get().getWindowManager()->enterPressed();
} }
activate();
break; break;
case A_Journal: case A_Journal:
toggleJournal (); toggleJournal ();
@ -193,7 +194,7 @@ namespace MWInput
case A_AutoMove: case A_AutoMove:
toggleAutoMove (); toggleAutoMove ();
break; break;
case A_ToggleWalk: case A_AlwaysRun:
toggleWalking (); toggleWalking ();
break; break;
case A_ToggleWeapon: case A_ToggleWeapon:
@ -315,10 +316,10 @@ namespace MWInput
else else
mPlayer.setUpDown (0); mPlayer.setUpDown (0);
if(actionIsActive(A_Run)) if (mAlwaysRunActive)
mPlayer.setRunState(true); mPlayer.setRunState(!actionIsActive(A_Run));
else else
mPlayer.setRunState(false); mPlayer.setRunState(actionIsActive(A_Run));
// if player tried to start moving, but can't (due to being overencumbered), display a notification. // if player tried to start moving, but can't (due to being overencumbered), display a notification.
if (triedToMove) if (triedToMove)
@ -699,7 +700,7 @@ namespace MWInput
void InputManager::toggleWalking() void InputManager::toggleWalking()
{ {
if (mWindows.isGuiMode()) return; if (mWindows.isGuiMode()) return;
mPlayer.toggleRunning(); mAlwaysRunActive = !mAlwaysRunActive;
} }
// Exit program now button (which is disabled in GUI mode) // Exit program now button (which is disabled in GUI mode)
@ -768,6 +769,7 @@ namespace MWInput
defaultKeyBindings[A_QuickKey10] = OIS::KC_0; defaultKeyBindings[A_QuickKey10] = OIS::KC_0;
defaultKeyBindings[A_Screenshot] = OIS::KC_SYSRQ; defaultKeyBindings[A_Screenshot] = OIS::KC_SYSRQ;
defaultKeyBindings[A_ToggleHUD] = OIS::KC_F12; defaultKeyBindings[A_ToggleHUD] = OIS::KC_F12;
defaultKeyBindings[A_AlwaysRun] = OIS::KC_Y;
std::map<int, int> defaultMouseButtonBindings; std::map<int, int> defaultMouseButtonBindings;
defaultMouseButtonBindings[A_Inventory] = OIS::MB_Right; defaultMouseButtonBindings[A_Inventory] = OIS::MB_Right;
@ -834,6 +836,7 @@ namespace MWInput
descriptions[A_QuickKey8] = "sQuick8Cmd"; descriptions[A_QuickKey8] = "sQuick8Cmd";
descriptions[A_QuickKey9] = "sQuick9Cmd"; descriptions[A_QuickKey9] = "sQuick9Cmd";
descriptions[A_QuickKey10] = "sQuick10Cmd"; descriptions[A_QuickKey10] = "sQuick10Cmd";
descriptions[A_AlwaysRun] = "sAlways_Run";
if (descriptions[action] == "") if (descriptions[action] == "")
return ""; // not configurable return ""; // not configurable
@ -865,6 +868,7 @@ namespace MWInput
ret.push_back(A_MoveRight); ret.push_back(A_MoveRight);
ret.push_back(A_TogglePOV); ret.push_back(A_TogglePOV);
ret.push_back(A_Run); ret.push_back(A_Run);
ret.push_back(A_AlwaysRun);
ret.push_back(A_Sneak); ret.push_back(A_Sneak);
ret.push_back(A_Activate); ret.push_back(A_Activate);
ret.push_back(A_ToggleWeapon); ret.push_back(A_ToggleWeapon);

View file

@ -152,6 +152,7 @@ namespace MWInput
int mMouseWheel; int mMouseWheel;
bool mDebug; bool mDebug;
bool mUserFileExists; bool mUserFileExists;
bool mAlwaysRunActive;
std::map<std::string, bool> mControlSwitch; std::map<std::string, bool> mControlSwitch;
@ -217,7 +218,7 @@ namespace MWInput
A_CycleWeaponLeft,//Cycling through weapons A_CycleWeaponLeft,//Cycling through weapons
A_CycleWeaponRight, A_CycleWeaponRight,
A_ToggleSneak, //Toggles Sneak A_ToggleSneak, //Toggles Sneak
A_ToggleWalk, //Toggle Walking/Running A_AlwaysRun, //Toggle Walking/Running
A_Sneak, A_Sneak,
A_QuickSave, A_QuickSave,

View file

@ -71,7 +71,7 @@ namespace MWMechanics
int endurance = creatureStats.getAttribute(5).getBase(); int endurance = creatureStats.getAttribute(5).getBase();
double magickaFactor = double magickaFactor =
creatureStats.getMagicEffects().get (EffectKey (84)).mMagnitude * 0.1 + 0.5; creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::FortifyMaximumMagicka)).mMagnitude * 0.1 + 0.5;
DynamicStat<float> health = creatureStats.getHealth(); DynamicStat<float> health = creatureStats.getHealth();
health.setBase (static_cast<int> (0.5 * (strength + endurance)) + creatureStats.getLevelHealthBonus ()); health.setBase (static_cast<int> (0.5 * (strength + endurance)) + creatureStats.getLevelHealthBonus ());
@ -92,8 +92,7 @@ namespace MWMechanics
if (duration == 3600) if (duration == 3600)
{ {
// stunted magicka bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0;
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(136)).mMagnitude > 0;
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
@ -140,9 +139,9 @@ namespace MWMechanics
for (int i=0; i<8; ++i) for (int i=0; i<8; ++i)
{ {
int modifier = int modifier =
creatureStats.getMagicEffects().get (EffectKey (79, i)).mMagnitude; creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::FortifyAttribute, i)).mMagnitude;
modifier -= creatureStats.getMagicEffects().get (EffectKey (17, i)).mMagnitude; modifier -= creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::DrainAttribute, i)).mMagnitude;
creatureStats.getAttribute(i).setModifier (modifier); creatureStats.getAttribute(i).setModifier (modifier);
} }
@ -165,6 +164,9 @@ namespace MWMechanics
void Actors::addActor (const MWWorld::Ptr& ptr) void Actors::addActor (const MWWorld::Ptr& ptr)
{ {
// erase previous death events since we are currently only tracking them while in an active cell
MWWorld::Class::get (ptr).getCreatureStats (ptr).clearHasDied();
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if(!MWWorld::Class::get(ptr).getCreatureStats(ptr).isDead()) if(!MWWorld::Class::get(ptr).getCreatureStats(ptr).isDead())
mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle, true))); mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle, true)));

View file

@ -46,7 +46,7 @@ int getClosestPoint(const ESM::Pathgrid* grid,float x,float y,float z)
float m = distance(grid->mPoints[0],x,y,z); float m = distance(grid->mPoints[0],x,y,z);
int i0 = 0; int i0 = 0;
for(int i=1; i<grid->mPoints.size();i++) for(unsigned int i=1; i<grid->mPoints.size();++i)
{ {
if(distance(grid->mPoints[i],x,y,z)<m) if(distance(grid->mPoints[i],x,y,z)<m)
{ {
@ -139,7 +139,7 @@ PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCe
{ {
PathGridGraph graph; PathGridGraph graph;
for(int i = 0;i<pathgrid->mPoints.size();i++) for(unsigned int i = 0;i<pathgrid->mPoints.size();++i)
{ {
PointID pID = boost::add_vertex(graph); PointID pID = boost::add_vertex(graph);
graph[pID].mX = pathgrid->mPoints[i].mX + xCell; graph[pID].mX = pathgrid->mPoints[i].mX + xCell;
@ -147,7 +147,7 @@ PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCe
graph[pID].mZ = pathgrid->mPoints[i].mZ; graph[pID].mZ = pathgrid->mPoints[i].mZ;
} }
for(int i = 0;i<pathgrid->mEdges.size();i++) for(unsigned int i = 0;i<pathgrid->mEdges.size();++i)
{ {
PointID u = pathgrid->mEdges[i].mV0; PointID u = pathgrid->mEdges[i].mV0;
PointID v = pathgrid->mEdges[i].mV1; PointID v = pathgrid->mEdges[i].mV1;

View file

@ -2,7 +2,7 @@
#define GAME_MWMECHANICS_AITRAVEL_H #define GAME_MWMECHANICS_AITRAVEL_H
#include "aipackage.hpp" #include "aipackage.hpp"
#include "components\esm\loadpgrd.hpp" #include <components/esm/loadpgrd.hpp>
#include <list> #include <list>
namespace MWMechanics namespace MWMechanics

View file

@ -10,7 +10,8 @@
namespace MWMechanics namespace MWMechanics
{ {
CreatureStats::CreatureStats() CreatureStats::CreatureStats()
: mLevel (0), mLevelHealthBonus(0.f), mDead (false), mFriendlyHits (0), mTalkedTo (false), mAlarmed (false), : mLevel (0), mLevelHealthBonus(0.f), mDead (false), mDied (false), mFriendlyHits (0),
mTalkedTo (false), mAlarmed (false),
mAttacked (false), mHostile (false) mAttacked (false), mHostile (false)
{ {
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
@ -167,7 +168,12 @@ namespace MWMechanics
mDynamic[index] = value; mDynamic[index] = value;
if (index==0 && mDynamic[index].getCurrent()<1) if (index==0 && mDynamic[index].getCurrent()<1)
{
if (!mDead)
mDied = true;
mDead = true; mDead = true;
}
} }
void CreatureStats::setLevel(int level) void CreatureStats::setLevel(int level)
@ -196,6 +202,16 @@ namespace MWMechanics
return mDead; return mDead;
} }
bool CreatureStats::hasDied() const
{
return mDied;
}
void CreatureStats::clearHasDied()
{
mDied = false;
}
void CreatureStats::resurrect() void CreatureStats::resurrect()
{ {
if (mDead) if (mDead)

View file

@ -28,6 +28,7 @@ namespace MWMechanics
AiSequence mAiSequence; AiSequence mAiSequence;
float mLevelHealthBonus; float mLevelHealthBonus;
bool mDead; bool mDead;
bool mDied;
int mFriendlyHits; int mFriendlyHits;
bool mTalkedTo; bool mTalkedTo;
bool mAlarmed; bool mAlarmed;
@ -100,6 +101,10 @@ namespace MWMechanics
bool isDead() const; bool isDead() const;
bool hasDied() const;
void clearHasDied();
void resurrect(); void resurrect();
bool hasCommonDisease() const; bool hasCommonDisease() const;

View file

@ -2,6 +2,7 @@
#include "mechanicsmanagerimp.hpp" #include "mechanicsmanagerimp.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"

View file

@ -0,0 +1,110 @@
#include "repair.hpp"
#include <boost/format.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp"
namespace MWMechanics
{
void Repair::repair(const MWWorld::Ptr &itemToRepair)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::LiveCellRef<ESM::Repair> *ref =
mTool.get<ESM::Repair>();
// reduce number of uses left
int uses = (mTool.getCellRef().mCharge != -1) ? mTool.getCellRef().mCharge : ref->mBase->mData.mUses;
mTool.getCellRef().mCharge = uses-1;
// unstack tool if required
if (mTool.getRefData().getCount() > 1 && uses == ref->mBase->mData.mUses)
{
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
MWWorld::ContainerStoreIterator it = store.add(mTool);
it->getRefData().setCount(mTool.getRefData().getCount()-1);
it->getCellRef().mCharge = -1;
mTool.getRefData().setCount(1);
}
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats(player);
float fatigueTerm = stats.getFatigueTerm();
int pcStrength = stats.getAttribute(ESM::Attribute::Strength).getModified();
int pcLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
int armorerSkill = npcStats.getSkill(ESM::Skill::Armorer).getModified();
float fRepairAmountMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("fRepairAmountMult")->getFloat();
float toolQuality = ref->mBase->mData.mQuality;
float x = (0.1 * pcStrength + 0.1 * pcLuck + armorerSkill) * fatigueTerm;
int roll = static_cast<float> (std::rand()) / RAND_MAX * 100;
if (roll <= x)
{
int y = fRepairAmountMult * toolQuality * roll;
y = std::max(1, y);
// repair by 'y' points
itemToRepair.getCellRef().mCharge += y;
itemToRepair.getCellRef().mCharge = std::min(itemToRepair.getCellRef().mCharge,
MWWorld::Class::get(itemToRepair).getItemMaxHealth(itemToRepair));
// set the OnPCRepair variable on the item's script
std::string script = MWWorld::Class::get(itemToRepair).getScript(itemToRepair);
if(script != "")
itemToRepair.getRefData().getLocals().setVarByInt(script, "onpcrepair", 1);
// increase skill
MWWorld::Class::get(player).skillUsageSucceeded(player, ESM::Skill::Armorer, 0);
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);
MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairSuccess}");
}
else
{
MWBase::Environment::get().getSoundManager()->playSound("Repair Fail",1,1);
MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairFailed}");
}
// tool used up?
if (mTool.getCellRef().mCharge == 0)
{
mTool.getRefData().setCount(0);
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("sNotifyMessage51")->getString();
MWBase::Environment::get().getWindowManager()->messageBox((boost::format(message) % MWWorld::Class::get(mTool).getName(mTool)).str());
// try to find a new tool of the same ID
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
for (MWWorld::ContainerStoreIterator iter (store.begin());
iter!=store.end(); ++iter)
{
if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, mTool.getCellRef().mRefID))
{
mTool = *iter;
break;
}
}
}
}
}

View file

@ -0,0 +1,23 @@
#ifndef OPENMW_MWMECHANICS_REPAIR_H
#define OPENMW_MWMECHANICS_REPAIR_H
#include "../mwworld/ptr.hpp"
namespace MWMechanics
{
class Repair
{
public:
void setTool (const MWWorld::Ptr& tool) { mTool = tool; }
MWWorld::Ptr getTool() { return mTool; }
void repair (const MWWorld::Ptr& itemToRepair);
private:
MWWorld::Ptr mTool;
};
}
#endif

View file

@ -104,11 +104,14 @@ namespace MWRender
mAnimation = new NpcAnimation(mCharacter, mNode, mAnimation = new NpcAnimation(mCharacter, mNode,
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0, renderHeadOnly()); MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0, renderHeadOnly());
float scale=1.f;
MWWorld::Class::get(mCharacter).adjustScale(mCharacter, scale);
mNode->setScale(Ogre::Vector3(scale));
mNode->setVisible (false); mNode->setVisible (false);
Ogre::Vector3 scale = mNode->getScale(); mCamera->setPosition(mPosition * mNode->getScale());
mCamera->setPosition(mPosition * scale); mCamera->lookAt(mLookAt * mNode->getScale());
mCamera->lookAt(mLookAt * scale);
onSetup(); onSetup();
} }

View file

@ -85,11 +85,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
MWBase::Environment::get().getWorld()->getStore(); MWBase::Environment::get().getWorld()->getStore();
const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace); const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace);
float scale = race->mData.mHeight.mMale;
if(!mNpc->isMale())
scale = race->mData.mHeight.mFemale;
node->scale(Ogre::Vector3(scale));
mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel; mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel;
mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHair)->mModel; mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHair)->mModel;

View file

@ -16,16 +16,31 @@
#include "renderconst.hpp" #include "renderconst.hpp"
using namespace MWRender; using namespace MWRender;
float Objects::lightLinearValue()
{
return mFallback->getFallbackFloat("LightAttenuation_LinearValue");
}
float Objects::lightLinearRadiusMult()
{
return mFallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
}
float Objects::lightQuadraticValue()
{
return mFallback->getFallbackFloat("LightAttenuation_QuadraticValue");
}
float Objects::lightQuadraticRadiusMult()
{
return mFallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
}
/// \todo Replace these, once fallback values from the ini file are available. bool Objects::lightOutQuadInLin()
float Objects::lightLinearValue = 3; {
float Objects::lightLinearRadiusMult = 1; return mFallback->getFallbackBool("LightAttenuation_OutQuadInLin");
}
float Objects::lightQuadraticValue = 16; bool Objects::lightQuadratic()
float Objects::lightQuadraticRadiusMult = 1; {
return mFallback->getFallbackBool("LightAttenuation_UseQuadratic");
bool Objects::lightOutQuadInLin = true; }
bool Objects::lightQuadratic = false;
int Objects::uniqueID = 0; int Objects::uniqueID = 0;
@ -269,14 +284,14 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, Ogre::Entity* skelBase, Ogre
if (!quadratic) if (!quadratic)
{ {
float r = radius * lightLinearRadiusMult; float r = radius * lightLinearRadiusMult();
float attenuation = lightLinearValue / r; float attenuation = lightLinearValue() / r;
light->setAttenuation(r*10, 0, attenuation, 0); light->setAttenuation(r*10, 0, attenuation, 0);
} }
else else
{ {
float r = radius * lightQuadraticRadiusMult; float r = radius * lightQuadraticRadiusMult();
float attenuation = lightQuadraticValue / pow(r, 2); float attenuation = lightQuadraticValue() / pow(r, 2);
light->setAttenuation(r*10, 0, 0, attenuation); light->setAttenuation(r*10, 0, 0, attenuation);
} }

View file

@ -5,6 +5,7 @@
#include <OgreAxisAlignedBox.h> #include <OgreAxisAlignedBox.h>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include "../mwworld/fallback.hpp"
namespace MWWorld namespace MWWorld
{ {
@ -56,21 +57,21 @@ class Objects{
Ogre::SceneNode* mRootNode; Ogre::SceneNode* mRootNode;
bool mIsStatic; bool mIsStatic;
static int uniqueID; static int uniqueID;
MWWorld::Fallback* mFallback;
float lightLinearValue();
float lightLinearRadiusMult();
static float lightLinearValue; bool lightQuadratic();
static float lightLinearRadiusMult; float lightQuadraticValue();
float lightQuadraticRadiusMult();
static bool lightQuadratic; bool lightOutQuadInLin();
static float lightQuadraticValue;
static float lightQuadraticRadiusMult;
static bool lightOutQuadInLin;
void clearSceneNode (Ogre::SceneNode *node); void clearSceneNode (Ogre::SceneNode *node);
///< Remove all movable objects from \a node. ///< Remove all movable objects from \a node.
public: public:
Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer), mIsStatic(false) {} Objects(OEngine::Render::OgreRenderer& renderer, MWWorld::Fallback* fallback): mRenderer (renderer), mIsStatic(false), mFallback(fallback) {}
~Objects(){} ~Objects(){}
void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light=false); void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light=false);

View file

@ -48,9 +48,10 @@ using namespace Ogre;
namespace MWRender { namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,MWWorld::Fallback* fallback)
: mRendering(_rend) : mRendering(_rend)
, mObjects(mRendering) , mFallback(fallback)
, mObjects(mRendering,mFallback)
, mActors(mRendering, this) , mActors(mRendering, this)
, mAmbientMode(0) , mAmbientMode(0)
, mSunEnabled(0) , mSunEnabled(0)
@ -884,6 +885,8 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
mPlayer->setAnimation(anim); mPlayer->setAnimation(anim);
mWater->removeEmitter (ptr); mWater->removeEmitter (ptr);
mWater->addEmitter (ptr); mWater->addEmitter (ptr);
// apply race height
MWBase::Environment::get().getWorld()->scaleObject(ptr, 1.f);
} }
void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw)

View file

@ -60,7 +60,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
public: public:
RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine); const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,MWWorld::Fallback* fallback);
virtual ~RenderingManager(); virtual ~RenderingManager();
void togglePOV() { void togglePOV() {
@ -220,6 +220,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
bool mSunEnabled; bool mSunEnabled;
MWWorld::Fallback* mFallback;
SkyManager* mSkyManager; SkyManager* mSkyManager;
OcclusionQuery* mOcclusionQuery; OcclusionQuery* mOcclusionQuery;

View file

@ -21,6 +21,8 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwworld/fallback.hpp"
#include "renderconst.hpp" #include "renderconst.hpp"
#include "renderingmanager.hpp" #include "renderingmanager.hpp"
@ -266,11 +268,12 @@ void SkyManager::create()
mLightning->setVisible (false); mLightning->setVisible (false);
mLightning->setDiffuseColour (ColourValue(3,3,3)); mLightning->setDiffuseColour (ColourValue(3,3,3));
mSecunda = new Moon("secunda_texture", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode, "openmw_moon"); const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback();
mSecunda = new Moon("secunda_texture", /*0.5*/fallback->getFallbackFloat("Moons_Secunda_Size")/100, Vector3(-0.4, 0.4, 0.5), mRootNode, "openmw_moon");
mSecunda->setType(Moon::Type_Secunda); mSecunda->setType(Moon::Type_Secunda);
mSecunda->setRenderQueue(RQG_SkiesEarly+4); mSecunda->setRenderQueue(RQG_SkiesEarly+4);
mMasser = new Moon("masser_texture", 0.75, Vector3(-0.4, 0.4, 0.5), mRootNode, "openmw_moon"); mMasser = new Moon("masser_texture", /*0.75*/fallback->getFallbackFloat("Moons_Masser_Size")/100, Vector3(-0.4, 0.4, 0.5), mRootNode, "openmw_moon");
mMasser->setRenderQueue(RQG_SkiesEarly+3); mMasser->setRenderQueue(RQG_SkiesEarly+3);
mMasser->setType(Moon::Type_Masser); mMasser->setType(Moon::Type_Masser);
@ -368,7 +371,7 @@ int SkyManager::getSecundaPhase() const
void SkyManager::update(float duration) void SkyManager::update(float duration)
{ {
if (!mEnabled) return; if (!mEnabled) return;
const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback();
mCamera->getParentSceneNode ()->needUpdate (); mCamera->getParentSceneNode ()->needUpdate ();
mRootNode->setPosition(mCamera->getDerivedPosition()); mRootNode->setPosition(mCamera->getDerivedPosition());
@ -381,7 +384,7 @@ void SkyManager::update(float duration)
mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) ); mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
mSecunda->setPhase ( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) ); mSecunda->setPhase ( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
mSecunda->setColour ( mMoonRed ? ColourValue(1.0, 0.0784, 0.0784) : ColourValue(1,1,1,1)); mSecunda->setColour ( mMoonRed ? fallback->getFallbackColour("Moons_Script_Color") : ColourValue(1,1,1,1));
mMasser->setColour (ColourValue(1,1,1,1)); mMasser->setColour (ColourValue(1,1,1,1));
if (mSunEnabled) if (mSunEnabled)

View file

@ -59,7 +59,7 @@ namespace MWScript
store.get<ESM::CreatureLevList>().search (name) || store.get<ESM::CreatureLevList>().search (name) ||
store.get<ESM::ItemLevList>().search (name) || store.get<ESM::ItemLevList>().search (name) ||
store.get<ESM::Light>().search (name) || store.get<ESM::Light>().search (name) ||
store.get<ESM::Tool>().search (name) || store.get<ESM::Lockpick>().search (name) ||
store.get<ESM::Miscellaneous>().search (name) || store.get<ESM::Miscellaneous>().search (name) ||
store.get<ESM::NPC>().search (name) || store.get<ESM::NPC>().search (name) ||
store.get<ESM::Probe>().search (name) || store.get<ESM::Probe>().search (name) ||

View file

@ -315,5 +315,6 @@ op 0x20001f8: Drop
op 0x20001f9: Drop, explicit reference op 0x20001f9: Drop, explicit reference
op 0x20001fa: DropSoulGem op 0x20001fa: DropSoulGem
op 0x20001fb: DropSoulGem, explicit reference op 0x20001fb: DropSoulGem, explicit reference
op 0x20001fc: OnDeath
opcodes 0x20001fa-0x3ffffff unused opcodes 0x20001fd-0x3ffffff unused

View file

@ -215,19 +215,22 @@ namespace MWScript
std::string InterpreterContext::getNPCRace() const std::string InterpreterContext::getNPCRace() const
{ {
ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase; ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase;
return npc.mRace; const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc.mRace);
return race->mName;
} }
std::string InterpreterContext::getNPCClass() const std::string InterpreterContext::getNPCClass() const
{ {
ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase; ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase;
return npc.mClass; const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc.mClass);
return class_->mName;
} }
std::string InterpreterContext::getNPCFaction() const std::string InterpreterContext::getNPCFaction() const
{ {
ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase; ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase;
return npc.mFaction; const ESM::Faction* faction = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(npc.mFaction);
return faction->mName;
} }
std::string InterpreterContext::getNPCRank() const std::string InterpreterContext::getNPCRank() const

View file

@ -1025,6 +1025,27 @@ namespace MWScript
} }
}; };
class OpOnDeath : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
MWWorld::Ptr ptr = context.getReference();
Interpreter::Type_Integer value =
MWWorld::Class::get (ptr).getCreatureStats (ptr).hasDied();
if (value)
MWWorld::Class::get (ptr).getCreatureStats (ptr).clearHasDied();
runtime.push (value);
}
};
const int numberOfAttributes = 8; const int numberOfAttributes = 8;
const int opcodeGetAttribute = 0x2000027; const int opcodeGetAttribute = 0x2000027;
@ -1114,6 +1135,8 @@ namespace MWScript
const int opcodeLowerRank = 0x20001ea; const int opcodeLowerRank = 0x20001ea;
const int opcodeLowerRankExplicit = 0x20001eb; const int opcodeLowerRankExplicit = 0x20001eb;
const int opcodeOnDeath = 0x20001fc;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
static const char *attributes[numberOfAttributes] = static const char *attributes[numberOfAttributes] =
@ -1227,6 +1250,8 @@ namespace MWScript
extensions.registerInstruction ("pcclearexpelled", "/S", opcodePcClearExpelled, opcodePcClearExpelledExplicit); extensions.registerInstruction ("pcclearexpelled", "/S", opcodePcClearExpelled, opcodePcClearExpelledExplicit);
extensions.registerInstruction ("raiserank", "", opcodeRaiseRank, opcodeRaiseRankExplicit); extensions.registerInstruction ("raiserank", "", opcodeRaiseRank, opcodeRaiseRankExplicit);
extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit); extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit);
extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -1341,6 +1366,8 @@ namespace MWScript
interpreter.installSegment5 (opcodeRaiseRankExplicit, new OpRaiseRank<ExplicitRef>); interpreter.installSegment5 (opcodeRaiseRankExplicit, new OpRaiseRank<ExplicitRef>);
interpreter.installSegment5 (opcodeLowerRank, new OpLowerRank<ImplicitRef>); interpreter.installSegment5 (opcodeLowerRank, new OpLowerRank<ImplicitRef>);
interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>); interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>);
interpreter.installSegment5 (opcodeOnDeath, new OpOnDeath);
} }
} }
} }

View file

@ -0,0 +1,18 @@
#include "actionrepair.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
namespace MWWorld
{
ActionRepair::ActionRepair(const Ptr &item)
: Action(false, item)
{
}
void ActionRepair::executeImp (const Ptr& actor)
{
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Repair);
MWBase::Environment::get().getWindowManager()->startRepairItem(getTarget());
}
}

View file

@ -0,0 +1,17 @@
#ifndef GAME_MWWORLD_ACTIONREPAIR_H
#define GAME_MWWORLD_ACTIONREPAIR_H
#include "action.hpp"
namespace MWWorld
{
class ActionRepair : public Action
{
virtual void executeImp (const Ptr& actor);
public:
ActionRepair(const MWWorld::Ptr& item);
};
}
#endif

View file

@ -206,7 +206,7 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& ce
if (MWWorld::LiveCellRef<ESM::Light> *ref = cell.mLights.find (name)) if (MWWorld::LiveCellRef<ESM::Light> *ref = cell.mLights.find (name))
ptr = Ptr (ref, &cell); ptr = Ptr (ref, &cell);
if (MWWorld::LiveCellRef<ESM::Tool> *ref = cell.mLockpicks.find (name)) if (MWWorld::LiveCellRef<ESM::Lockpick> *ref = cell.mLockpicks.find (name))
ptr = Ptr (ref, &cell); ptr = Ptr (ref, &cell);
if (MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = cell.mMiscItems.find (name)) if (MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = cell.mMiscItems.find (name))

Some files were not shown because too many files have changed in this diff Show more