mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-24 03:23:54 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
71c3bd6288
62 changed files with 1104 additions and 182 deletions
|
@ -370,6 +370,10 @@ if(WIN32)
|
|||
INSTALL(FILES
|
||||
"${OpenMW_BINARY_DIR}/plugins.cfg"
|
||||
"${OpenMW_SOURCE_DIR}/readme.txt"
|
||||
"${OpenMW_SOURCE_DIR}/GPL3.txt"
|
||||
"${OpenMW_SOURCE_DIR}/OFL.txt"
|
||||
"${OpenMW_SOURCE_DIR}/Bitstream Vera License.txt"
|
||||
"${OpenMW_SOURCE_DIR}/Daedric Font License.txt"
|
||||
"${OpenMW_BINARY_DIR}/launcher.qss"
|
||||
"${OpenMW_BINARY_DIR}/settings-default.cfg"
|
||||
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
|
||||
|
@ -391,8 +395,8 @@ if(WIN32)
|
|||
!insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
|
||||
Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Readme.lnk\\\"
|
||||
")
|
||||
SET(CPACK_RESOURCE_FILE_README "${OpenMW_SOURCE_DIR}/readme.txt")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
|
||||
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
|
||||
SET(CPACK_NSIS_DISPLAY_NAME "OpenMW")
|
||||
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
|
||||
|
|
|
@ -8,6 +8,7 @@ set(LAUNCHER
|
|||
playpage.cpp
|
||||
pluginsmodel.cpp
|
||||
pluginsview.cpp
|
||||
filedialog.cpp
|
||||
|
||||
launcher.rc
|
||||
)
|
||||
|
@ -22,6 +23,7 @@ set(LAUNCHER_HEADER
|
|||
playpage.hpp
|
||||
pluginsmodel.hpp
|
||||
pluginsview.hpp
|
||||
filedialog.hpp
|
||||
)
|
||||
|
||||
# Headers that must be pre-processed
|
||||
|
@ -34,6 +36,7 @@ set(LAUNCHER_HEADER_MOC
|
|||
playpage.hpp
|
||||
pluginsmodel.hpp
|
||||
pluginsview.hpp
|
||||
filedialog.hpp
|
||||
)
|
||||
|
||||
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC})
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "datafilespage.hpp"
|
||||
#include "lineedit.hpp"
|
||||
#include "filedialog.hpp"
|
||||
#include "naturalsort.hpp"
|
||||
#include "pluginsmodel.hpp"
|
||||
#include "pluginsview.hpp"
|
||||
|
@ -203,8 +204,7 @@ void DataFilesPage::setupDataFiles()
|
|||
mCfgMgr.readConfiguration(variables, desc);
|
||||
|
||||
// Put the paths in a boost::filesystem vector to use with Files::Collections
|
||||
Files::PathContainer dataDirs(variables["data"].as<Files::PathContainer>());
|
||||
mDataDirs = dataDirs;
|
||||
mDataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||
|
||||
// std::string local = variables["data-local"].as<std::string>();
|
||||
// if (!local.empty()) {
|
||||
|
@ -212,14 +212,12 @@ void DataFilesPage::setupDataFiles()
|
|||
// dataDirs.push_back(Files::PathContainer::value_type(local));
|
||||
// }
|
||||
|
||||
if (dataDirs.size()>1)
|
||||
dataDirs.resize (1);
|
||||
if (mDataDirs.size()>1)
|
||||
mDataDirs.resize (1);
|
||||
|
||||
mCfgMgr.processPaths(dataDirs);
|
||||
|
||||
while (dataDirs.empty()) {
|
||||
// No valid data files directory found
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
|
||||
while (mDataDirs.empty()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error detecting Morrowind installation");
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
|
@ -235,13 +233,21 @@ void DataFilesPage::setupDataFiles()
|
|||
|
||||
if (msgBox.clickedButton() == dirSelectButton) {
|
||||
|
||||
QString dataDir = QFileDialog::getExistingDirectory(
|
||||
// Show a custom dir selection dialog which only accepts valid dirs
|
||||
QString selectedDir = FileDialog::getExistingDirectory(
|
||||
this, tr("Select Data Files Directory"),
|
||||
"/home",
|
||||
QDir::currentPath(),
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
dataDirs.push_back(Files::PathContainer::value_type(dataDir.toStdString()));
|
||||
mDataDirs.push_back(Files::PathContainer::value_type(dataDir.toStdString()));
|
||||
// Add the user selected data directory
|
||||
if (!selectedDir.isEmpty()) {
|
||||
mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString()));
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
} else {
|
||||
// Cancel from within the dir selection dialog
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Cancel
|
||||
break;
|
||||
|
@ -249,13 +255,13 @@ void DataFilesPage::setupDataFiles()
|
|||
}
|
||||
|
||||
// Check if cancel was clicked because we can't exit from while loop
|
||||
if (dataDirs.empty()) {
|
||||
if (mDataDirs.empty()) {
|
||||
QApplication::exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a file collection for the dataDirs
|
||||
Files::Collections fileCollections(dataDirs, !variables["fs-strict"].as<bool>());
|
||||
// Create a file collection for the data dirs
|
||||
Files::Collections fileCollections(mDataDirs, !variables["fs-strict"].as<bool>());
|
||||
|
||||
// First we add all the master files
|
||||
const Files::MultiDirCollection &esm = fileCollections.getCollection(".esm");
|
||||
|
@ -1057,8 +1063,25 @@ void DataFilesPage::writeConfig(QString profile)
|
|||
return;
|
||||
}
|
||||
|
||||
QString pathStr = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||
QDir userPath(pathStr);
|
||||
|
||||
if (!userPath.exists()) {
|
||||
if (!userPath.mkpath(pathStr)) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error creating OpenMW configuration directory");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not create %0</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>").arg(pathStr));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->exit(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Open the OpenMW config as a QFile
|
||||
QFile file(QString::fromStdString((mCfgMgr.getUserPath() / "openmw.cfg").string()));
|
||||
QFile file(pathStr.append("openmw.cfg"));
|
||||
|
||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||
// File cannot be opened or created
|
||||
|
|
57
apps/launcher/filedialog.cpp
Normal file
57
apps/launcher/filedialog.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "filedialog.hpp"
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
|
||||
FileDialog::FileDialog(QWidget *parent)
|
||||
: QFileDialog(parent)
|
||||
{
|
||||
// Remove the default Choose button to prevent it being updated elsewhere
|
||||
QDialogButtonBox *box = qFindChild<QDialogButtonBox*>(this);
|
||||
Q_ASSERT(box);
|
||||
box->removeButton(box->button(QDialogButtonBox::Open));
|
||||
|
||||
// Add our own button so we can disable/enable it
|
||||
mChooseButton = new QPushButton(tr("&Choose"));
|
||||
mChooseButton->setIcon(QIcon::fromTheme("document-open"));
|
||||
mChooseButton->setEnabled(false);
|
||||
box->addButton(mChooseButton, QDialogButtonBox::AcceptRole);
|
||||
|
||||
connect(this, SIGNAL(directoryEntered(const QString&)), this, SLOT(updateChooseButton(const QString&)));
|
||||
emit directoryEntered(QDir::currentPath());
|
||||
}
|
||||
|
||||
QString FileDialog::getExistingDirectory(QWidget *parent,
|
||||
const QString &caption,
|
||||
const QString &dir,
|
||||
Options options)
|
||||
{
|
||||
// create a non-native file dialog
|
||||
FileDialog dialog;
|
||||
dialog.setFileMode(DirectoryOnly);
|
||||
dialog.setOptions(options & (DontUseNativeDialog | ShowDirsOnly));
|
||||
|
||||
if (!caption.isEmpty())
|
||||
dialog.setWindowTitle(caption);
|
||||
|
||||
if (!dir.isEmpty())
|
||||
dialog.setDirectory(dir);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
return dialog.selectedFiles().value(0);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void FileDialog::updateChooseButton(const QString &directory)
|
||||
{
|
||||
QDir currentDir = QDir(directory);
|
||||
currentDir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
|
||||
currentDir.setNameFilters(QStringList() << "*.esm" << "*.esp");
|
||||
|
||||
if (!currentDir.entryList().isEmpty()) {
|
||||
// There are data files in the current dir
|
||||
mChooseButton->setEnabled(true);
|
||||
} else {
|
||||
mChooseButton->setEnabled(false);
|
||||
}
|
||||
}
|
28
apps/launcher/filedialog.hpp
Normal file
28
apps/launcher/filedialog.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef FILEDIALOG_HPP
|
||||
#define FILEDIALOG_HPP
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
class QPushButton;
|
||||
|
||||
class FileDialog : public QFileDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FileDialog(QWidget *parent = 0);
|
||||
|
||||
static QString getExistingDirectory(QWidget *parent = 0,
|
||||
const QString &caption = QString(),
|
||||
const QString &dir = QString(),
|
||||
Options options = ShowDirsOnly);
|
||||
|
||||
private slots:
|
||||
void updateChooseButton(const QString &directory);
|
||||
|
||||
private:
|
||||
QPushButton *mChooseButton;
|
||||
};
|
||||
|
||||
|
||||
#endif // FILEDIALOG_HPP
|
|
@ -200,12 +200,13 @@ void GraphicsPage::writeConfig()
|
|||
Settings::Manager::setBool("vsync", "Video", mVSyncCheckBox->checkState());
|
||||
Settings::Manager::setBool("fullscreen", "Video", mFullScreenCheckBox->checkState());
|
||||
Settings::Manager::setString("antialiasing", "Video", mAntiAliasingComboBox->currentText().toStdString());
|
||||
Settings::Manager::setString("render system", "Video", mRendererComboBox->currentText().toStdString());
|
||||
|
||||
std::string resolution = mResolutionComboBox->currentText().toStdString();
|
||||
// parse resolution x and y from a string like "800 x 600"
|
||||
size_t xPos = resolution.find("x");
|
||||
int resX = boost::lexical_cast<int>(resolution.substr(0, xPos-1));
|
||||
int resY = boost::lexical_cast<int>(resolution.substr(xPos+2, resolution.size()-(xPos+2)));
|
||||
QString resolution = mResolutionComboBox->currentText();
|
||||
QStringList tokens = resolution.split(" ", QString::SkipEmptyParts);
|
||||
int resX = boost::lexical_cast<int>(tokens.at(0).toStdString());
|
||||
int resY = boost::lexical_cast<int>(tokens.at(2).toStdString());
|
||||
Settings::Manager::setInt("resolution x", "Video", resX);
|
||||
Settings::Manager::setInt("resolution y", "Video", resY);
|
||||
}
|
||||
|
@ -239,6 +240,42 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy
|
|||
return result;
|
||||
}
|
||||
|
||||
QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer)
|
||||
{
|
||||
QString key ("Video Mode");
|
||||
QStringList result;
|
||||
|
||||
uint row = 0;
|
||||
Ogre::ConfigOptionMap options = renderer->getConfigOptions();
|
||||
|
||||
for (Ogre::ConfigOptionMap::iterator i = options.begin (); i != options.end (); i++, row++)
|
||||
{
|
||||
if (key.toStdString() != i->first)
|
||||
continue;
|
||||
|
||||
Ogre::StringVector::iterator opt_it;
|
||||
uint idx = 0;
|
||||
for (opt_it = i->second.possibleValues.begin ();
|
||||
opt_it != i->second.possibleValues.end (); opt_it++, idx++)
|
||||
{
|
||||
QString qval = QString::fromStdString(*opt_it).simplified();
|
||||
// remove extra tokens after the resolution (for example bpp, can be there or not depending on rendersystem)
|
||||
QStringList tokens = qval.split(" ", QString::SkipEmptyParts);
|
||||
assert (tokens.size() >= 3);
|
||||
QString resolutionStr = tokens.at(0) + QString(" x ") + tokens.at(2);
|
||||
{
|
||||
|
||||
// do not add duplicate resolutions
|
||||
if (!result.contains(resolutionStr))
|
||||
result << resolutionStr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void GraphicsPage::rendererChanged(const QString &renderer)
|
||||
{
|
||||
mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString());
|
||||
|
@ -247,5 +284,5 @@ void GraphicsPage::rendererChanged(const QString &renderer)
|
|||
mResolutionComboBox->clear();
|
||||
|
||||
mAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||
mResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mSelectedRenderSystem));
|
||||
mResolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem));
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ private:
|
|||
Files::ConfigurationManager &mCfgMgr;
|
||||
|
||||
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
||||
QStringList getAvailableResolutions(Ogre::RenderSystem *renderer);
|
||||
|
||||
void createPages();
|
||||
void setupConfig();
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2007 Trolltech ASA <info@trolltech.com>
|
||||
**
|
||||
** Use, modification and distribution is allowed without limitation,
|
||||
** warranty, liability or support of any kind.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "lineedit.hpp"
|
||||
#include <QToolButton>
|
||||
#include <QStyle>
|
||||
|
@ -14,33 +5,33 @@
|
|||
LineEdit::LineEdit(QWidget *parent)
|
||||
: QLineEdit(parent)
|
||||
{
|
||||
clearButton = new QToolButton(this);
|
||||
mClearButton = new QToolButton(this);
|
||||
QPixmap pixmap(":images/clear.png");
|
||||
clearButton->setIcon(QIcon(pixmap));
|
||||
clearButton->setIconSize(pixmap.size());
|
||||
clearButton->setCursor(Qt::ArrowCursor);
|
||||
clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
||||
clearButton->hide();
|
||||
connect(clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
||||
mClearButton->setIcon(QIcon(pixmap));
|
||||
mClearButton->setIconSize(pixmap.size());
|
||||
mClearButton->setCursor(Qt::ArrowCursor);
|
||||
mClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
||||
mClearButton->hide();
|
||||
connect(mClearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
||||
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&)));
|
||||
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||
setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(clearButton->sizeHint().width() + frameWidth + 1));
|
||||
setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1));
|
||||
QSize msz = minimumSizeHint();
|
||||
setMinimumSize(qMax(msz.width(), clearButton->sizeHint().height() + frameWidth * 2 + 2),
|
||||
qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2));
|
||||
setMinimumSize(qMax(msz.width(), mClearButton->sizeHint().height() + frameWidth * 2 + 2),
|
||||
qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2));
|
||||
}
|
||||
|
||||
void LineEdit::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
QSize sz = clearButton->sizeHint();
|
||||
QSize sz = mClearButton->sizeHint();
|
||||
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||
clearButton->move(rect().right() - frameWidth - sz.width(),
|
||||
mClearButton->move(rect().right() - frameWidth - sz.width(),
|
||||
(rect().bottom() + 1 - sz.height())/2);
|
||||
}
|
||||
|
||||
void LineEdit::updateCloseButton(const QString& text)
|
||||
{
|
||||
clearButton->setVisible(!text.isEmpty());
|
||||
mClearButton->setVisible(!text.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ private slots:
|
|||
void updateCloseButton(const QString &text);
|
||||
|
||||
private:
|
||||
QToolButton *clearButton;
|
||||
QToolButton *mClearButton;
|
||||
};
|
||||
|
||||
#endif // LIENEDIT_H
|
||||
|
|
|
@ -31,8 +31,10 @@ int main(int argc, char *argv[])
|
|||
|
||||
QDir::setCurrent(dir.absolutePath());
|
||||
|
||||
MainDialog dialog;
|
||||
return dialog.exec();
|
||||
MainDialog mainWin;
|
||||
mainWin.show();
|
||||
|
||||
return app.exec();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,10 @@ MainDialog::MainDialog()
|
|||
mSettings.loadUser(globaldefault);
|
||||
|
||||
|
||||
mIconWidget = new QListWidget;
|
||||
QWidget *centralWidget = new QWidget(this);
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
mIconWidget = new QListWidget(centralWidget);
|
||||
mIconWidget->setObjectName("IconWidget");
|
||||
mIconWidget->setViewMode(QListView::IconMode);
|
||||
mIconWidget->setWrapping(false);
|
||||
|
@ -43,7 +46,7 @@ MainDialog::MainDialog()
|
|||
mIconWidget->setCurrentRow(0);
|
||||
mIconWidget->setFlow(QListView::LeftToRight);
|
||||
|
||||
QGroupBox *groupBox = new QGroupBox(this);
|
||||
QGroupBox *groupBox = new QGroupBox(centralWidget);
|
||||
QVBoxLayout *groupLayout = new QVBoxLayout(groupBox);
|
||||
|
||||
mPagesWidget = new QStackedWidget(groupBox);
|
||||
|
@ -51,16 +54,15 @@ MainDialog::MainDialog()
|
|||
|
||||
QPushButton *playButton = new QPushButton(tr("Play"));
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(centralWidget);
|
||||
buttonBox->setStandardButtons(QDialogButtonBox::Close);
|
||||
buttonBox->addButton(playButton, QDialogButtonBox::AcceptRole);
|
||||
|
||||
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
||||
QVBoxLayout *dialogLayout = new QVBoxLayout(centralWidget);
|
||||
dialogLayout->addWidget(mIconWidget);
|
||||
dialogLayout->addWidget(groupBox);
|
||||
dialogLayout->addWidget(buttonBox);
|
||||
|
||||
|
||||
setWindowTitle(tr("OpenMW Launcher"));
|
||||
setWindowIcon(QIcon(":/images/openmw.png"));
|
||||
// Remove what's this? button
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef MAINDIALOG_H
|
||||
#define MAINDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMainWindow>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
@ -17,7 +17,7 @@ class PlayPage;
|
|||
class GraphicsPage;
|
||||
class DataFilesPage;
|
||||
|
||||
class MainDialog : public QDialog
|
||||
class MainDialog : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
@ -192,4 +192,17 @@ namespace MWClass
|
|||
{
|
||||
return getContainerStore (ptr).getWeight();
|
||||
}
|
||||
|
||||
void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const
|
||||
{
|
||||
if (lockLevel<0)
|
||||
lockLevel = 0;
|
||||
|
||||
ptr.getCellRef().lockLevel = lockLevel;
|
||||
}
|
||||
|
||||
void Container::unlock (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ptr.getCellRef().lockLevel = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,12 @@ namespace MWClass
|
|||
///< Returns total weight of objects inside this object (including modifications from magic
|
||||
/// effects). Throws an exception, if the object can't hold other objects.
|
||||
|
||||
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
|
||||
///< Lock object
|
||||
|
||||
virtual void unlock (const MWWorld::Ptr& ptr) const;
|
||||
///< Unlock object
|
||||
|
||||
static void registerSelf();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -57,6 +57,11 @@ namespace MWClass
|
|||
|
||||
data->mCreatureStats.mLevel = ref->base->data.level;
|
||||
|
||||
data->mCreatureStats.mHello = ref->base->AI.hello;
|
||||
data->mCreatureStats.mFight = ref->base->AI.fight;
|
||||
data->mCreatureStats.mFlee = ref->base->AI.flee;
|
||||
data->mCreatureStats.mAlarm = ref->base->AI.alarm;
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
}
|
||||
|
|
|
@ -70,12 +70,12 @@ namespace MWClass
|
|||
}
|
||||
}
|
||||
|
||||
// creature stats
|
||||
if(ref->base->npdt52.gold != -10)
|
||||
{
|
||||
for (int i=0; i<27; ++i)
|
||||
data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]);
|
||||
|
||||
// creature stats
|
||||
data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength);
|
||||
data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence);
|
||||
data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower);
|
||||
|
@ -95,6 +95,11 @@ namespace MWClass
|
|||
/// \todo do something with npdt12 maybe:p
|
||||
}
|
||||
|
||||
data->mCreatureStats.mHello = ref->base->AI.hello;
|
||||
data->mCreatureStats.mFight = ref->base->AI.fight;
|
||||
data->mCreatureStats.mFlee = ref->base->AI.flee;
|
||||
data->mCreatureStats.mAlarm = ref->base->AI.alarm;
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
}
|
||||
|
|
|
@ -843,7 +843,7 @@ namespace MWDialogue
|
|||
|
||||
void DialogueManager::goodbyeSelected()
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
|
||||
}
|
||||
|
||||
void DialogueManager::questionAnswered(std::string answere)
|
||||
|
|
|
@ -70,8 +70,8 @@ namespace MWGui
|
|||
|
||||
void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
mWindowManager.popGuiMode();
|
||||
mWindowManager.popGuiMode();
|
||||
mWindowManager.removeGuiMode(GM_Alchemy);
|
||||
mWindowManager.removeGuiMode(GM_Inventory);
|
||||
}
|
||||
|
||||
void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender)
|
||||
|
|
|
@ -92,7 +92,7 @@ void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
|||
// no 3d sounds because the object could be in a container.
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
mWindowManager.removeGuiMode(GM_Book);
|
||||
}
|
||||
|
||||
void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
|
@ -102,7 +102,7 @@ void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
|||
MWWorld::ActionTake take(mBook);
|
||||
take.execute();
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
mWindowManager.removeGuiMode(GM_Book);
|
||||
}
|
||||
|
||||
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* _sender)
|
||||
|
|
|
@ -708,6 +708,9 @@ void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
|
|||
if (mGenerateClassResultDialog)
|
||||
mWM->removeDialog(mGenerateClassResultDialog);
|
||||
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass);
|
||||
const ESM::Class *klass = MWBase::Environment::get().getWorld()->getStore().classes.find(mGenerateClass);
|
||||
mPlayerClass = *klass;
|
||||
mWM->setPlayerClass(mPlayerClass);
|
||||
|
||||
if (mCreationStage == CSE_ReviewNext)
|
||||
{
|
||||
|
|
|
@ -640,7 +640,7 @@ void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
|||
{
|
||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -671,7 +671,7 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
|
|||
|
||||
containerStore.clear();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -205,11 +205,14 @@ void addColorInString(std::string& str, const std::string& keyword,std::string c
|
|||
|
||||
std::string DialogueWindow::parseText(std::string text)
|
||||
{
|
||||
bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored)
|
||||
for(unsigned int i = 0;i<topicsList->getItemCount();i++)
|
||||
{
|
||||
std::string keyWord = topicsList->getItemNameAt(i);
|
||||
if (keyWord != "")
|
||||
if (separatorReached && keyWord != "")
|
||||
addColorInString(text,keyWord,"#686EBA","#B29154");
|
||||
else
|
||||
separatorReached = true;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ void MessageBoxManager::onFrame (float frameDuration)
|
|||
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
|
||||
delete mInterMessageBoxe;
|
||||
mInterMessageBoxe = NULL;
|
||||
mWindowManager->popGuiMode();
|
||||
mWindowManager->removeGuiMode(GM_InterMessageBox);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,13 +86,12 @@ void MessageBoxManager::createMessageBox (const std::string& message)
|
|||
|
||||
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
|
||||
{
|
||||
/// \todo Don't write this kind of error message to cout. Either discard the old message box
|
||||
/// silently or throw an exception.
|
||||
if(mInterMessageBoxe != NULL) {
|
||||
std::cout << "there is a MessageBox already" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "interactive MessageBox: " << message << " - ";
|
||||
std::copy (buttons.begin(), buttons.end(), std::ostream_iterator<std::string> (std::cout, ", "));
|
||||
std::cout << std::endl;
|
||||
|
||||
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
|||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
mWindowManager.removeGuiMode(GM_Scroll);
|
||||
}
|
||||
|
||||
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
|
@ -66,5 +66,5 @@ void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
|||
MWWorld::ActionTake take(mScroll);
|
||||
take.execute();
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
mWindowManager.removeGuiMode(GM_Scroll);
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ namespace MWGui
|
|||
|
||||
void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
mWindowManager.popGuiMode();
|
||||
mWindowManager.removeGuiMode(GM_Settings);
|
||||
}
|
||||
|
||||
void SettingsWindow::onResolutionSelected(MyGUI::ListBox* _sender, size_t index)
|
||||
|
|
|
@ -212,7 +212,7 @@ namespace MWGui
|
|||
std::string sound = "Item Gold Up";
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
mWindowManager.removeGuiMode(GM_Barter);
|
||||
}
|
||||
|
||||
void TradeWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
|
@ -222,7 +222,7 @@ namespace MWGui
|
|||
// now gimme back my stuff!
|
||||
mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mPtr).getContainerStore(mPtr));
|
||||
|
||||
mWindowManager.popGuiMode();
|
||||
mWindowManager.removeGuiMode(GM_Barter);
|
||||
}
|
||||
|
||||
void TradeWindow::updateLabels()
|
||||
|
|
|
@ -464,7 +464,7 @@ void WindowManager::onDialogueWindowBye()
|
|||
//removeDialog(dialogueWindow);
|
||||
mDialogueWindow->setVisible(false);
|
||||
}
|
||||
popGuiMode();
|
||||
removeGuiMode(GM_Dialogue);
|
||||
}
|
||||
|
||||
void WindowManager::onFrame (float frameDuration)
|
||||
|
@ -677,6 +677,9 @@ void WindowManager::removeGuiMode(GuiMode mode)
|
|||
++it;
|
||||
}
|
||||
|
||||
bool gameMode = !isGuiMode();
|
||||
MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode);
|
||||
|
||||
updateVisible();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ namespace MWMechanics
|
|||
Spells mSpells;
|
||||
ActiveSpells mActiveSpells;
|
||||
MagicEffects mMagicEffects;
|
||||
int mHello;
|
||||
int mFight;
|
||||
int mFlee;
|
||||
int mAlarm;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <components/interpreter/runtime.hpp>
|
||||
#include <components/interpreter/opcodes.hpp>
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
||||
#include "interpretercontext.hpp"
|
||||
#include "ref.hpp"
|
||||
|
||||
|
@ -88,6 +90,95 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpAiWander : public Interpreter::Opcode1
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
// Interpreter::Type_Float range = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
// Interpreter::Type_Float duration = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
// Interpreter::Type_Float time = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
// discard additional idle arguments for now
|
||||
// discard additional arguments (reset), because we have no idea what they mean.
|
||||
for (unsigned int i=0; i<arg0; ++i) runtime.pop();
|
||||
|
||||
std::cout << "AiWanter" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpSetHello : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).mHello = value;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpSetFight : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).mFight = value;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpSetFlee : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).mFlee = value;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpSetAlarm : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).mAlarm = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const int opcodeAiTravel = 0x20000;
|
||||
|
@ -96,6 +187,16 @@ namespace MWScript
|
|||
const int opcodeAiEscortExplicit = 0x20003;
|
||||
const int opcodeGetAiPackageDone = 0x200007c;
|
||||
const int opcodeGetAiPackageDoneExplicit = 0x200007d;
|
||||
const int opcodeAiWander = 0x20010;
|
||||
const int opcodeAiWanderExplicit = 0x20011;
|
||||
const int opcodeSetHello = 0x200015e;
|
||||
const int opcodeSetHelloExplicit = 0x200015d;
|
||||
const int opcodeSetFight = 0x200015e;
|
||||
const int opcodeSetFightExplicit = 0x200015f;
|
||||
const int opcodeSetFlee = 0x2000160;
|
||||
const int opcodeSetFleeExplicit = 0x2000161;
|
||||
const int opcodeSetAlarm = 0x2000162;
|
||||
const int opcodeSetAlarmExplicit = 0x2000163;
|
||||
|
||||
void registerExtensions (Compiler::Extensions& extensions)
|
||||
{
|
||||
|
@ -103,9 +204,16 @@ namespace MWScript
|
|||
opcodeAiTravelExplicit);
|
||||
extensions.registerInstruction ("aiescort", "cffff/l", opcodeAiEscort,
|
||||
opcodeAiEscortExplicit);
|
||||
extensions.registerInstruction ("aiwander", "fff/llllllllll", opcodeAiWander,
|
||||
opcodeAiWanderExplicit);
|
||||
|
||||
extensions.registerFunction ("getaipackagedone", 'l', "", opcodeGetAiPackageDone,
|
||||
opcodeGetAiPackageDoneExplicit);
|
||||
|
||||
extensions.registerInstruction ("sethello", "l", opcodeSetHello, opcodeSetHelloExplicit);
|
||||
extensions.registerInstruction ("setfight", "l", opcodeSetFight, opcodeSetFightExplicit);
|
||||
extensions.registerInstruction ("setflee", "l", opcodeSetFlee, opcodeSetFleeExplicit);
|
||||
extensions.registerInstruction ("setalarm", "l", opcodeSetAlarm, opcodeSetAlarmExplicit);
|
||||
}
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
|
@ -114,9 +222,19 @@ namespace MWScript
|
|||
interpreter.installSegment3 (opcodeAiTravelExplicit, new OpAiTravel<ExplicitRef>);
|
||||
interpreter.installSegment3 (opcodeAiEscort, new OpAiEscort<ImplicitRef>);
|
||||
interpreter.installSegment3 (opcodeAiEscortExplicit, new OpAiEscort<ExplicitRef>);
|
||||
interpreter.installSegment3 (opcodeAiWander, new OpAiWander<ImplicitRef>);
|
||||
interpreter.installSegment3 (opcodeAiWanderExplicit, new OpAiWander<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeGetAiPackageDone, new OpGetAiPackageDone<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeGetAiPackageDoneExplicit,
|
||||
new OpGetAiPackageDone<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetHello, new OpSetHello<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetHelloExplicit, new OpSetHello<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetFight, new OpSetFight<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetFightExplicit, new OpSetFight<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetFlee, new OpSetFlee<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetFleeExplicit, new OpSetFlee<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetAlarm, new OpSetAlarm<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetAlarmExplicit, new OpSetAlarm<ExplicitRef>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "scriptmanager.hpp"
|
||||
|
||||
namespace MWScript
|
||||
{
|
||||
CompilerContext::CompilerContext (Type type)
|
||||
|
@ -21,6 +23,18 @@ namespace MWScript
|
|||
return MWBase::Environment::get().getWorld()->getGlobalVariableType (name);
|
||||
}
|
||||
|
||||
char CompilerContext::getMemberType (const std::string& name, const std::string& id) const
|
||||
{
|
||||
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPtr (id, false);
|
||||
|
||||
std::string script = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
if (script.empty())
|
||||
return ' ';
|
||||
|
||||
return MWBase::Environment::get().getScriptManager()->getLocals (script).getType (name);
|
||||
}
|
||||
|
||||
bool CompilerContext::isId (const std::string& name) const
|
||||
{
|
||||
return
|
||||
|
|
|
@ -30,6 +30,9 @@ namespace MWScript
|
|||
/// 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
virtual char getGlobalType (const std::string& name) const;
|
||||
|
||||
virtual char getMemberType (const std::string& name, const std::string& id) const;
|
||||
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
|
||||
virtual bool isId (const std::string& name) const;
|
||||
///< Does \a name match an ID, that can be referenced?
|
||||
};
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "interpretercontext.hpp"
|
||||
#include "ref.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -54,11 +57,71 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpClearForceRun : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
MWWorld::Class::get (ptr).getNpcStats (ptr).mForceRun = false;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpForceRun : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
MWWorld::Class::get (ptr).getNpcStats (ptr).mForceRun = true;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpClearForceSneak : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
MWWorld::Class::get (ptr).getNpcStats (ptr).mForceSneak = false;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpForceSneak : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
MWWorld::Class::get (ptr).getNpcStats (ptr).mForceSneak = true;
|
||||
}
|
||||
};
|
||||
|
||||
const int numberOfControls = 7;
|
||||
|
||||
const int opcodeEnable = 0x200007e;
|
||||
const int opcodeDisable = 0x2000085;
|
||||
const int opcodeToggleCollision = 0x2000130;
|
||||
const int opcodeClearForceRun = 0x2000154;
|
||||
const int opcodeClearForceRunExplicit = 0x2000155;
|
||||
const int opcodeForceRun = 0x2000156;
|
||||
const int opcodeForceRunExplicit = 0x2000157;
|
||||
const int opcodeClearForceSneak = 0x2000158;
|
||||
const int opcodeClearForceSneakExplicit = 0x2000159;
|
||||
const int opcodeForceSneak = 0x200015a;
|
||||
const int opcodeForceSneakExplicit = 0x200015b;
|
||||
|
||||
const char *controls[numberOfControls] =
|
||||
{
|
||||
|
@ -79,6 +142,16 @@ namespace MWScript
|
|||
|
||||
extensions.registerInstruction ("togglecollision", "", opcodeToggleCollision);
|
||||
extensions.registerInstruction ("tcl", "", opcodeToggleCollision);
|
||||
|
||||
extensions.registerInstruction ("clearforcerun", "", opcodeClearForceRun,
|
||||
opcodeClearForceRunExplicit);
|
||||
extensions.registerInstruction ("forcerun", "", opcodeForceRun,
|
||||
opcodeForceRunExplicit);
|
||||
|
||||
extensions.registerInstruction ("clearforcesneak", "", opcodeClearForceSneak,
|
||||
opcodeClearForceSneakExplicit);
|
||||
extensions.registerInstruction ("forcesneak", "", opcodeForceSneak,
|
||||
opcodeForceSneakExplicit);
|
||||
}
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
|
@ -90,6 +163,20 @@ namespace MWScript
|
|||
}
|
||||
|
||||
interpreter.installSegment5 (opcodeToggleCollision, new OpToggleCollision);
|
||||
|
||||
interpreter.installSegment5 (opcodeClearForceRun, new OpClearForceRun<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeForceRun, new OpForceRun<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeClearForceSneak, new OpClearForceSneak<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeForceSneak, new OpForceSneak<ImplicitRef>);
|
||||
|
||||
interpreter.installSegment5 (opcodeClearForceRunExplicit,
|
||||
new OpClearForceRun<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeForceRunExplicit,
|
||||
new OpForceRun<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeClearForceSneakExplicit,
|
||||
new OpClearForceSneak<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeForceSneakExplicit,
|
||||
new OpForceSneak<ExplicitRef>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ op 0x2000c: PCLowerRank
|
|||
op 0x2000d: PCJoinFaction
|
||||
op 0x2000e: PCGetRank implicit
|
||||
op 0x2000f: PCGetRank explicit
|
||||
opcodes 0x20010-0x3ffff unused
|
||||
op 0x20010: AiWander
|
||||
op 0x20011: AiWander, explicit reference
|
||||
opcodes 0x20012-0x3ffff unused
|
||||
|
||||
Segment 4:
|
||||
(not implemented yet)
|
||||
|
@ -147,4 +149,20 @@ op 0x2000150: ForceGreeting, explicit reference
|
|||
op 0x2000151: ToggleFullHelp
|
||||
op 0x2000152: Goodbye
|
||||
op 0x2000153: DontSaveObject (left unimplemented)
|
||||
opcodes 0x2000154-0x3ffffff unused
|
||||
op 0x2000154: ClearForceRun
|
||||
op 0x2000155: ClearForceRun, explicit reference
|
||||
op 0x2000156: ForceRun
|
||||
op 0x2000157: ForceRun, explicit reference
|
||||
op 0x2000158: ClearForceSneak
|
||||
op 0x2000159: ClearForceSneak, explicit reference
|
||||
op 0x200015a: ForceSneak
|
||||
op 0x200015b: ForceSneak, explicit reference
|
||||
op 0x200015c: SetHello
|
||||
op 0x200015d: SetHello, explicit reference
|
||||
op 0x200015e: SetFight
|
||||
op 0x200015f: SetFight, explicit reference
|
||||
op 0x2000160: SetFlee
|
||||
op 0x2000161: SetFlee, explicit reference
|
||||
op 0x2000162: SetAlarm
|
||||
op 0x2000163: SetAlarm, explicit reference
|
||||
opcodes 0x2000164-0x3ffffff unused
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace MWScript
|
|||
extensions.registerInstruction ("enableclassmenu", "", opcodeEnableClassMenu);
|
||||
extensions.registerInstruction ("enablenamemenu", "", opcodeEnableNameMenu);
|
||||
extensions.registerInstruction ("enableracemenu", "", opcodeEnableRaceMenu);
|
||||
extensions.registerInstruction ("enablestatsreviewmenu", "",
|
||||
extensions.registerInstruction ("enablestatreviewmenu", "",
|
||||
opcodeEnableStatsReviewMenu);
|
||||
|
||||
extensions.registerInstruction ("enableinventorymenu", "", opcodeEnableInventoryMenu);
|
||||
|
|
|
@ -270,6 +270,84 @@ namespace MWScript
|
|||
MWBase::Environment::get().getWorld()->disable (ref);
|
||||
}
|
||||
|
||||
int InterpreterContext::getMemberShort (const std::string& id, const std::string& name) const
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 's');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
return ptr.getRefData().getLocals().mShorts[index];
|
||||
}
|
||||
|
||||
int InterpreterContext::getMemberLong (const std::string& id, const std::string& name) const
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'l');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
return ptr.getRefData().getLocals().mLongs[index];
|
||||
}
|
||||
|
||||
float InterpreterContext::getMemberFloat (const std::string& id, const std::string& name) const
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'f');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
return ptr.getRefData().getLocals().mFloats[index];
|
||||
}
|
||||
|
||||
void InterpreterContext::setMemberShort (const std::string& id, const std::string& name, int value)
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 's');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
ptr.getRefData().getLocals().mShorts[index] = value;
|
||||
}
|
||||
|
||||
void InterpreterContext::setMemberLong (const std::string& id, const std::string& name, int value)
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'l');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
ptr.getRefData().getLocals().mLongs[index] = value;
|
||||
}
|
||||
|
||||
void InterpreterContext::setMemberFloat (const std::string& id, const std::string& name, float value)
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'f');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
ptr.getRefData().getLocals().mFloats[index] = value;
|
||||
}
|
||||
|
||||
MWWorld::Ptr InterpreterContext::getReference()
|
||||
{
|
||||
return getReference ("", true);
|
||||
|
|
|
@ -107,6 +107,18 @@ namespace MWScript
|
|||
|
||||
virtual void disable (const std::string& id = "");
|
||||
|
||||
virtual int getMemberShort (const std::string& id, const std::string& name) const;
|
||||
|
||||
virtual int getMemberLong (const std::string& id, const std::string& name) const;
|
||||
|
||||
virtual float getMemberFloat (const std::string& id, const std::string& name) const;
|
||||
|
||||
virtual void setMemberShort (const std::string& id, const std::string& name, int value);
|
||||
|
||||
virtual void setMemberLong (const std::string& id, const std::string& name, int value);
|
||||
|
||||
virtual void setMemberFloat (const std::string& id, const std::string& name, float value);
|
||||
|
||||
MWWorld::Ptr getReference();
|
||||
///< Reference, that the script is running from (can be empty)
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <components/compiler/scanner.hpp>
|
||||
#include <components/compiler/context.hpp>
|
||||
#include <components/compiler/exception.hpp>
|
||||
|
||||
#include "extensions.hpp"
|
||||
|
||||
|
@ -46,8 +47,14 @@ namespace MWScript
|
|||
if (!mErrorHandler.isGood())
|
||||
Success = false;
|
||||
}
|
||||
catch (...)
|
||||
catch (const Compiler::SourceException&)
|
||||
{
|
||||
// error has already been reported via error handler
|
||||
Success = false;
|
||||
}
|
||||
catch (const std::exception& error)
|
||||
{
|
||||
std::cerr << "An exception has been thrown: " << error.what() << std::endl;
|
||||
Success = false;
|
||||
}
|
||||
|
||||
|
@ -140,6 +147,9 @@ namespace MWScript
|
|||
{
|
||||
if (!compile (name))
|
||||
{
|
||||
/// \todo Handle case of cyclic member variable access. Currently this could look up
|
||||
/// the whole application in an endless recursion.
|
||||
|
||||
// failed -> ignore script from now on.
|
||||
std::vector<Interpreter::Type_Code> empty;
|
||||
mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));
|
||||
|
@ -156,4 +166,43 @@ namespace MWScript
|
|||
{
|
||||
return mGlobalScripts;
|
||||
}
|
||||
|
||||
int ScriptManager::getLocalIndex (const std::string& scriptId, const std::string& variable,
|
||||
char type)
|
||||
{
|
||||
const ESM::Script *script = mStore.scripts.find (scriptId);
|
||||
|
||||
int offset = 0;
|
||||
int size = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 's':
|
||||
|
||||
offset = 0;
|
||||
size = script->data.numShorts;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
||||
offset = script->data.numShorts;
|
||||
size = script->data.numLongs;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
|
||||
offset = script->data.numShorts+script->data.numLongs;
|
||||
size = script->data.numFloats;
|
||||
|
||||
default:
|
||||
|
||||
throw std::runtime_error ("invalid variable type");
|
||||
}
|
||||
|
||||
for (int i=0; i<size; ++i)
|
||||
if (script->varNames.at (i+offset)==variable)
|
||||
return i;
|
||||
|
||||
throw std::runtime_error ("unable to access local variable " + variable + " of " + scriptId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,10 @@ namespace MWScript
|
|||
///< Return locals for script \a name.
|
||||
|
||||
GlobalScripts& getGlobalScripts();
|
||||
|
||||
int getLocalIndex (const std::string& scriptId, const std::string& variable, char type);
|
||||
///< Return index of the variable of the given name and type in the given script. Will
|
||||
/// throw an exception, if there is no such script or variable or the type does not match.
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ class OgreFile : public audiere::File
|
|||
}
|
||||
|
||||
size_t refs;
|
||||
virtual void ref() { ++refs; }
|
||||
virtual void unref()
|
||||
ADR_METHOD(void) ref() { ++refs; }
|
||||
ADR_METHOD(void) unref()
|
||||
{
|
||||
if(--refs == 0)
|
||||
delete this;
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace MWWorld
|
|||
{
|
||||
void ActionAlchemy::execute()
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Alchemy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,7 +142,10 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& ce
|
|||
(int(*)(int)) std::tolower);
|
||||
|
||||
if (std::binary_search (cell.mIds.begin(), cell.mIds.end(), lowerCase))
|
||||
{
|
||||
cell.load (mStore, mReader);
|
||||
fillContainers (cell);
|
||||
}
|
||||
else
|
||||
return Ptr();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
set(BULLET_ROOT $ENV{BULLET_ROOT})
|
||||
|
||||
macro(_FIND_BULLET_LIBRARY _var)
|
||||
find_library(${_var}
|
||||
NAMES
|
||||
|
|
|
@ -22,7 +22,7 @@ IF (WIN32) #Windows
|
|||
SET(MYGUISDK $ENV{MYGUI_HOME})
|
||||
IF (MYGUISDK)
|
||||
findpkg_begin ( "MYGUI" )
|
||||
MESSAGE(STATUS "Using MyGUI in OGRE SDK")
|
||||
MESSAGE(STATUS "Using MyGUI in MyGUI SDK")
|
||||
STRING(REGEX REPLACE "[\\]" "/" MYGUISDK "${MYGUISDK}" )
|
||||
|
||||
find_path ( MYGUI_INCLUDE_DIRS
|
||||
|
@ -35,7 +35,7 @@ MyGUI_OgrePlatform.h
|
|||
"${MYGUISDK}/Platforms/Ogre/OgrePlatform/include"
|
||||
NO_DEFAULT_PATH )
|
||||
|
||||
SET ( MYGUI_LIB_DIR ${MYGUISDK}/*/lib )
|
||||
SET ( MYGUI_LIB_DIR ${MYGUISDK}/lib ${MYGUISDK}/*/lib )
|
||||
|
||||
find_library ( MYGUI_LIBRARIES_REL NAMES
|
||||
MyGUIEngine.lib
|
||||
|
@ -69,7 +69,7 @@ make_library_set ( MYGUI_PLATFORM_LIBRARIES )
|
|||
MESSAGE ("${MYGUI_LIBRARIES}")
|
||||
MESSAGE ("${MYGUI_PLATFORM_LIBRARIES}")
|
||||
|
||||
findpkg_finish ( "MYGUI" )
|
||||
#findpkg_finish ( "MYGUI" )
|
||||
|
||||
ENDIF (MYGUISDK)
|
||||
IF (OGRESOURCE)
|
||||
|
|
|
@ -33,10 +33,12 @@ namespace Compiler
|
|||
virtual char getGlobalType (const std::string& name) const = 0;
|
||||
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
|
||||
virtual char getMemberType (const std::string& name, const std::string& id) const = 0;
|
||||
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
|
||||
virtual bool isId (const std::string& name) const = 0;
|
||||
///< Does \a name match an ID, that can be referenced?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -195,10 +195,31 @@ namespace Compiler
|
|||
return parseArguments (arguments, scanner, mCode);
|
||||
}
|
||||
|
||||
bool ExprParser::handleMemberAccess (const std::string& name)
|
||||
{
|
||||
mMemberOp = false;
|
||||
|
||||
std::string name2 = toLower (name);
|
||||
std::string id = toLower (mExplicit);
|
||||
|
||||
char type = getContext().getMemberType (name2, id);
|
||||
|
||||
if (type!=' ')
|
||||
{
|
||||
Generator::fetchMember (mCode, mLiterals, type, name2, id);
|
||||
mNextOperand = false;
|
||||
mExplicit.clear();
|
||||
mOperands.push_back (type=='f' ? 'f' : 'l');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||
Literals& literals, bool argument)
|
||||
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals),
|
||||
mNextOperand (true), mFirst (true), mArgument (argument)
|
||||
mNextOperand (true), mFirst (true), mArgument (argument), mRefOp (false), mMemberOp (false)
|
||||
{}
|
||||
|
||||
bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
||||
|
@ -251,7 +272,12 @@ namespace Compiler
|
|||
Scanner& scanner)
|
||||
{
|
||||
if (!mExplicit.empty())
|
||||
{
|
||||
if (mMemberOp && handleMemberAccess (name))
|
||||
return true;
|
||||
|
||||
return Parser::parseName (name, loc, scanner);
|
||||
}
|
||||
|
||||
mFirst = false;
|
||||
|
||||
|
@ -281,9 +307,9 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
if (mExplicit.empty() && getContext().isId (name))
|
||||
if (mExplicit.empty() && getContext().isId (name2))
|
||||
{
|
||||
mExplicit = name;
|
||||
mExplicit = name2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -497,6 +523,12 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!mMemberOp && code==Scanner::S_member)
|
||||
{
|
||||
mMemberOp = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return Parser::parseSpecial (code, loc, scanner);
|
||||
}
|
||||
|
||||
|
@ -609,6 +641,7 @@ namespace Compiler
|
|||
mFirst = true;
|
||||
mExplicit.clear();
|
||||
mRefOp = false;
|
||||
mMemberOp = false;
|
||||
Parser::reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Compiler
|
|||
bool mArgument;
|
||||
std::string mExplicit;
|
||||
bool mRefOp;
|
||||
bool mMemberOp;
|
||||
|
||||
int getPriority (char op) const;
|
||||
|
||||
|
@ -53,6 +54,8 @@ namespace Compiler
|
|||
|
||||
int parseArguments (const std::string& arguments, Scanner& scanner);
|
||||
|
||||
bool handleMemberAccess (const std::string& name);
|
||||
|
||||
public:
|
||||
|
||||
ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||
|
|
|
@ -260,6 +260,36 @@ namespace
|
|||
code.push_back (Compiler::Generator::segment5 (44));
|
||||
}
|
||||
|
||||
void opStoreMemberShort (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (59));
|
||||
}
|
||||
|
||||
void opStoreMemberLong (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (60));
|
||||
}
|
||||
|
||||
void opStoreMemberFloat (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (61));
|
||||
}
|
||||
|
||||
void opFetchMemberShort (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (62));
|
||||
}
|
||||
|
||||
void opFetchMemberLong (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (63));
|
||||
}
|
||||
|
||||
void opFetchMemberFloat (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (64));
|
||||
}
|
||||
|
||||
void opRandom (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (45));
|
||||
|
@ -644,7 +674,7 @@ namespace Compiler
|
|||
|
||||
if (localType!=valueType)
|
||||
{
|
||||
if (localType=='f' && valueType=='l')
|
||||
if (localType=='f' && (valueType=='l' || valueType=='s'))
|
||||
{
|
||||
opIntToFloat (code);
|
||||
}
|
||||
|
@ -707,6 +737,88 @@ namespace Compiler
|
|||
}
|
||||
}
|
||||
|
||||
void assignToMember (CodeContainer& code, Literals& literals, char localType,
|
||||
const std::string& name, const std::string& id, const CodeContainer& value, char valueType)
|
||||
{
|
||||
int index = literals.addString (name);
|
||||
|
||||
opPushInt (code, index);
|
||||
|
||||
index = literals.addString (id);
|
||||
|
||||
opPushInt (code, index);
|
||||
|
||||
std::copy (value.begin(), value.end(), std::back_inserter (code));
|
||||
|
||||
if (localType!=valueType)
|
||||
{
|
||||
if (localType=='f' && (valueType=='l' || valueType=='s'))
|
||||
{
|
||||
opIntToFloat (code);
|
||||
}
|
||||
else if ((localType=='l' || localType=='s') && valueType=='f')
|
||||
{
|
||||
opFloatToInt (code);
|
||||
}
|
||||
}
|
||||
|
||||
switch (localType)
|
||||
{
|
||||
case 'f':
|
||||
|
||||
opStoreMemberFloat (code);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
|
||||
opStoreMemberShort (code);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
||||
opStoreMemberLong (code);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
void fetchMember (CodeContainer& code, Literals& literals, char localType,
|
||||
const std::string& name, const std::string& id)
|
||||
{
|
||||
int index = literals.addString (name);
|
||||
|
||||
opPushInt (code, index);
|
||||
|
||||
index = literals.addString (id);
|
||||
|
||||
opPushInt (code, index);
|
||||
|
||||
switch (localType)
|
||||
{
|
||||
case 'f':
|
||||
|
||||
opFetchMemberFloat (code);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
|
||||
opFetchMemberShort (code);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
||||
opFetchMemberLong (code);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
void random (CodeContainer& code)
|
||||
{
|
||||
opRandom (code);
|
||||
|
|
|
@ -101,6 +101,12 @@ namespace Compiler
|
|||
void fetchGlobal (CodeContainer& code, Literals& literals, char localType,
|
||||
const std::string& name);
|
||||
|
||||
void assignToMember (CodeContainer& code, Literals& literals, char memberType,
|
||||
const std::string& name, const std::string& id, const CodeContainer& value, char valueType);
|
||||
|
||||
void fetchMember (CodeContainer& code, Literals& literals, char memberType,
|
||||
const std::string& name, const std::string& id);
|
||||
|
||||
void random (CodeContainer& code);
|
||||
|
||||
void scriptRunning (CodeContainer& code);
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace Compiler
|
|||
if (!mExplicit.empty())
|
||||
{
|
||||
mExprParser.parseName (mExplicit, loc, scanner);
|
||||
if (mState==MemberState)
|
||||
mExprParser.parseSpecial (Scanner::S_member, loc, scanner);
|
||||
else
|
||||
mExprParser.parseSpecial (Scanner::S_ref, loc, scanner);
|
||||
}
|
||||
|
||||
|
@ -110,12 +113,13 @@ namespace Compiler
|
|||
if (mState==SetState)
|
||||
{
|
||||
std::string name2 = toLower (name);
|
||||
mName = name2;
|
||||
|
||||
// local variable?
|
||||
char type = mLocals.getType (name2);
|
||||
if (type!=' ')
|
||||
{
|
||||
mName = name2;
|
||||
mType = type;
|
||||
mState = SetLocalVarState;
|
||||
return true;
|
||||
}
|
||||
|
@ -123,12 +127,27 @@ namespace Compiler
|
|||
type = getContext().getGlobalType (name2);
|
||||
if (type!=' ')
|
||||
{
|
||||
mName = name2;
|
||||
mType = type;
|
||||
mState = SetGlobalVarState;
|
||||
return true;
|
||||
}
|
||||
|
||||
mState = SetPotentialMemberVarState;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mState==SetMemberVarState)
|
||||
{
|
||||
mMemberName = toLower (name);
|
||||
char type = getContext().getMemberType (mMemberName, mName);
|
||||
|
||||
if (type!=' ')
|
||||
{
|
||||
mState = SetMemberVarState2;
|
||||
mType = type;
|
||||
return true;
|
||||
}
|
||||
|
||||
getErrorHandler().error ("unknown variable", loc);
|
||||
SkipParser skip (getErrorHandler(), getContext());
|
||||
scanner.scan (skip);
|
||||
|
@ -256,6 +275,7 @@ namespace Compiler
|
|||
{
|
||||
scanner.putbackKeyword (keyword, loc);
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -269,6 +289,7 @@ namespace Compiler
|
|||
{
|
||||
scanner.putbackKeyword (keyword, loc);
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -333,6 +354,19 @@ namespace Compiler
|
|||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
else if (mState==SetMemberVarState2 && keyword==Scanner::K_to)
|
||||
{
|
||||
mExprParser.reset();
|
||||
scanner.scan (mExprParser);
|
||||
|
||||
std::vector<Interpreter::Type_Code> code;
|
||||
char type = mExprParser.append (code);
|
||||
|
||||
Generator::assignToMember (mCode, mLiterals, mType, mMemberName, mName, code, type);
|
||||
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mAllowExpression)
|
||||
{
|
||||
|
@ -342,6 +376,7 @@ namespace Compiler
|
|||
{
|
||||
scanner.putbackKeyword (keyword, loc);
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -366,6 +401,14 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
if (code==Scanner::S_member && mState==PotentialExplicitState)
|
||||
{
|
||||
mState = MemberState;
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (code==Scanner::S_newline && mState==MessageButtonState)
|
||||
{
|
||||
Generator::message (mCode, mLiterals, mName, mButtons);
|
||||
|
@ -378,11 +421,18 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
if (code==Scanner::S_member && mState==SetPotentialMemberVarState)
|
||||
{
|
||||
mState = SetMemberVarState;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mAllowExpression && mState==BeginState &&
|
||||
(code==Scanner::S_open || code==Scanner::S_minus))
|
||||
{
|
||||
scanner.putbackSpecial (code, loc);
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,11 @@ namespace Compiler
|
|||
{
|
||||
BeginState,
|
||||
ShortState, LongState, FloatState,
|
||||
SetState, SetLocalVarState, SetGlobalVarState,
|
||||
SetState, SetLocalVarState, SetGlobalVarState, SetPotentialMemberVarState,
|
||||
SetMemberVarState, SetMemberVarState2,
|
||||
MessageState, MessageCommaState, MessageButtonState, MessageButtonCommaState,
|
||||
EndState,
|
||||
PotentialExplicitState, ExplicitState
|
||||
PotentialExplicitState, ExplicitState, MemberState
|
||||
};
|
||||
|
||||
Locals& mLocals;
|
||||
|
@ -32,6 +33,7 @@ namespace Compiler
|
|||
std::vector<Interpreter::Type_Code>& mCode;
|
||||
State mState;
|
||||
std::string mName;
|
||||
std::string mMemberName;
|
||||
int mButtons;
|
||||
std::string mExplicit;
|
||||
char mType;
|
||||
|
|
|
@ -360,6 +360,8 @@ namespace Compiler
|
|||
special = S_open;
|
||||
else if (c==')')
|
||||
special = S_close;
|
||||
else if (c=='.')
|
||||
special = S_member;
|
||||
else if (c=='=')
|
||||
{
|
||||
if (get (c))
|
||||
|
|
|
@ -65,7 +65,8 @@ namespace Compiler
|
|||
S_cmpEQ, S_cmpNE, S_cmpLT, S_cmpLE, S_cmpGT, S_cmpGE,
|
||||
S_plus, S_minus, S_mult, S_div,
|
||||
S_comma,
|
||||
S_ref
|
||||
S_ref,
|
||||
S_member
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -65,6 +65,19 @@ namespace Interpreter
|
|||
virtual void enable (const std::string& id = "") = 0;
|
||||
|
||||
virtual void disable (const std::string& id = "") = 0;
|
||||
|
||||
virtual int getMemberShort (const std::string& id, const std::string& name) const = 0;
|
||||
|
||||
virtual int getMemberLong (const std::string& id, const std::string& name) const = 0;
|
||||
|
||||
virtual float getMemberFloat (const std::string& id, const std::string& name) const = 0;
|
||||
|
||||
virtual void setMemberShort (const std::string& id, const std::string& name, int value) = 0;
|
||||
|
||||
virtual void setMemberLong (const std::string& id, const std::string& name, int value) = 0;
|
||||
|
||||
virtual void setMemberFloat (const std::string& id, const std::string& name, float value)
|
||||
= 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -121,5 +121,11 @@ op 58: report string literal index in stack[0];
|
|||
additional arguments (if any) in stack[n]..stack[1];
|
||||
n is determined according to the message string
|
||||
all arguments are removed from stack
|
||||
opcodes 59-33554431 unused
|
||||
op 59: store stack[0] in member short stack[2] of object with ID stack[1]
|
||||
op 60: store stack[0] in member long stack[2] of object with ID stack[1]
|
||||
op 61: store stack[0] in member float stack[2] of object with ID stack[1]
|
||||
op 62: replace stack[0] with member short stack[1] of object with ID stack[0]
|
||||
op 63: replace stack[0] with member short stack[1] of object with ID stack[0]
|
||||
op 64: replace stack[0] with member short stack[1] of object with ID stack[0]
|
||||
opcodes 65-33554431 unused
|
||||
opcodes 33554432-67108863 reserved for extensions
|
||||
|
|
|
@ -40,6 +40,12 @@ namespace Interpreter
|
|||
interpreter.installSegment5 (42, new OpFetchGlobalShort);
|
||||
interpreter.installSegment5 (43, new OpFetchGlobalLong);
|
||||
interpreter.installSegment5 (44, new OpFetchGlobalFloat);
|
||||
interpreter.installSegment5 (59, new OpStoreMemberShort);
|
||||
interpreter.installSegment5 (60, new OpStoreMemberLong);
|
||||
interpreter.installSegment5 (61, new OpStoreMemberFloat);
|
||||
interpreter.installSegment5 (62, new OpFetchMemberShort);
|
||||
interpreter.installSegment5 (63, new OpFetchMemberLong);
|
||||
interpreter.installSegment5 (64, new OpFetchMemberFloat);
|
||||
|
||||
// math
|
||||
interpreter.installSegment5 (9, new OpAddInt<Type_Integer>);
|
||||
|
|
|
@ -205,7 +205,117 @@ namespace Interpreter
|
|||
runtime[0].mFloat = value;
|
||||
}
|
||||
};
|
||||
|
||||
class OpStoreMemberShort : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
Type_Integer index = runtime[1].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[2].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
|
||||
runtime.getContext().setMemberShort (id, variable, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
};
|
||||
|
||||
class OpStoreMemberLong : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
Type_Integer index = runtime[1].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[2].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
|
||||
runtime.getContext().setMemberLong (id, variable, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
};
|
||||
|
||||
class OpStoreMemberFloat : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float data = runtime[0].mFloat;
|
||||
Type_Integer index = runtime[1].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[2].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
|
||||
runtime.getContext().setMemberFloat (id, variable, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchMemberShort : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer index = runtime[0].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[1].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
runtime.pop();
|
||||
|
||||
int value = runtime.getContext().getMemberShort (id, variable);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchMemberLong : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer index = runtime[0].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[1].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
runtime.pop();
|
||||
|
||||
int value = runtime.getContext().getMemberLong (id, variable);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchMemberFloat : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer index = runtime[0].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[1].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
runtime.pop();
|
||||
|
||||
float value = runtime.getContext().getMemberFloat (id, variable);
|
||||
runtime[0].mFloat = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -222,6 +222,14 @@ namespace Physic
|
|||
PhysicEngine::~PhysicEngine()
|
||||
{
|
||||
|
||||
HeightFieldContainer::iterator hf_it = mHeightFieldMap.begin();
|
||||
for (; hf_it != mHeightFieldMap.end(); ++hf_it)
|
||||
{
|
||||
dynamicsWorld->removeRigidBody(hf_it->second.mBody);
|
||||
delete hf_it->second.mShape;
|
||||
delete hf_it->second.mBody;
|
||||
}
|
||||
|
||||
RigidBodyContainer::iterator rb_it = RigidBodyMap.begin();
|
||||
for (; rb_it != RigidBodyMap.end(); ++rb_it)
|
||||
{
|
||||
|
@ -320,6 +328,8 @@ namespace Physic
|
|||
dynamicsWorld->removeRigidBody(hf.mBody);
|
||||
delete hf.mShape;
|
||||
delete hf.mBody;
|
||||
|
||||
mHeightFieldMap.erase(name);
|
||||
}
|
||||
|
||||
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale)
|
||||
|
@ -478,7 +488,7 @@ namespace Physic
|
|||
dynamicsWorld->rayTest(from, to, resultCallback1);
|
||||
if (resultCallback1.hasHit())
|
||||
{
|
||||
name = static_cast<RigidBody&>(*resultCallback1.m_collisionObject).mName;
|
||||
name = static_cast<const RigidBody&>(*resultCallback1.m_collisionObject).mName;
|
||||
d1 = resultCallback1.m_closestHitFraction;
|
||||
d = d1;
|
||||
}
|
||||
|
@ -492,7 +502,7 @@ namespace Physic
|
|||
d2 = resultCallback1.m_closestHitFraction;
|
||||
if(d2<=d1)
|
||||
{
|
||||
name = static_cast<PairCachingGhostObject&>(*resultCallback2.m_collisionObject).mName;
|
||||
name = static_cast<const PairCachingGhostObject&>(*resultCallback2.m_collisionObject).mName;
|
||||
d = d2;
|
||||
}
|
||||
}
|
||||
|
@ -505,25 +515,25 @@ namespace Physic
|
|||
MyRayResultCallback resultCallback1;
|
||||
resultCallback1.m_collisionFilterMask = COL_WORLD|COL_RAYCASTING;
|
||||
dynamicsWorld->rayTest(from, to, resultCallback1);
|
||||
std::vector< std::pair<float, btCollisionObject*> > results = resultCallback1.results;
|
||||
std::vector< std::pair<float, const btCollisionObject*> > results = resultCallback1.results;
|
||||
|
||||
MyRayResultCallback resultCallback2;
|
||||
resultCallback2.m_collisionFilterMask = COL_ACTOR_INTERNAL|COL_ACTOR_EXTERNAL;
|
||||
dynamicsWorld->rayTest(from, to, resultCallback2);
|
||||
std::vector< std::pair<float, btCollisionObject*> > actorResults = resultCallback2.results;
|
||||
std::vector< std::pair<float, const btCollisionObject*> > actorResults = resultCallback2.results;
|
||||
|
||||
std::vector< std::pair<float, std::string> > results2;
|
||||
|
||||
for (std::vector< std::pair<float, btCollisionObject*> >::iterator it=results.begin();
|
||||
for (std::vector< std::pair<float, const btCollisionObject*> >::iterator it=results.begin();
|
||||
it != results.end(); ++it)
|
||||
{
|
||||
results2.push_back( std::make_pair( (*it).first, static_cast<RigidBody&>(*(*it).second).mName ) );
|
||||
results2.push_back( std::make_pair( (*it).first, static_cast<const RigidBody&>(*(*it).second).mName ) );
|
||||
}
|
||||
|
||||
for (std::vector< std::pair<float, btCollisionObject*> >::iterator it=actorResults.begin();
|
||||
for (std::vector< std::pair<float, const btCollisionObject*> >::iterator it=actorResults.begin();
|
||||
it != actorResults.end(); ++it)
|
||||
{
|
||||
results2.push_back( std::make_pair( (*it).first, static_cast<PairCachingGhostObject&>(*(*it).second).mName ) );
|
||||
results2.push_back( std::make_pair( (*it).first, static_cast<const PairCachingGhostObject&>(*(*it).second).mName ) );
|
||||
}
|
||||
|
||||
std::sort(results2.begin(), results2.end(), MyRayResultCallback::cmp);
|
||||
|
|
|
@ -278,7 +278,7 @@ namespace Physic
|
|||
return false;
|
||||
}
|
||||
|
||||
std::vector < std::pair<float, btCollisionObject*> > results;
|
||||
std::vector < std::pair<float, const btCollisionObject*> > results;
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -15,8 +15,6 @@ Quake 3 Arena is copyright (C) 1999-2005 Id Software, Inc.
|
|||
|
||||
//#include "GameTime.h"
|
||||
|
||||
//#include "Object.h"
|
||||
|
||||
//#include "Sound.h"
|
||||
|
||||
//#include "..\..\ESMParser\ESMParser\SNDG.h"
|
||||
|
@ -68,7 +66,6 @@ static struct playermoveLocal
|
|||
int waterHeight;
|
||||
bool hasWater;
|
||||
bool isInterior;
|
||||
//Object* traceObj;
|
||||
|
||||
} pml;
|
||||
|
||||
|
@ -1833,13 +1830,6 @@ void PmoveSingle (playerMove* const pmove)
|
|||
pml.hasWater = pmove->hasWater;
|
||||
pml.isInterior = pmove->isInterior;
|
||||
pml.waterHeight = pmove->waterHeight;
|
||||
#ifdef _DEBUG
|
||||
if (!pml.traceObj)
|
||||
__debugbreak();
|
||||
|
||||
if (!pml.traceObj->incellptr)
|
||||
__debugbreak();
|
||||
#endif
|
||||
|
||||
// determine the time
|
||||
pml.msec = pmove->cmd.serverTime - pm->ps.commandTime;
|
||||
|
|
|
@ -190,7 +190,6 @@ struct playerMove
|
|||
int waterHeight;
|
||||
bool hasWater;
|
||||
bool isInterior;
|
||||
//Object* traceObj;
|
||||
OEngine::Physic::PhysicEngine* mEngine;
|
||||
};
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ Nikolay “corristo” Kasyanov
|
|||
Pieter “pvdk” van der Kloet
|
||||
Roman "Kromgart" Melnik
|
||||
Sebastian “swick” Wick
|
||||
Sylvain "Garvek" T.
|
||||
|
||||
Retired Developers:
|
||||
Ardekantur
|
||||
|
|
Loading…
Reference in a new issue