forked from teamnwah/openmw-tes3coop
resolving conflicts
This commit is contained in:
commit
18cc435aa1
94 changed files with 2875 additions and 523 deletions
|
@ -15,7 +15,7 @@ include (OpenMWMacros)
|
||||||
# Version
|
# Version
|
||||||
|
|
||||||
set (OPENMW_VERSION_MAJOR 0)
|
set (OPENMW_VERSION_MAJOR 0)
|
||||||
set (OPENMW_VERSION_MINOR 17)
|
set (OPENMW_VERSION_MINOR 18)
|
||||||
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}")
|
||||||
|
@ -513,6 +513,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
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(d ${WARNINGS_DISABLE})
|
foreach(d ${WARNINGS_DISABLE})
|
||||||
|
@ -524,6 +525,7 @@ if (WIN32)
|
||||||
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})
|
||||||
|
set_target_properties(esmtool PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
|
|
||||||
# Same for MinGW
|
# Same for MinGW
|
||||||
|
@ -631,7 +633,7 @@ if (APPLE)
|
||||||
include(CPack)
|
include(CPack)
|
||||||
endif (APPLE)
|
endif (APPLE)
|
||||||
|
|
||||||
if (NOT WIN32 AND NOT DPKG_PROGRAM)
|
if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
|
||||||
## Non Debian based Linux building
|
## Non Debian based Linux building
|
||||||
# paths
|
# paths
|
||||||
set(BINDIR "${CMAKE_INSTALL_PREFIX}/usr/bin" CACHE PATH "Where to install binaries")
|
set(BINDIR "${CMAKE_INSTALL_PREFIX}/usr/bin" CACHE PATH "Where to install binaries")
|
||||||
|
@ -662,4 +664,4 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM)
|
||||||
# Install resources
|
# Install resources
|
||||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" )
|
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" )
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${DATADIR}/resources" )
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${DATADIR}/resources" )
|
||||||
endif(NOT WIN32 AND NOT DPKG_PROGRAM)
|
endif(NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
|
||||||
|
|
|
@ -189,73 +189,8 @@ void DataFilesPage::setupConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DataFilesPage::setupDataFiles()
|
void DataFilesPage::addDataFiles(Files::Collections &fileCollections, const QString &encoding)
|
||||||
{
|
{
|
||||||
// We use the Configuration Manager to retrieve the configuration values
|
|
||||||
boost::program_options::variables_map variables;
|
|
||||||
boost::program_options::options_description desc;
|
|
||||||
|
|
||||||
desc.add_options()
|
|
||||||
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken())
|
|
||||||
("data-local", boost::program_options::value<std::string>()->default_value(""))
|
|
||||||
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
|
||||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"));
|
|
||||||
|
|
||||||
mCfgMgr.readConfiguration(variables, desc);
|
|
||||||
|
|
||||||
// Put the paths in a boost::filesystem vector to use with Files::Collections
|
|
||||||
mDataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
|
||||||
|
|
||||||
std::string local = variables["data-local"].as<std::string>();
|
|
||||||
if (!local.empty()) {
|
|
||||||
mDataLocal.push_back(Files::PathContainer::value_type(local));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mDataDirs.size()>1)
|
|
||||||
mDataDirs.resize (1);
|
|
||||||
|
|
||||||
mCfgMgr.processPaths(mDataDirs);
|
|
||||||
|
|
||||||
while (mDataDirs.empty()) {
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle("Error detecting Morrowind installation");
|
|
||||||
msgBox.setIcon(QMessageBox::Warning);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Cancel);
|
|
||||||
msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \
|
|
||||||
The directory containing the data files was not found.<br><br> \
|
|
||||||
Press \"Browse...\" to specify the location manually.<br>"));
|
|
||||||
|
|
||||||
QAbstractButton *dirSelectButton =
|
|
||||||
msgBox.addButton(tr("B&rowse..."), QMessageBox::ActionRole);
|
|
||||||
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
if (msgBox.clickedButton() == dirSelectButton) {
|
|
||||||
|
|
||||||
// Show a custom dir selection dialog which only accepts valid dirs
|
|
||||||
QString selectedDir = FileDialog::getExistingDirectory(
|
|
||||||
this, tr("Select Data Files Directory"),
|
|
||||||
QDir::currentPath(),
|
|
||||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
|
||||||
|
|
||||||
// Add the user selected data directory
|
|
||||||
if (!selectedDir.isEmpty()) {
|
|
||||||
mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString()));
|
|
||||||
mCfgMgr.processPaths(mDataDirs);
|
|
||||||
} else {
|
|
||||||
// Cancel from within the dir selection dialog
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Cancel
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a file collection for the data dirs
|
|
||||||
Files::Collections fileCollections(mDataDirs, !variables["fs-strict"].as<bool>());
|
|
||||||
|
|
||||||
// First we add all the master files
|
// First we add all the master files
|
||||||
const Files::MultiDirCollection &esm = fileCollections.getCollection(".esm");
|
const Files::MultiDirCollection &esm = fileCollections.getCollection(".esm");
|
||||||
unsigned int i = 0; // Row number
|
unsigned int i = 0; // Row number
|
||||||
|
@ -283,7 +218,7 @@ bool DataFilesPage::setupDataFiles()
|
||||||
ESMReader fileReader;
|
ESMReader fileReader;
|
||||||
QStringList availableMasters; // Will contain all found masters
|
QStringList availableMasters; // Will contain all found masters
|
||||||
|
|
||||||
fileReader.setEncoding(variables["encoding"].as<std::string>());
|
fileReader.setEncoding(encoding.toStdString());
|
||||||
fileReader.open(iter->second.string());
|
fileReader.open(iter->second.string());
|
||||||
|
|
||||||
// First we fill the availableMasters and the mMastersWidget
|
// First we fill the availableMasters and the mMastersWidget
|
||||||
|
@ -350,10 +285,86 @@ bool DataFilesPage::setupDataFiles()
|
||||||
|
|
||||||
} catch(std::runtime_error &e) {
|
} catch(std::runtime_error &e) {
|
||||||
// An error occurred while reading the .esp
|
// An error occurred while reading the .esp
|
||||||
|
std::cerr << "Error reading .esp: " << e.what() << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DataFilesPage::setupDataFiles()
|
||||||
|
{
|
||||||
|
// We use the Configuration Manager to retrieve the configuration values
|
||||||
|
boost::program_options::variables_map variables;
|
||||||
|
boost::program_options::options_description desc;
|
||||||
|
|
||||||
|
desc.add_options()
|
||||||
|
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken())
|
||||||
|
("data-local", boost::program_options::value<std::string>()->default_value(""))
|
||||||
|
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
||||||
|
("encoding", boost::program_options::value<std::string>()->default_value("win1252"));
|
||||||
|
|
||||||
|
mCfgMgr.readConfiguration(variables, desc);
|
||||||
|
|
||||||
|
// Put the paths in a boost::filesystem vector to use with Files::Collections
|
||||||
|
mDataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||||
|
|
||||||
|
std::string local = variables["data-local"].as<std::string>();
|
||||||
|
if (!local.empty()) {
|
||||||
|
mDataLocal.push_back(Files::PathContainer::value_type(local));
|
||||||
|
}
|
||||||
|
|
||||||
|
mCfgMgr.processPaths(mDataDirs);
|
||||||
|
mCfgMgr.processPaths(mDataLocal);
|
||||||
|
|
||||||
|
while (mDataDirs.empty()) {
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle("Error detecting Morrowind installation");
|
||||||
|
msgBox.setIcon(QMessageBox::Warning);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Cancel);
|
||||||
|
msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \
|
||||||
|
The directory containing the data files was not found.<br><br> \
|
||||||
|
Press \"Browse...\" to specify the location manually.<br>"));
|
||||||
|
|
||||||
|
QAbstractButton *dirSelectButton =
|
||||||
|
msgBox.addButton(tr("B&rowse..."), QMessageBox::ActionRole);
|
||||||
|
|
||||||
|
msgBox.exec();
|
||||||
|
|
||||||
|
if (msgBox.clickedButton() == dirSelectButton) {
|
||||||
|
|
||||||
|
// Show a custom dir selection dialog which only accepts valid dirs
|
||||||
|
QString selectedDir = FileDialog::getExistingDirectory(
|
||||||
|
this, tr("Select Data Files Directory"),
|
||||||
|
QDir::currentPath(),
|
||||||
|
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||||
|
|
||||||
|
// Add the user selected data directory
|
||||||
|
if (!selectedDir.isEmpty()) {
|
||||||
|
mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString()));
|
||||||
|
mCfgMgr.processPaths(mDataDirs);
|
||||||
|
} else {
|
||||||
|
// Cancel from within the dir selection dialog
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Cancel
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the plugins in the data directories
|
||||||
|
Files::Collections dataCollections(mDataDirs, !variables["fs-strict"].as<bool>());
|
||||||
|
Files::Collections dataLocalCollections(mDataLocal, !variables["fs-strict"].as<bool>());
|
||||||
|
|
||||||
|
addDataFiles(dataCollections, QString::fromStdString(variables["encoding"].as<std::string>()));
|
||||||
|
addDataFiles(dataLocalCollections, QString::fromStdString(variables["encoding"].as<std::string>()));
|
||||||
|
|
||||||
|
mDataFilesModel->sort(0);
|
||||||
|
|
||||||
readConfig();
|
readConfig();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1139,11 +1150,13 @@ void DataFilesPage::writeConfig(QString profile)
|
||||||
path = QString::fromStdString(it->string());
|
path = QString::fromStdString(it->string());
|
||||||
path.remove(QChar('\"'));
|
path.remove(QChar('\"'));
|
||||||
|
|
||||||
|
QDir dir(path);
|
||||||
|
|
||||||
// Make sure the string is quoted when it contains spaces
|
// Make sure the string is quoted when it contains spaces
|
||||||
if (path.contains(" ")) {
|
if (path.contains(" ")) {
|
||||||
gameConfig << "data=\"" << path << "\"" << endl;
|
gameConfig << "data=\"" << dir.absolutePath() << "\"" << endl;
|
||||||
} else {
|
} else {
|
||||||
gameConfig << "data=" << path << endl;
|
gameConfig << "data=" << dir.absolutePath() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,10 +1165,12 @@ void DataFilesPage::writeConfig(QString profile)
|
||||||
path = QString::fromStdString(mDataLocal.front().string());
|
path = QString::fromStdString(mDataLocal.front().string());
|
||||||
path.remove(QChar('\"'));
|
path.remove(QChar('\"'));
|
||||||
|
|
||||||
|
QDir dir(path);
|
||||||
|
|
||||||
if (path.contains(" ")) {
|
if (path.contains(" ")) {
|
||||||
gameConfig << "data-local=\"" << path << "\"" << endl;
|
gameConfig << "data-local=\"" << dir.absolutePath() << "\"" << endl;
|
||||||
} else {
|
} else {
|
||||||
gameConfig << "data-local=" << path << endl;
|
gameConfig << "data-local=" << dir.absolutePath() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ private:
|
||||||
const QStringList checkedPlugins();
|
const QStringList checkedPlugins();
|
||||||
const QStringList selectedMasters();
|
const QStringList selectedMasters();
|
||||||
|
|
||||||
|
void addDataFiles(Files::Collections &fileCollections, const QString &encoding);
|
||||||
void addPlugins(const QModelIndex &index);
|
void addPlugins(const QModelIndex &index);
|
||||||
void removePlugins(const QModelIndex &index);
|
void removePlugins(const QModelIndex &index);
|
||||||
void uncheckPlugins();
|
void uncheckPlugins();
|
||||||
|
|
|
@ -16,7 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||||
add_openmw_dir (mwrender
|
add_openmw_dir (mwrender
|
||||||
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
|
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
|
||||||
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
|
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
|
||||||
compositors characterpreview externalrendering
|
compositors characterpreview externalrendering globalmap
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwinput
|
add_openmw_dir (mwinput
|
||||||
|
@ -29,7 +29,7 @@ add_openmw_dir (mwgui
|
||||||
map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
|
map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
|
||||||
formatting inventorywindow container hud countdialog tradewindow settingswindow
|
formatting inventorywindow container hud countdialog tradewindow settingswindow
|
||||||
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
|
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
|
||||||
itemselection spellbuyingwindow loadingscreen
|
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwdialogue
|
add_openmw_dir (mwdialogue
|
||||||
|
|
|
@ -299,6 +299,7 @@ void OMW::Engine::go()
|
||||||
mOgre->configure(
|
mOgre->configure(
|
||||||
mCfgMgr.getLogPath().string(),
|
mCfgMgr.getLogPath().string(),
|
||||||
renderSystem,
|
renderSystem,
|
||||||
|
Settings::Manager::getString("opengl rtt mode", "Video"),
|
||||||
false);
|
false);
|
||||||
|
|
||||||
// This has to be added BEFORE MyGUI is initialized, as it needs
|
// This has to be added BEFORE MyGUI is initialized, as it needs
|
||||||
|
@ -306,6 +307,8 @@ void OMW::Engine::go()
|
||||||
|
|
||||||
//addResourcesDirectory(mResDir);
|
//addResourcesDirectory(mResDir);
|
||||||
|
|
||||||
|
addResourcesDirectory(mCfgMgr.getCachePath ().string());
|
||||||
|
|
||||||
addResourcesDirectory(mResDir / "mygui");
|
addResourcesDirectory(mResDir / "mygui");
|
||||||
addResourcesDirectory(mResDir / "water");
|
addResourcesDirectory(mResDir / "water");
|
||||||
addResourcesDirectory(mResDir / "gbuffer");
|
addResourcesDirectory(mResDir / "gbuffer");
|
||||||
|
@ -366,6 +369,7 @@ void OMW::Engine::go()
|
||||||
pos.pos[2] = 0;
|
pos.pos[2] = 0;
|
||||||
|
|
||||||
mEnvironment.getWorld()->renderPlayer();
|
mEnvironment.getWorld()->renderPlayer();
|
||||||
|
mEnvironment.getWorld()->renderGlobalMap();
|
||||||
|
|
||||||
if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName))
|
if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName))
|
||||||
{
|
{
|
||||||
|
|
|
@ -118,7 +118,7 @@ namespace MWBase
|
||||||
/// Set value for the given ID.
|
/// Set value for the given ID.
|
||||||
virtual void setValue (const std::string& id, const MWMechanics::Stat<int>& value) = 0;
|
virtual void setValue (const std::string& id, const MWMechanics::Stat<int>& value) = 0;
|
||||||
virtual void setValue (int parSkill, const MWMechanics::Stat<float>& value) = 0;
|
virtual void setValue (int parSkill, const MWMechanics::Stat<float>& value) = 0;
|
||||||
virtual void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value) = 0;
|
virtual void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value) = 0;
|
||||||
virtual void setValue (const std::string& id, const std::string& value) = 0;
|
virtual void setValue (const std::string& id, const std::string& value) = 0;
|
||||||
virtual void setValue (const std::string& id, int value) = 0;
|
virtual void setValue (const std::string& id, int value) = 0;
|
||||||
|
|
||||||
|
@ -189,6 +189,8 @@ namespace MWBase
|
||||||
virtual void allowMouse() = 0;
|
virtual void allowMouse() = 0;
|
||||||
virtual void notifyInputActionBound() = 0;
|
virtual void notifyInputActionBound() = 0;
|
||||||
|
|
||||||
|
virtual void addVisitedLocation(const std::string& name, int x, int y) = 0;
|
||||||
|
|
||||||
virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0;
|
virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0;
|
||||||
///< Hides dialog and schedules dialog to be deleted.
|
///< Hides dialog and schedules dialog to be deleted.
|
||||||
|
|
||||||
|
@ -219,6 +221,11 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total) = 0;
|
virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total) = 0;
|
||||||
virtual void loadingDone() = 0;
|
virtual void loadingDone() = 0;
|
||||||
|
|
||||||
|
virtual void enableRest() = 0;
|
||||||
|
virtual bool getRestEnabled() = 0;
|
||||||
|
|
||||||
|
virtual bool getPlayerSleeping() = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,9 @@ namespace MWBase
|
||||||
virtual void setDay (int day) = 0;
|
virtual void setDay (int day) = 0;
|
||||||
///< Set in-game time day.
|
///< Set in-game time day.
|
||||||
|
|
||||||
|
virtual int getDay() = 0;
|
||||||
|
virtual int getMonth() = 0;
|
||||||
|
|
||||||
virtual MWWorld::TimeStamp getTimeStamp() const = 0;
|
virtual MWWorld::TimeStamp getTimeStamp() const = 0;
|
||||||
///< Return current in-game time stamp.
|
///< Return current in-game time stamp.
|
||||||
|
|
||||||
|
@ -204,6 +207,9 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z, bool adjust = false) = 0;
|
virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z, bool adjust = false) = 0;
|
||||||
|
|
||||||
|
virtual void safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos) = 0;
|
||||||
|
///< place an object in a "safe" location (ie not in the void, etc).
|
||||||
|
|
||||||
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
|
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
|
||||||
const = 0;
|
const = 0;
|
||||||
///< Convert cell numbers to position.
|
///< Convert cell numbers to position.
|
||||||
|
@ -218,7 +224,7 @@ namespace MWBase
|
||||||
virtual bool toggleCollisionMode() = 0;
|
virtual bool toggleCollisionMode() = 0;
|
||||||
///< Toggle collision mode for player. If disabled player object should ignore
|
///< Toggle collision mode for player. If disabled player object should ignore
|
||||||
/// collisions and gravity.
|
/// collisions and gravity.
|
||||||
///< \return Resulting mode
|
/// \return Resulting mode
|
||||||
|
|
||||||
virtual bool toggleRenderMode (RenderMode mode) = 0;
|
virtual bool toggleRenderMode (RenderMode mode) = 0;
|
||||||
///< Toggle a render mode.
|
///< Toggle a render mode.
|
||||||
|
@ -276,8 +282,16 @@ namespace MWBase
|
||||||
virtual void togglePlayerLooking(bool enable) = 0;
|
virtual void togglePlayerLooking(bool enable) = 0;
|
||||||
|
|
||||||
virtual void renderPlayer() = 0;
|
virtual void renderPlayer() = 0;
|
||||||
|
virtual void renderGlobalMap() = 0;
|
||||||
|
|
||||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
||||||
|
|
||||||
|
virtual int canRest() = 0;
|
||||||
|
///< check if the player is allowed to rest \n
|
||||||
|
/// 0 - yes \n
|
||||||
|
/// 1 - only waiting \n
|
||||||
|
/// 2 - player is underwater \n
|
||||||
|
/// 3 - enemies are nearby (not implemented)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,7 @@ namespace MWClass
|
||||||
assert(ref->base != NULL);
|
assert(ref->base != NULL);
|
||||||
|
|
||||||
std::string headID = ref->base->mHead;
|
std::string headID = ref->base->mHead;
|
||||||
|
|
||||||
int end = headID.find_last_of("head_") - 4;
|
int end = headID.find_last_of("head_") - 4;
|
||||||
std::string bodyRaceID = headID.substr(0, end);
|
std::string bodyRaceID = headID.substr(0, end);
|
||||||
|
|
||||||
|
@ -153,6 +154,7 @@ namespace MWClass
|
||||||
model = "meshes\\base_animkna.nif";
|
model = "meshes\\base_animkna.nif";
|
||||||
}
|
}
|
||||||
return model;
|
return model;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Npc::getName (const MWWorld::Ptr& ptr) const
|
std::string Npc::getName (const MWWorld::Ptr& ptr) const
|
||||||
|
@ -297,7 +299,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
Ogre::Vector3 vector (0, 0, 0);
|
Ogre::Vector3 vector (0, 0, 0);
|
||||||
|
|
||||||
vector.x = - getMovementSettings (ptr).mLeftRight * 127;
|
vector.x = getMovementSettings (ptr).mLeftRight * 127;
|
||||||
vector.y = getMovementSettings (ptr).mForwardBackward * 127;
|
vector.y = getMovementSettings (ptr).mForwardBackward * 127;
|
||||||
vector.z = getMovementSettings(ptr).mUpDown * 127;
|
vector.z = getMovementSettings(ptr).mUpDown * 127;
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ void CharacterCreation::setValue (const std::string& id, const MWMechanics::Stat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
|
void CharacterCreation::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
if (mReviewDialog)
|
if (mReviewDialog)
|
||||||
{
|
{
|
||||||
|
@ -294,17 +294,17 @@ void CharacterCreation::spawnDialog(const char id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat<int>& value)
|
void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
mPlayerHealth = value;
|
mPlayerHealth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::setPlayerMagicka (const MWMechanics::DynamicStat<int>& value)
|
void CharacterCreation::setPlayerMagicka (const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
mPlayerMagicka = value;
|
mPlayerMagicka = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::setPlayerFatigue (const MWMechanics::DynamicStat<int>& value)
|
void CharacterCreation::setPlayerFatigue (const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
mPlayerFatigue = value;
|
mPlayerFatigue = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,14 +35,14 @@ namespace MWGui
|
||||||
//Show a dialog
|
//Show a dialog
|
||||||
void spawnDialog(const char id);
|
void spawnDialog(const char id);
|
||||||
|
|
||||||
void setPlayerHealth (const MWMechanics::DynamicStat<int>& value);
|
void setPlayerHealth (const MWMechanics::DynamicStat<float>& value);
|
||||||
|
|
||||||
void setPlayerMagicka (const MWMechanics::DynamicStat<int>& value);
|
void setPlayerMagicka (const MWMechanics::DynamicStat<float>& value);
|
||||||
|
|
||||||
void setPlayerFatigue (const MWMechanics::DynamicStat<int>& value);
|
void setPlayerFatigue (const MWMechanics::DynamicStat<float>& value);
|
||||||
|
|
||||||
void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
|
void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
|
||||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
||||||
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
||||||
void configureSkills (const SkillList& major, const SkillList& minor);
|
void configureSkills (const SkillList& major, const SkillList& minor);
|
||||||
|
|
||||||
|
@ -65,9 +65,9 @@ namespace MWGui
|
||||||
std::string mPlayerRaceId;
|
std::string mPlayerRaceId;
|
||||||
std::string mPlayerBirthSignId;
|
std::string mPlayerBirthSignId;
|
||||||
ESM::Class mPlayerClass;
|
ESM::Class mPlayerClass;
|
||||||
MWMechanics::DynamicStat<int> mPlayerHealth;
|
MWMechanics::DynamicStat<float> mPlayerHealth;
|
||||||
MWMechanics::DynamicStat<int> mPlayerMagicka;
|
MWMechanics::DynamicStat<float> mPlayerMagicka;
|
||||||
MWMechanics::DynamicStat<int> mPlayerFatigue;
|
MWMechanics::DynamicStat<float> mPlayerFatigue;
|
||||||
|
|
||||||
//Class generation vars
|
//Class generation vars
|
||||||
unsigned mGenerateClassStep; // Keeps track of current step in Generate Class dialog
|
unsigned mGenerateClassStep; // Keeps track of current step in Generate Class dialog
|
||||||
|
|
|
@ -161,7 +161,7 @@ void HUD::setEffect(const char *img)
|
||||||
mEffect1->setImageTexture(img);
|
mEffect1->setImageTexture(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& value)
|
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
static const char *ids[] =
|
static const char *ids[] =
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace MWGui
|
||||||
public:
|
public:
|
||||||
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
|
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
|
||||||
void setEffect(const char *img);
|
void setEffect(const char *img);
|
||||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
||||||
void setFPS(float fps);
|
void setFPS(float fps);
|
||||||
void setTriangleCount(unsigned int count);
|
void setTriangleCount(unsigned int count);
|
||||||
void setBatchCount(unsigned int count);
|
void setBatchCount(unsigned int count);
|
||||||
|
|
197
apps/openmw/mwgui/levelupdialog.cpp
Normal file
197
apps/openmw/mwgui/levelupdialog.cpp
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
#include "levelupdialog.hpp"
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/player.hpp"
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
#include "../mwmechanics/stat.hpp"
|
||||||
|
|
||||||
|
#include <components/esm_store/reclists.hpp>
|
||||||
|
#include <components/esm_store/store.hpp>
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
|
||||||
|
LevelupDialog::LevelupDialog(MWBase::WindowManager &parWindowManager)
|
||||||
|
: WindowBase("openmw_levelup_dialog.layout", parWindowManager)
|
||||||
|
{
|
||||||
|
getWidget(mOkButton, "OkButton");
|
||||||
|
getWidget(mClassImage, "ClassImage");
|
||||||
|
getWidget(mLevelText, "LevelText");
|
||||||
|
|
||||||
|
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &LevelupDialog::onOkButtonClicked);
|
||||||
|
|
||||||
|
for (int i=1; i<9; ++i)
|
||||||
|
{
|
||||||
|
MyGUI::TextBox* t;
|
||||||
|
getWidget(t, "AttribVal" + boost::lexical_cast<std::string>(i));
|
||||||
|
|
||||||
|
MyGUI::Button* b;
|
||||||
|
getWidget(b, "Attrib" + boost::lexical_cast<std::string>(i));
|
||||||
|
b->setUserData (i-1);
|
||||||
|
b->eventMouseButtonClick += MyGUI::newDelegate(this, &LevelupDialog::onAttributeClicked);
|
||||||
|
mAttributes.push_back(b);
|
||||||
|
|
||||||
|
mAttributeValues.push_back(t);
|
||||||
|
|
||||||
|
getWidget(t, "AttribMultiplier" + boost::lexical_cast<std::string>(i));
|
||||||
|
|
||||||
|
mAttributeMultipliers.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
int curX = mMainWidget->getWidth()/2 - (16 + 2) * 1.5;
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
MyGUI::ImageBox* image = mMainWidget->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(curX,250,16,16), MyGUI::Align::Default);
|
||||||
|
image->setImageTexture ("icons\\tx_goldicon.dds");
|
||||||
|
curX += 24+2;
|
||||||
|
mCoins.push_back(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
center();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelupDialog::setAttributeValues()
|
||||||
|
{
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
|
||||||
|
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
|
||||||
|
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
|
||||||
|
for (int i=0; i<8; ++i)
|
||||||
|
{
|
||||||
|
int val = creatureStats.getAttribute (i).getBase ();
|
||||||
|
if (std::find(mSpentAttributes.begin(), mSpentAttributes.end(), i) != mSpentAttributes.end())
|
||||||
|
{
|
||||||
|
val += pcStats.getLevelupAttributeMultiplier (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val >= 100)
|
||||||
|
val = 100;
|
||||||
|
|
||||||
|
mAttributeValues[i]->setCaption(boost::lexical_cast<std::string>(val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LevelupDialog::resetCoins ()
|
||||||
|
{
|
||||||
|
int curX = mMainWidget->getWidth()/2 - (16 + 2) * 1.5;
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
MyGUI::ImageBox* image = mCoins[i];
|
||||||
|
image->setCoord(MyGUI::IntCoord(curX,250,16,16));
|
||||||
|
curX += 24+2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelupDialog::assignCoins ()
|
||||||
|
{
|
||||||
|
resetCoins();
|
||||||
|
for (unsigned int i=0; i<mSpentAttributes.size(); ++i)
|
||||||
|
{
|
||||||
|
MyGUI::ImageBox* image = mCoins[i];
|
||||||
|
int attribute = mSpentAttributes[i];
|
||||||
|
|
||||||
|
int xdiff = mAttributeMultipliers[attribute]->getCaption() == "" ? 0 : 30;
|
||||||
|
|
||||||
|
MyGUI::IntPoint pos = mAttributes[attribute]->getAbsolutePosition() - mMainWidget->getAbsolutePosition() - MyGUI::IntPoint(24+xdiff,-4);
|
||||||
|
image->setPosition(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
setAttributeValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelupDialog::open()
|
||||||
|
{
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
|
||||||
|
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
|
||||||
|
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
|
||||||
|
center();
|
||||||
|
|
||||||
|
mSpentAttributes.clear();
|
||||||
|
resetCoins();
|
||||||
|
|
||||||
|
setAttributeValues();
|
||||||
|
|
||||||
|
// set class image
|
||||||
|
const ESM::Class& playerClass = MWBase::Environment::get().getWorld ()->getPlayer ().getClass ();
|
||||||
|
// retrieve the ID to this class
|
||||||
|
std::string classId;
|
||||||
|
std::map<std::string, ESM::Class> list = MWBase::Environment::get().getWorld()->getStore ().classes.list;
|
||||||
|
for (std::map<std::string, ESM::Class>::iterator it = list.begin(); it != list.end(); ++it)
|
||||||
|
{
|
||||||
|
if (playerClass.mName == it->second.mName)
|
||||||
|
classId = it->first;
|
||||||
|
}
|
||||||
|
mClassImage->setImageTexture ("textures\\levelup\\" + classId + ".dds");
|
||||||
|
|
||||||
|
/// \todo replace this with INI-imported texts
|
||||||
|
int level = creatureStats.getLevel ()+1;
|
||||||
|
mLevelText->setCaptionWithReplacing("#{sLevelUpMenu1} " + boost::lexical_cast<std::string>(level));
|
||||||
|
|
||||||
|
for (int i=0; i<8; ++i)
|
||||||
|
{
|
||||||
|
MyGUI::TextBox* text = mAttributeMultipliers[i];
|
||||||
|
int mult = pcStats.getLevelupAttributeMultiplier (i);
|
||||||
|
text->setCaption(mult <= 1 ? "" : "x" + boost::lexical_cast<std::string>(mult));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelupDialog::onOkButtonClicked (MyGUI::Widget* sender)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
|
||||||
|
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
|
||||||
|
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
|
||||||
|
if (mSpentAttributes.size() < 3)
|
||||||
|
MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage36}", std::vector<std::string>());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// increase attributes
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
MWMechanics::Stat<int>& attribute = creatureStats.getAttribute(mSpentAttributes[i]);
|
||||||
|
attribute.setBase (attribute.getBase () + pcStats.getLevelupAttributeMultiplier (mSpentAttributes[i]));
|
||||||
|
|
||||||
|
if (attribute.getBase() >= 100)
|
||||||
|
attribute.setBase(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "When you gain a level, in addition to increasing three primary attributes, your Health
|
||||||
|
// will automatically increase by 10% of your Endurance attribute. If you increased Endurance this level,
|
||||||
|
// the Health increase is calculated from the increased Endurance"
|
||||||
|
creatureStats.increaseLevelHealthBonus (creatureStats.getAttribute(ESM::Attribute::Endurance).getBase() * 0.1f);
|
||||||
|
|
||||||
|
creatureStats.setLevel (creatureStats.getLevel()+1);
|
||||||
|
pcStats.levelUp ();
|
||||||
|
|
||||||
|
mWindowManager.removeGuiMode (GM_Levelup);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelupDialog::onAttributeClicked (MyGUI::Widget *sender)
|
||||||
|
{
|
||||||
|
int attribute = *sender->getUserData<int>();
|
||||||
|
|
||||||
|
std::vector<int>::iterator found = std::find(mSpentAttributes.begin(), mSpentAttributes.end(), attribute);
|
||||||
|
if (found != mSpentAttributes.end())
|
||||||
|
mSpentAttributes.erase (found);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mSpentAttributes.size() == 3)
|
||||||
|
mSpentAttributes[2] = attribute;
|
||||||
|
else
|
||||||
|
mSpentAttributes.push_back(attribute);
|
||||||
|
}
|
||||||
|
assignCoins();
|
||||||
|
}
|
||||||
|
}
|
39
apps/openmw/mwgui/levelupdialog.hpp
Normal file
39
apps/openmw/mwgui/levelupdialog.hpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef MWGUI_LEVELUPDIALOG_H
|
||||||
|
#define MWGUI_LEVELUPDIALOG_H
|
||||||
|
|
||||||
|
#include "window_base.hpp"
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
|
||||||
|
class LevelupDialog : public WindowBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LevelupDialog(MWBase::WindowManager& parWindowManager);
|
||||||
|
|
||||||
|
virtual void open();
|
||||||
|
|
||||||
|
private:
|
||||||
|
MyGUI::Button* mOkButton;
|
||||||
|
MyGUI::ImageBox* mClassImage;
|
||||||
|
MyGUI::TextBox* mLevelText;
|
||||||
|
|
||||||
|
std::vector<MyGUI::Button*> mAttributes;
|
||||||
|
std::vector<MyGUI::TextBox*> mAttributeValues;
|
||||||
|
std::vector<MyGUI::TextBox*> mAttributeMultipliers;
|
||||||
|
std::vector<MyGUI::ImageBox*> mCoins;
|
||||||
|
|
||||||
|
std::vector<int> mSpentAttributes;
|
||||||
|
|
||||||
|
void onOkButtonClicked (MyGUI::Widget* sender);
|
||||||
|
void onAttributeClicked (MyGUI::Widget* sender);
|
||||||
|
|
||||||
|
void assignCoins();
|
||||||
|
void resetCoins();
|
||||||
|
|
||||||
|
void setAttributeValues();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,10 +3,13 @@
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#include <OgreVector2.h>
|
#include <OgreVector2.h>
|
||||||
|
#include <OgreTextureManager.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwworld/player.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
using namespace MWGui;
|
||||||
|
|
||||||
|
@ -254,18 +257,24 @@ MapWindow::MapWindow(MWBase::WindowManager& parWindowManager) :
|
||||||
|
|
||||||
getWidget(mLocalMap, "LocalMap");
|
getWidget(mLocalMap, "LocalMap");
|
||||||
getWidget(mGlobalMap, "GlobalMap");
|
getWidget(mGlobalMap, "GlobalMap");
|
||||||
getWidget(mPlayerArrow, "Compass");
|
getWidget(mGlobalMapImage, "GlobalMapImage");
|
||||||
|
getWidget(mPlayerArrowLocal, "CompassLocal");
|
||||||
|
getWidget(mPlayerArrowGlobal, "CompassGlobal");
|
||||||
|
|
||||||
|
mGlobalMap->setVisible (false);
|
||||||
|
|
||||||
getWidget(mButton, "WorldButton");
|
getWidget(mButton, "WorldButton");
|
||||||
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
||||||
mButton->setCaptionWithReplacing("#{sWorld}");
|
mButton->setCaptionWithReplacing("#{sWorld}");
|
||||||
|
|
||||||
MyGUI::Button* eventbox;
|
getWidget(mEventBoxGlobal, "EventBoxGlobal");
|
||||||
getWidget(eventbox, "EventBox");
|
mEventBoxGlobal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||||
eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
mEventBoxGlobal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||||
eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
getWidget(mEventBoxLocal, "EventBoxLocal");
|
||||||
|
mEventBoxLocal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||||
|
mEventBoxLocal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||||
|
|
||||||
LocalMapBase::init(mLocalMap, mPlayerArrow, this);
|
LocalMapBase::init(mLocalMap, mPlayerArrowLocal, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWindow::setCellName(const std::string& cellName)
|
void MapWindow::setCellName(const std::string& cellName)
|
||||||
|
@ -273,10 +282,38 @@ void MapWindow::setCellName(const std::string& cellName)
|
||||||
setTitle(cellName);
|
setTitle(cellName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
|
||||||
|
{
|
||||||
|
const int cellSize = 24;
|
||||||
|
|
||||||
|
int size = 24 * 61;
|
||||||
|
|
||||||
|
MyGUI::IntCoord widgetCoord(
|
||||||
|
(x+30)*cellSize+6,
|
||||||
|
(size-1) - (y+30)*cellSize+6,
|
||||||
|
12, 12);
|
||||||
|
|
||||||
|
|
||||||
|
static int _counter=0;
|
||||||
|
MyGUI::Button* markerWidget = mGlobalMapImage->createWidget<MyGUI::Button>("ButtonImage",
|
||||||
|
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(_counter));
|
||||||
|
markerWidget->setImageResource("DoorMarker");
|
||||||
|
markerWidget->setUserString("ToolTipType", "Layout");
|
||||||
|
markerWidget->setUserString("ToolTipLayout", "TextToolTip");
|
||||||
|
markerWidget->setUserString("Caption_Text", name);
|
||||||
|
++_counter;
|
||||||
|
|
||||||
|
markerWidget = mEventBoxGlobal->createWidget<MyGUI::Button>("",
|
||||||
|
widgetCoord, MyGUI::Align::Default);
|
||||||
|
markerWidget->setNeedMouseFocus (true);
|
||||||
|
markerWidget->setUserString("ToolTipType", "Layout");
|
||||||
|
markerWidget->setUserString("ToolTipLayout", "TextToolTip");
|
||||||
|
markerWidget->setUserString("Caption_Text", name);
|
||||||
|
}
|
||||||
|
|
||||||
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
||||||
{
|
{
|
||||||
if (_id!=MyGUI::MouseButton::Left) return;
|
if (_id!=MyGUI::MouseButton::Left) return;
|
||||||
if (!mGlobal)
|
|
||||||
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,14 +321,16 @@ void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::
|
||||||
{
|
{
|
||||||
if (_id!=MyGUI::MouseButton::Left) return;
|
if (_id!=MyGUI::MouseButton::Left) return;
|
||||||
|
|
||||||
if (!mGlobal)
|
|
||||||
{
|
|
||||||
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
|
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
|
||||||
|
|
||||||
|
if (!mGlobal)
|
||||||
mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff );
|
mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff );
|
||||||
|
else
|
||||||
|
mGlobalMap->setViewOffset( mGlobalMap->getViewOffset() + diff );
|
||||||
|
|
||||||
|
|
||||||
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
|
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
|
@ -307,3 +346,41 @@ void MapWindow::onPinToggled()
|
||||||
{
|
{
|
||||||
mWindowManager.setMinimapVisibility(!mPinned);
|
mWindowManager.setMinimapVisibility(!mPinned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapWindow::open()
|
||||||
|
{
|
||||||
|
mGlobalMapImage->setImageTexture("GlobalMap.png");
|
||||||
|
|
||||||
|
int size = 24 * 61;
|
||||||
|
|
||||||
|
mGlobalMap->setCanvasSize (size, size);
|
||||||
|
mGlobalMapImage->setSize(size, size);
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<mGlobalMapImage->getChildCount (); ++i)
|
||||||
|
{
|
||||||
|
if (mGlobalMapImage->getChildAt (i)->getName().substr(0,6) == "Marker")
|
||||||
|
mGlobalMapImage->getChildAt (i)->castType<MyGUI::Button>()->setImageResource("DoorMarker");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
|
||||||
|
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
|
||||||
|
Ogre::Vector2 dir (orient.yAxis ().x, -orient.yAxis().z);
|
||||||
|
|
||||||
|
float worldX = ((pos.x / 8192.f-0.5) / 30.f+1)/2.f;
|
||||||
|
float worldY = ((pos.z / 8192.f+1.5) / 30.f+1)/2.f;
|
||||||
|
|
||||||
|
// for interiors, we have no choice other than using the last position & direction.
|
||||||
|
/// \todo save this last position in the savegame?
|
||||||
|
if (MWBase::Environment::get().getWorld ()->isCellExterior ())
|
||||||
|
{
|
||||||
|
mPlayerArrowGlobal->setPosition(MyGUI::IntPoint(size * worldX - 16, size * worldY - 16));
|
||||||
|
|
||||||
|
MyGUI::ISubWidget* main = mPlayerArrowGlobal->getSubWidgetMain();
|
||||||
|
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
||||||
|
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
||||||
|
float angle = std::atan2(dir.x, dir.y);
|
||||||
|
rotatingSubskin->setAngle(angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
mPlayerArrowGlobal->setImageTexture ("textures\\compass.dds");
|
||||||
|
}
|
||||||
|
|
|
@ -62,17 +62,26 @@ namespace MWGui
|
||||||
|
|
||||||
void setCellName(const std::string& cellName);
|
void setCellName(const std::string& cellName);
|
||||||
|
|
||||||
|
void addVisitedLocation(const std::string& name, int x, int y); // adds the marker to the global map
|
||||||
|
|
||||||
|
virtual void open();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
||||||
void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
||||||
void onWorldButtonClicked(MyGUI::Widget* _sender);
|
void onWorldButtonClicked(MyGUI::Widget* _sender);
|
||||||
|
|
||||||
MyGUI::ScrollView* mGlobalMap;
|
MyGUI::ScrollView* mGlobalMap;
|
||||||
MyGUI::ImageBox* mPlayerArrow;
|
MyGUI::ImageBox* mGlobalMapImage;
|
||||||
|
MyGUI::ImageBox* mPlayerArrowLocal;
|
||||||
|
MyGUI::ImageBox* mPlayerArrowGlobal;
|
||||||
MyGUI::Button* mButton;
|
MyGUI::Button* mButton;
|
||||||
MyGUI::IntPoint mLastDragPos;
|
MyGUI::IntPoint mLastDragPos;
|
||||||
bool mGlobal;
|
bool mGlobal;
|
||||||
|
|
||||||
|
MyGUI::Button* mEventBoxGlobal;
|
||||||
|
MyGUI::Button* mEventBoxLocal;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void onPinToggled();
|
virtual void onPinToggled();
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,8 +20,11 @@ namespace MWGui
|
||||||
GM_Dialogue, // NPC interaction
|
GM_Dialogue, // NPC interaction
|
||||||
GM_Barter,
|
GM_Barter,
|
||||||
GM_Rest,
|
GM_Rest,
|
||||||
|
GM_RestBed,
|
||||||
GM_SpellBuying,
|
GM_SpellBuying,
|
||||||
|
|
||||||
|
GM_Levelup,
|
||||||
|
|
||||||
// Startup character creation dialogs
|
// Startup character creation dialogs
|
||||||
GM_Name,
|
GM_Name,
|
||||||
GM_Race,
|
GM_Race,
|
||||||
|
|
|
@ -40,7 +40,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
|
||||||
|
|
||||||
getWidget(mHeadRotate, "HeadRotate");
|
getWidget(mHeadRotate, "HeadRotate");
|
||||||
mHeadRotate->setScrollRange(50);
|
mHeadRotate->setScrollRange(50);
|
||||||
mHeadRotate->setScrollPosition(20);
|
mHeadRotate->setScrollPosition(25);
|
||||||
mHeadRotate->setScrollViewPage(10);
|
mHeadRotate->setScrollViewPage(10);
|
||||||
mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate);
|
mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate);
|
||||||
|
|
||||||
|
|
|
@ -134,21 +134,21 @@ void ReviewDialog::setBirthSign(const std::string& signId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<int>& value)
|
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
mHealth->setValue(value.getCurrent(), value.getModified());
|
mHealth->setValue(value.getCurrent(), value.getModified());
|
||||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||||
mHealth->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
mHealth->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<int>& value)
|
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
mMagicka->setValue(value.getCurrent(), value.getModified());
|
mMagicka->setValue(value.getCurrent(), value.getModified());
|
||||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||||
mMagicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
mMagicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<int>& value)
|
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
mFatigue->setValue(value.getCurrent(), value.getModified());
|
mFatigue->setValue(value.getCurrent(), value.getModified());
|
||||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||||
|
|
|
@ -35,9 +35,9 @@ namespace MWGui
|
||||||
void setClass(const ESM::Class& class_);
|
void setClass(const ESM::Class& class_);
|
||||||
void setBirthSign (const std::string &signId);
|
void setBirthSign (const std::string &signId);
|
||||||
|
|
||||||
void setHealth(const MWMechanics::DynamicStat<int>& value);
|
void setHealth(const MWMechanics::DynamicStat<float>& value);
|
||||||
void setMagicka(const MWMechanics::DynamicStat<int>& value);
|
void setMagicka(const MWMechanics::DynamicStat<float>& value);
|
||||||
void setFatigue(const MWMechanics::DynamicStat<int>& value);
|
void setFatigue(const MWMechanics::DynamicStat<float>& value);
|
||||||
|
|
||||||
void setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value);
|
void setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value);
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,7 @@ namespace MWGui
|
||||||
getWidget(mInvertYButton, "InvertYButton");
|
getWidget(mInvertYButton, "InvertYButton");
|
||||||
getWidget(mUISensitivitySlider, "UISensitivitySlider");
|
getWidget(mUISensitivitySlider, "UISensitivitySlider");
|
||||||
getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider");
|
getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider");
|
||||||
|
getWidget(mGammaSlider, "GammaSlider");
|
||||||
|
|
||||||
mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
@ -143,6 +144,7 @@ namespace MWGui
|
||||||
mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||||
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
|
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
|
||||||
mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||||
|
mGammaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||||
|
|
||||||
mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
@ -200,6 +202,14 @@ namespace MWGui
|
||||||
getWidget(fovText, "FovText");
|
getWidget(fovText, "FovText");
|
||||||
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getFloat("field of view", "General"))) + ")");
|
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getFloat("field of view", "General"))) + ")");
|
||||||
|
|
||||||
|
float gammaVal = (Settings::Manager::getFloat("gamma", "Video")-0.1f)/(3.f-0.1f);
|
||||||
|
mGammaSlider->setScrollPosition(gammaVal * (mGammaSlider->getScrollRange()-1));
|
||||||
|
MyGUI::TextBox* gammaText;
|
||||||
|
getWidget(gammaText, "GammaText");
|
||||||
|
std::stringstream gamma;
|
||||||
|
gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video");
|
||||||
|
gammaText->setCaption("Gamma (" + gamma.str() + ")");
|
||||||
|
|
||||||
float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0;
|
float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0;
|
||||||
mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1));
|
mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1));
|
||||||
std::string tf = Settings::Manager::getString("texture filtering", "General");
|
std::string tf = Settings::Manager::getString("texture filtering", "General");
|
||||||
|
@ -511,6 +521,15 @@ namespace MWGui
|
||||||
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int((1-val) * sFovMin + val * sFovMax)) + ")");
|
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int((1-val) * sFovMin + val * sFovMax)) + ")");
|
||||||
Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax);
|
Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax);
|
||||||
}
|
}
|
||||||
|
else if (scroller == mGammaSlider)
|
||||||
|
{
|
||||||
|
Settings::Manager::setFloat("gamma", "Video", (1-val) * 0.1f + val * 3.f);
|
||||||
|
MyGUI::TextBox* gammaText;
|
||||||
|
getWidget(gammaText, "GammaText");
|
||||||
|
std::stringstream gamma;
|
||||||
|
gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video");
|
||||||
|
gammaText->setCaption("Gamma (" + gamma.str() + ")");
|
||||||
|
}
|
||||||
else if (scroller == mAnisotropySlider)
|
else if (scroller == mAnisotropySlider)
|
||||||
{
|
{
|
||||||
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")");
|
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")");
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace MWGui
|
||||||
MyGUI::Button* mFPSButton;
|
MyGUI::Button* mFPSButton;
|
||||||
MyGUI::ScrollBar* mViewDistanceSlider;
|
MyGUI::ScrollBar* mViewDistanceSlider;
|
||||||
MyGUI::ScrollBar* mFOVSlider;
|
MyGUI::ScrollBar* mFOVSlider;
|
||||||
|
MyGUI::ScrollBar* mGammaSlider;
|
||||||
MyGUI::ScrollBar* mAnisotropySlider;
|
MyGUI::ScrollBar* mAnisotropySlider;
|
||||||
MyGUI::Button* mTextureFilteringButton;
|
MyGUI::Button* mTextureFilteringButton;
|
||||||
MyGUI::TextBox* mAnisotropyLabel;
|
MyGUI::TextBox* mAnisotropyLabel;
|
||||||
|
|
|
@ -137,7 +137,7 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
|
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
static const char *ids[] =
|
static const char *ids[] =
|
||||||
{
|
{
|
||||||
|
@ -150,7 +150,7 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicSta
|
||||||
if (ids[i]==id)
|
if (ids[i]==id)
|
||||||
{
|
{
|
||||||
std::string id (ids[i]);
|
std::string id (ids[i]);
|
||||||
setBar (id, id + "T", value.getCurrent(), value.getModified());
|
setBar (id, id + "T", static_cast<int>(value.getCurrent()), static_cast<int>(value.getModified()));
|
||||||
|
|
||||||
// health, magicka, fatigue tooltip
|
// health, magicka, fatigue tooltip
|
||||||
MyGUI::Widget* w;
|
MyGUI::Widget* w;
|
||||||
|
@ -236,12 +236,21 @@ void StatsWindow::configureSkills (const std::vector<int>& major, const std::vec
|
||||||
|
|
||||||
void StatsWindow::onFrame ()
|
void StatsWindow::onFrame ()
|
||||||
{
|
{
|
||||||
if (mMainWidget->getVisible())
|
if (!mMainWidget->getVisible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||||
MWMechanics::NpcStats PCstats = MWWorld::Class::get(player).getNpcStats(player);
|
MWMechanics::NpcStats PCstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||||
|
|
||||||
|
// level progress
|
||||||
|
MyGUI::Widget* levelWidget;
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
getWidget(levelWidget, i==0 ? "Level_str" : "LevelText");
|
||||||
|
levelWidget->setUserString("RangePosition_LevelProgress", boost::lexical_cast<std::string>(PCstats.getLevelProgress()));
|
||||||
|
levelWidget->setUserString("Caption_LevelProgressText", boost::lexical_cast<std::string>(PCstats.getLevelProgress()) + "/10");
|
||||||
|
}
|
||||||
|
|
||||||
setFactions(PCstats.getFactionRanks());
|
setFactions(PCstats.getFactionRanks());
|
||||||
|
|
||||||
setBirthSign(MWBase::Environment::get().getWorld()->getPlayer().getBirthsign());
|
setBirthSign(MWBase::Environment::get().getWorld()->getPlayer().getBirthsign());
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace MWGui
|
||||||
|
|
||||||
/// Set value for the given ID.
|
/// Set value for the given ID.
|
||||||
void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
|
void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
|
||||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
||||||
void setValue (const std::string& id, const std::string& value);
|
void setValue (const std::string& id, const std::string& value);
|
||||||
void setValue (const std::string& id, int value);
|
void setValue (const std::string& id, int value);
|
||||||
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
||||||
|
|
|
@ -47,10 +47,22 @@ void TextInputDialog::open()
|
||||||
|
|
||||||
void TextInputDialog::onOkClicked(MyGUI::Widget* _sender)
|
void TextInputDialog::onOkClicked(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
|
if (mTextEdit->getCaption() == "")
|
||||||
|
{
|
||||||
|
mWindowManager.messageBox ("#{sNotifyMessage37}", std::vector<std::string>());
|
||||||
|
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
|
||||||
|
}
|
||||||
|
else
|
||||||
eventDone(this);
|
eventDone(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
|
void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
|
||||||
{
|
{
|
||||||
|
if (mTextEdit->getCaption() == "")
|
||||||
|
{
|
||||||
|
mWindowManager.messageBox ("#{sNotifyMessage37}", std::vector<std::string>());
|
||||||
|
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
|
||||||
|
}
|
||||||
|
else
|
||||||
eventDone(this);
|
eventDone(this);
|
||||||
}
|
}
|
||||||
|
|
213
apps/openmw/mwgui/waitdialog.cpp
Normal file
213
apps/openmw/mwgui/waitdialog.cpp
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
#include "waitdialog.hpp"
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include <libs/openengine/ogre/fader.hpp>
|
||||||
|
|
||||||
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/timestamp.hpp"
|
||||||
|
#include "../mwworld/player.hpp"
|
||||||
|
#include "../mwworld/ptr.hpp"
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
|
#include "widgets.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
|
||||||
|
WaitDialogProgressBar::WaitDialogProgressBar(MWBase::WindowManager &parWindowManager)
|
||||||
|
: WindowBase("openmw_wait_dialog_progressbar.layout", parWindowManager)
|
||||||
|
{
|
||||||
|
getWidget(mProgressBar, "ProgressBar");
|
||||||
|
getWidget(mProgressText, "ProgressText");
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialogProgressBar::open()
|
||||||
|
{
|
||||||
|
center();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialogProgressBar::setProgress (int cur, int total)
|
||||||
|
{
|
||||||
|
mProgressBar->setProgressRange (total);
|
||||||
|
mProgressBar->setProgressPosition (cur);
|
||||||
|
mProgressText->setCaption(boost::lexical_cast<std::string>(cur) + "/" + boost::lexical_cast<std::string>(total));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
WaitDialog::WaitDialog(MWBase::WindowManager &parWindowManager)
|
||||||
|
: WindowBase("openmw_wait_dialog.layout", parWindowManager)
|
||||||
|
, mProgressBar(parWindowManager)
|
||||||
|
, mWaiting(false)
|
||||||
|
, mSleeping(false)
|
||||||
|
, mHours(1)
|
||||||
|
, mRemainingTime(0.05)
|
||||||
|
{
|
||||||
|
getWidget(mDateTimeText, "DateTimeText");
|
||||||
|
getWidget(mRestText, "RestText");
|
||||||
|
getWidget(mHourText, "HourText");
|
||||||
|
getWidget(mHourSlider, "HourSlider");
|
||||||
|
getWidget(mUntilHealedButton, "UntilHealedButton");
|
||||||
|
getWidget(mWaitButton, "WaitButton");
|
||||||
|
getWidget(mCancelButton, "CancelButton");
|
||||||
|
|
||||||
|
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onCancelButtonClicked);
|
||||||
|
mUntilHealedButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onUntilHealedButtonClicked);
|
||||||
|
mWaitButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onWaitButtonClicked);
|
||||||
|
|
||||||
|
mHourSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &WaitDialog::onHourSliderChangedPosition);
|
||||||
|
|
||||||
|
mProgressBar.setVisible (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialog::open()
|
||||||
|
{
|
||||||
|
if (!MWBase::Environment::get().getWindowManager ()->getRestEnabled ())
|
||||||
|
{
|
||||||
|
mWindowManager.popGuiMode ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int canRest = MWBase::Environment::get().getWorld ()->canRest ();
|
||||||
|
|
||||||
|
if (canRest == 2)
|
||||||
|
{
|
||||||
|
// resting underwater or mid-air not allowed
|
||||||
|
mWindowManager.messageBox ("#{sNotifyMessage1}", std::vector<std::string>());
|
||||||
|
mWindowManager.popGuiMode ();
|
||||||
|
}
|
||||||
|
|
||||||
|
setCanRest(canRest == 0);
|
||||||
|
|
||||||
|
onHourSliderChangedPosition(mHourSlider, 0);
|
||||||
|
mHourSlider->setScrollPosition (0);
|
||||||
|
|
||||||
|
// http://www.uesp.net/wiki/Lore:Calendar
|
||||||
|
std::string month;
|
||||||
|
int m = MWBase::Environment::get().getWorld ()->getMonth ();
|
||||||
|
if (m == 0)
|
||||||
|
month = "#{sMonthMorningstar}";
|
||||||
|
else if (m == 1)
|
||||||
|
month = "#{sMonthSunsdawn}";
|
||||||
|
else if (m == 2)
|
||||||
|
month = "#{sMonthFirstseed}";
|
||||||
|
else if (m == 3)
|
||||||
|
month = "#{sMonthRainshand}";
|
||||||
|
else if (m == 4)
|
||||||
|
month = "#{sMonthSecondseed}";
|
||||||
|
else if (m == 5)
|
||||||
|
month = "#{sMonthMidyear}";
|
||||||
|
else if (m == 6)
|
||||||
|
month = "#{sMonthSunsheight}";
|
||||||
|
else if (m == 7)
|
||||||
|
month = "#{sMonthLastseed}";
|
||||||
|
else if (m == 8)
|
||||||
|
month = "#{sMonthHeartfire}";
|
||||||
|
else if (m == 9)
|
||||||
|
month = "#{sMonthFrostfall}";
|
||||||
|
else if (m == 10)
|
||||||
|
month = "#{sMonthSunsdusk}";
|
||||||
|
else if (m == 11)
|
||||||
|
month = "#{sMonthEveningstar}";
|
||||||
|
|
||||||
|
int hour = MWBase::Environment::get().getWorld ()->getTimeStamp ().getHour ();
|
||||||
|
bool pm = hour >= 12;
|
||||||
|
if (hour >= 13) hour -= 12;
|
||||||
|
|
||||||
|
std::string dateTimeText =
|
||||||
|
boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getDay ()+1) + " "
|
||||||
|
+ month + " (#{sDay} " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getTimeStamp ().getDay ()+1)
|
||||||
|
+ ") " + boost::lexical_cast<std::string>(hour) + " " + (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}");
|
||||||
|
|
||||||
|
mDateTimeText->setCaptionWithReplacing (dateTimeText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender)
|
||||||
|
{
|
||||||
|
startWaiting();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialog::onWaitButtonClicked(MyGUI::Widget* sender)
|
||||||
|
{
|
||||||
|
startWaiting();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialog::startWaiting ()
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.2);
|
||||||
|
setVisible(false);
|
||||||
|
mProgressBar.setVisible (true);
|
||||||
|
mWaiting = true;
|
||||||
|
mCurHour = 0;
|
||||||
|
mRemainingTime = 0.05;
|
||||||
|
mProgressBar.setProgress (0, mHours);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialog::onCancelButtonClicked(MyGUI::Widget* sender)
|
||||||
|
{
|
||||||
|
mWindowManager.popGuiMode ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialog::onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position)
|
||||||
|
{
|
||||||
|
mHourText->setCaptionWithReplacing (boost::lexical_cast<std::string>(position+1) + " #{sRestMenu2}");
|
||||||
|
mHours = position+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialog::setCanRest (bool canRest)
|
||||||
|
{
|
||||||
|
mUntilHealedButton->setVisible(canRest);
|
||||||
|
mWaitButton->setCaptionWithReplacing (canRest ? "#{sRest}" : "#{sWait}");
|
||||||
|
mRestText->setCaptionWithReplacing (canRest ? "#{sRestMenu3}" : "#{sRestIllegal}");
|
||||||
|
|
||||||
|
mSleeping = canRest;
|
||||||
|
|
||||||
|
dynamic_cast<Widgets::Box*>(mMainWidget)->notifyChildrenSizeChanged();
|
||||||
|
center();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialog::onFrame(float dt)
|
||||||
|
{
|
||||||
|
if (!mWaiting)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mRemainingTime -= dt;
|
||||||
|
|
||||||
|
if (mRemainingTime < 0)
|
||||||
|
{
|
||||||
|
mRemainingTime = 0.05;
|
||||||
|
++mCurHour;
|
||||||
|
mProgressBar.setProgress (mCurHour, mHours);
|
||||||
|
|
||||||
|
if (mCurHour <= mHours)
|
||||||
|
MWBase::Environment::get().getWorld ()->advanceTime (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCurHour > mHours)
|
||||||
|
stopWaiting();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitDialog::stopWaiting ()
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.2);
|
||||||
|
mProgressBar.setVisible (false);
|
||||||
|
mWindowManager.popGuiMode ();
|
||||||
|
mWaiting = false;
|
||||||
|
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||||
|
MWMechanics::NpcStats pcstats = MWWorld::Class::get(player).getNpcStats(player);
|
||||||
|
|
||||||
|
// trigger levelup if possible
|
||||||
|
if (mSleeping && pcstats.getLevelProgress () >= 10)
|
||||||
|
{
|
||||||
|
mWindowManager.pushGuiMode (GM_Levelup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
66
apps/openmw/mwgui/waitdialog.hpp
Normal file
66
apps/openmw/mwgui/waitdialog.hpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#ifndef MWGUI_WAIT_DIALOG_H
|
||||||
|
#define MWGUI_WAIT_DIALOG_H
|
||||||
|
|
||||||
|
#include "window_base.hpp"
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
|
||||||
|
class WaitDialogProgressBar : public WindowBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WaitDialogProgressBar(MWBase::WindowManager& parWindowManager);
|
||||||
|
|
||||||
|
virtual void open();
|
||||||
|
|
||||||
|
void setProgress(int cur, int total);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MyGUI::ProgressBar* mProgressBar;
|
||||||
|
MyGUI::TextBox* mProgressText;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WaitDialog : public WindowBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WaitDialog(MWBase::WindowManager& parWindowManager);
|
||||||
|
|
||||||
|
virtual void open();
|
||||||
|
|
||||||
|
void onFrame(float dt);
|
||||||
|
|
||||||
|
void bedActivated() { setCanRest(true); }
|
||||||
|
|
||||||
|
bool getSleeping() { return mWaiting && mSleeping; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MyGUI::TextBox* mDateTimeText;
|
||||||
|
MyGUI::TextBox* mRestText;
|
||||||
|
MyGUI::TextBox* mHourText;
|
||||||
|
MyGUI::ScrollBar* mHourSlider;
|
||||||
|
MyGUI::Button* mUntilHealedButton;
|
||||||
|
MyGUI::Button* mWaitButton;
|
||||||
|
MyGUI::Button* mCancelButton;
|
||||||
|
|
||||||
|
bool mWaiting;
|
||||||
|
bool mSleeping;
|
||||||
|
int mCurHour;
|
||||||
|
int mHours;
|
||||||
|
float mRemainingTime;
|
||||||
|
|
||||||
|
WaitDialogProgressBar mProgressBar;
|
||||||
|
|
||||||
|
void onUntilHealedButtonClicked(MyGUI::Widget* sender);
|
||||||
|
void onWaitButtonClicked(MyGUI::Widget* sender);
|
||||||
|
void onCancelButtonClicked(MyGUI::Widget* sender);
|
||||||
|
void onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position);
|
||||||
|
|
||||||
|
void setCanRest(bool canRest);
|
||||||
|
|
||||||
|
void startWaiting();
|
||||||
|
void stopWaiting();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -795,7 +795,6 @@ void MWDynamicStat::initialiseOverride()
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w)
|
void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w)
|
||||||
{
|
{
|
||||||
if (w->getParent () != 0)
|
if (w->getParent () != 0)
|
||||||
|
@ -869,29 +868,33 @@ void AutoSizedButton::setPropertyOverride(const std::string& _key, const std::st
|
||||||
|
|
||||||
Box::Box()
|
Box::Box()
|
||||||
: mSpacing(4)
|
: mSpacing(4)
|
||||||
|
, mPadding(0)
|
||||||
|
, mAutoResize(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Box::setPropertyOverride(const std::string& _key, const std::string& _value)
|
|
||||||
{
|
|
||||||
if (_key == "Spacing")
|
|
||||||
{
|
|
||||||
mSpacing = MyGUI::utility::parseValue<int>(_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::notifyChildrenSizeChanged ()
|
void Box::notifyChildrenSizeChanged ()
|
||||||
{
|
{
|
||||||
align();
|
align();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Box::_setPropertyImpl(const std::string& _key, const std::string& _value)
|
||||||
|
{
|
||||||
|
if (_key == "Spacing")
|
||||||
|
mSpacing = MyGUI::utility::parseValue<int>(_value);
|
||||||
|
else if (_key == "Padding")
|
||||||
|
mPadding = MyGUI::utility::parseValue<int>(_value);
|
||||||
|
else if (_key == "AutoResize")
|
||||||
|
mAutoResize = MyGUI::utility::parseValue<bool>(_value);
|
||||||
|
}
|
||||||
|
|
||||||
void HBox::align ()
|
void HBox::align ()
|
||||||
{
|
{
|
||||||
unsigned int count = getChildCount ();
|
unsigned int count = getChildCount ();
|
||||||
size_t h_stretched_count = 0;
|
size_t h_stretched_count = 0;
|
||||||
int total_width = 0;
|
int total_width = 0;
|
||||||
|
int total_height = 0;
|
||||||
std::vector< std::pair<MyGUI::IntSize, bool> > sizes;
|
std::vector< std::pair<MyGUI::IntSize, bool> > sizes;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
|
@ -904,28 +907,43 @@ void HBox::align ()
|
||||||
{
|
{
|
||||||
sizes.push_back(std::make_pair(aw->getRequestedSize (), hstretch));
|
sizes.push_back(std::make_pair(aw->getRequestedSize (), hstretch));
|
||||||
total_width += aw->getRequestedSize ().width;
|
total_width += aw->getRequestedSize ().width;
|
||||||
|
total_height = std::max(total_height, aw->getRequestedSize ().height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!hstretch) h_stretched_count ++;
|
sizes.push_back (std::make_pair(w->getSize(), hstretch));
|
||||||
sizes.push_back (std::make_pair(MyGUI::IntSize(0,0), true));
|
total_width += w->getSize().width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != count-1)
|
if (i != count-1)
|
||||||
total_width += mSpacing;
|
total_width += mSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height))
|
||||||
|
{
|
||||||
|
setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int curX = 0;
|
int curX = 0;
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
|
if (i == 0)
|
||||||
|
curX += mPadding;
|
||||||
|
|
||||||
MyGUI::Widget* w = getChildAt(i);
|
MyGUI::Widget* w = getChildAt(i);
|
||||||
|
|
||||||
|
bool vstretch = w->getUserString ("VStretch") == "true";
|
||||||
|
int height = vstretch ? total_height : sizes[i].first.height;
|
||||||
|
|
||||||
MyGUI::IntCoord widgetCoord;
|
MyGUI::IntCoord widgetCoord;
|
||||||
widgetCoord.left = curX;
|
widgetCoord.left = curX;
|
||||||
widgetCoord.top = (getSize().height - sizes[i].first.height) / 2;
|
widgetCoord.top = mPadding + (getSize().height-mPadding*2 - height) / 2;
|
||||||
int width = sizes[i].second ? sizes[i].first.width + (getSize().width - total_width)/h_stretched_count
|
int width = sizes[i].second ? sizes[i].first.width + (getSize().width-mPadding*2 - total_width)/h_stretched_count
|
||||||
: sizes[i].first.width;
|
: sizes[i].first.width;
|
||||||
widgetCoord.width = width;
|
widgetCoord.width = width;
|
||||||
widgetCoord.height = sizes[i].first.height;
|
widgetCoord.height = height;
|
||||||
w->setCoord(widgetCoord);
|
w->setCoord(widgetCoord);
|
||||||
curX += width;
|
curX += width;
|
||||||
|
|
||||||
|
@ -934,12 +952,33 @@ void HBox::align ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HBox::setPropertyOverride(const std::string& _key, const std::string& _value)
|
||||||
|
{
|
||||||
|
Box::_setPropertyImpl (_key, _value);
|
||||||
|
}
|
||||||
|
|
||||||
void HBox::setSize (const MyGUI::IntSize& _value)
|
void HBox::setSize (const MyGUI::IntSize& _value)
|
||||||
{
|
{
|
||||||
MyGUI::Widget::setSize (_value);
|
MyGUI::Widget::setSize (_value);
|
||||||
align();
|
align();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HBox::setCoord (const MyGUI::IntCoord& _value)
|
||||||
|
{
|
||||||
|
MyGUI::Widget::setCoord (_value);
|
||||||
|
align();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HBox::onWidgetCreated(MyGUI::Widget* _widget)
|
||||||
|
{
|
||||||
|
align();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HBox::onWidgetDestroy(MyGUI::Widget* _widget)
|
||||||
|
{
|
||||||
|
align();
|
||||||
|
}
|
||||||
|
|
||||||
MyGUI::IntSize HBox::getRequestedSize ()
|
MyGUI::IntSize HBox::getRequestedSize ()
|
||||||
{
|
{
|
||||||
MyGUI::IntSize size(0,0);
|
MyGUI::IntSize size(0,0);
|
||||||
|
@ -954,6 +993,19 @@ MyGUI::IntSize HBox::getRequestedSize ()
|
||||||
if (i != getChildCount()-1)
|
if (i != getChildCount()-1)
|
||||||
size.width += mSpacing;
|
size.width += mSpacing;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MyGUI::IntSize requested = getChildAt(i)->getSize ();
|
||||||
|
size.height = std::max(size.height, requested.height);
|
||||||
|
|
||||||
|
if (getChildAt(i)->getUserString("HStretch") != "true")
|
||||||
|
size.width = size.width + requested.width;
|
||||||
|
|
||||||
|
if (i != getChildCount()-1)
|
||||||
|
size.width += mSpacing;
|
||||||
|
}
|
||||||
|
size.height += mPadding*2;
|
||||||
|
size.width += mPadding*2;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -963,7 +1015,69 @@ MyGUI::IntSize HBox::getRequestedSize ()
|
||||||
|
|
||||||
void VBox::align ()
|
void VBox::align ()
|
||||||
{
|
{
|
||||||
// not yet implemented
|
unsigned int count = getChildCount ();
|
||||||
|
size_t v_stretched_count = 0;
|
||||||
|
int total_height = 0;
|
||||||
|
int total_width = 0;
|
||||||
|
std::vector< std::pair<MyGUI::IntSize, bool> > sizes;
|
||||||
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
MyGUI::Widget* w = getChildAt(i);
|
||||||
|
bool vstretch = w->getUserString ("VStretch") == "true";
|
||||||
|
v_stretched_count += vstretch;
|
||||||
|
AutoSizedWidget* aw = dynamic_cast<AutoSizedWidget*>(w);
|
||||||
|
if (aw)
|
||||||
|
{
|
||||||
|
sizes.push_back(std::make_pair(aw->getRequestedSize (), vstretch));
|
||||||
|
total_height += aw->getRequestedSize ().height;
|
||||||
|
total_width = std::max(total_width, aw->getRequestedSize ().width);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sizes.push_back (std::make_pair(w->getSize(), vstretch));
|
||||||
|
total_height += w->getSize().height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != count-1)
|
||||||
|
total_height += mSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height))
|
||||||
|
{
|
||||||
|
setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int curY = 0;
|
||||||
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (i==0)
|
||||||
|
curY += mPadding;
|
||||||
|
|
||||||
|
MyGUI::Widget* w = getChildAt(i);
|
||||||
|
|
||||||
|
bool hstretch = w->getUserString ("HStretch") == "true";
|
||||||
|
int width = hstretch ? total_width : sizes[i].first.width;
|
||||||
|
|
||||||
|
MyGUI::IntCoord widgetCoord;
|
||||||
|
widgetCoord.top = curY;
|
||||||
|
widgetCoord.left = mPadding + (getSize().width-mPadding*2 - width) / 2;
|
||||||
|
int height = sizes[i].second ? sizes[i].first.height + (getSize().height-mPadding*2 - total_height)/v_stretched_count
|
||||||
|
: sizes[i].first.height;
|
||||||
|
widgetCoord.height = height;
|
||||||
|
widgetCoord.width = width;
|
||||||
|
w->setCoord(widgetCoord);
|
||||||
|
curY += height;
|
||||||
|
|
||||||
|
if (i != count-1)
|
||||||
|
curY += mSpacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VBox::setPropertyOverride(const std::string& _key, const std::string& _value)
|
||||||
|
{
|
||||||
|
Box::_setPropertyImpl (_key, _value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VBox::setSize (const MyGUI::IntSize& _value)
|
void VBox::setSize (const MyGUI::IntSize& _value)
|
||||||
|
@ -972,6 +1086,12 @@ void VBox::setSize (const MyGUI::IntSize& _value)
|
||||||
align();
|
align();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VBox::setCoord (const MyGUI::IntCoord& _value)
|
||||||
|
{
|
||||||
|
MyGUI::Widget::setCoord (_value);
|
||||||
|
align();
|
||||||
|
}
|
||||||
|
|
||||||
MyGUI::IntSize VBox::getRequestedSize ()
|
MyGUI::IntSize VBox::getRequestedSize ()
|
||||||
{
|
{
|
||||||
MyGUI::IntSize size(0,0);
|
MyGUI::IntSize size(0,0);
|
||||||
|
@ -986,6 +1106,29 @@ MyGUI::IntSize VBox::getRequestedSize ()
|
||||||
if (i != getChildCount()-1)
|
if (i != getChildCount()-1)
|
||||||
size.height += mSpacing;
|
size.height += mSpacing;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MyGUI::IntSize requested = getChildAt(i)->getSize ();
|
||||||
|
size.width = std::max(size.width, requested.width);
|
||||||
|
|
||||||
|
if (getChildAt(i)->getUserString("VStretch") != "true")
|
||||||
|
size.height = size.height + requested.height;
|
||||||
|
|
||||||
|
if (i != getChildCount()-1)
|
||||||
|
size.height += mSpacing;
|
||||||
|
}
|
||||||
|
size.height += mPadding*2;
|
||||||
|
size.width += mPadding*2;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VBox::onWidgetCreated(MyGUI::Widget* _widget)
|
||||||
|
{
|
||||||
|
align();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VBox::onWidgetDestroy(MyGUI::Widget* _widget)
|
||||||
|
{
|
||||||
|
align();
|
||||||
|
}
|
||||||
|
|
|
@ -357,10 +357,13 @@ namespace MWGui
|
||||||
protected:
|
protected:
|
||||||
virtual void align() = 0;
|
virtual void align() = 0;
|
||||||
|
|
||||||
virtual void setPropertyOverride(const std::string& _key, const std::string& _value);
|
virtual void _setPropertyImpl(const std::string& _key, const std::string& _value);
|
||||||
|
|
||||||
|
|
||||||
int mSpacing; // how much space to put between elements
|
int mSpacing; // how much space to put between elements
|
||||||
|
|
||||||
|
int mPadding; // outer padding
|
||||||
|
|
||||||
|
bool mAutoResize; // auto resize the box so that it exactly fits all elements
|
||||||
};
|
};
|
||||||
|
|
||||||
class HBox : public Box, public MyGUI::Widget
|
class HBox : public Box, public MyGUI::Widget
|
||||||
|
@ -369,10 +372,16 @@ namespace MWGui
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void setSize (const MyGUI::IntSize &_value);
|
virtual void setSize (const MyGUI::IntSize &_value);
|
||||||
|
virtual void setCoord (const MyGUI::IntCoord &_value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void align();
|
virtual void align();
|
||||||
virtual MyGUI::IntSize getRequestedSize();
|
virtual MyGUI::IntSize getRequestedSize();
|
||||||
|
|
||||||
|
virtual void setPropertyOverride(const std::string& _key, const std::string& _value);
|
||||||
|
|
||||||
|
virtual void onWidgetCreated(MyGUI::Widget* _widget);
|
||||||
|
virtual void onWidgetDestroy(MyGUI::Widget* _widget);
|
||||||
};
|
};
|
||||||
|
|
||||||
class VBox : public Box, public MyGUI::Widget
|
class VBox : public Box, public MyGUI::Widget
|
||||||
|
@ -381,10 +390,16 @@ namespace MWGui
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void setSize (const MyGUI::IntSize &_value);
|
virtual void setSize (const MyGUI::IntSize &_value);
|
||||||
|
virtual void setCoord (const MyGUI::IntCoord &_value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void align();
|
virtual void align();
|
||||||
virtual MyGUI::IntSize getRequestedSize();
|
virtual MyGUI::IntSize getRequestedSize();
|
||||||
|
|
||||||
|
virtual void setPropertyOverride(const std::string& _key, const std::string& _value);
|
||||||
|
|
||||||
|
virtual void onWidgetCreated(MyGUI::Widget* _widget);
|
||||||
|
virtual void onWidgetDestroy(MyGUI::Widget* _widget);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
#include "spellwindow.hpp"
|
#include "spellwindow.hpp"
|
||||||
#include "quickkeysmenu.hpp"
|
#include "quickkeysmenu.hpp"
|
||||||
#include "loadingscreen.hpp"
|
#include "loadingscreen.hpp"
|
||||||
|
#include "levelupdialog.hpp"
|
||||||
|
#include "waitdialog.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
using namespace MWGui;
|
||||||
|
|
||||||
|
@ -70,6 +72,8 @@ WindowManager::WindowManager(
|
||||||
, mSpellWindow(NULL)
|
, mSpellWindow(NULL)
|
||||||
, mLoadingScreen(NULL)
|
, mLoadingScreen(NULL)
|
||||||
, mCharGen(NULL)
|
, mCharGen(NULL)
|
||||||
|
, mLevelupDialog(NULL)
|
||||||
|
, mWaitDialog(NULL)
|
||||||
, mPlayerClass()
|
, mPlayerClass()
|
||||||
, mPlayerName()
|
, mPlayerName()
|
||||||
, mPlayerRaceId()
|
, mPlayerRaceId()
|
||||||
|
@ -84,6 +88,7 @@ WindowManager::WindowManager(
|
||||||
, mGarbageDialogs()
|
, mGarbageDialogs()
|
||||||
, mShown(GW_ALL)
|
, mShown(GW_ALL)
|
||||||
, mAllowed(newGame ? GW_None : GW_ALL)
|
, mAllowed(newGame ? GW_None : GW_ALL)
|
||||||
|
, mRestAllowed(newGame ? false : true)
|
||||||
, mShowFPSLevel(fpsLevel)
|
, mShowFPSLevel(fpsLevel)
|
||||||
, mFPS(0.0f)
|
, mFPS(0.0f)
|
||||||
, mTriangleCount(0)
|
, mTriangleCount(0)
|
||||||
|
@ -147,6 +152,8 @@ WindowManager::WindowManager(
|
||||||
mAlchemyWindow = new AlchemyWindow(*this);
|
mAlchemyWindow = new AlchemyWindow(*this);
|
||||||
mSpellWindow = new SpellWindow(*this);
|
mSpellWindow = new SpellWindow(*this);
|
||||||
mQuickKeysMenu = new QuickKeysMenu(*this);
|
mQuickKeysMenu = new QuickKeysMenu(*this);
|
||||||
|
mLevelupDialog = new LevelupDialog(*this);
|
||||||
|
mWaitDialog = new WaitDialog(*this);
|
||||||
|
|
||||||
mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this);
|
mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this);
|
||||||
mLoadingScreen->onResChange (w,h);
|
mLoadingScreen->onResChange (w,h);
|
||||||
|
@ -200,6 +207,8 @@ WindowManager::~WindowManager()
|
||||||
delete mAlchemyWindow;
|
delete mAlchemyWindow;
|
||||||
delete mSpellWindow;
|
delete mSpellWindow;
|
||||||
delete mLoadingScreen;
|
delete mLoadingScreen;
|
||||||
|
delete mLevelupDialog;
|
||||||
|
delete mWaitDialog;
|
||||||
|
|
||||||
cleanupGarbage();
|
cleanupGarbage();
|
||||||
|
|
||||||
|
@ -247,6 +256,8 @@ void WindowManager::updateVisible()
|
||||||
mAlchemyWindow->setVisible(false);
|
mAlchemyWindow->setVisible(false);
|
||||||
mSpellWindow->setVisible(false);
|
mSpellWindow->setVisible(false);
|
||||||
mQuickKeysMenu->setVisible(false);
|
mQuickKeysMenu->setVisible(false);
|
||||||
|
mLevelupDialog->setVisible(false);
|
||||||
|
mWaitDialog->setVisible(false);
|
||||||
|
|
||||||
mHud->setVisible(true);
|
mHud->setVisible(true);
|
||||||
|
|
||||||
|
@ -298,6 +309,16 @@ void WindowManager::updateVisible()
|
||||||
case GM_Alchemy:
|
case GM_Alchemy:
|
||||||
mAlchemyWindow->setVisible(true);
|
mAlchemyWindow->setVisible(true);
|
||||||
break;
|
break;
|
||||||
|
case GM_Rest:
|
||||||
|
mWaitDialog->setVisible(true);
|
||||||
|
break;
|
||||||
|
case GM_RestBed:
|
||||||
|
mWaitDialog->setVisible(true);
|
||||||
|
mWaitDialog->bedActivated();
|
||||||
|
break;
|
||||||
|
case GM_Levelup:
|
||||||
|
mLevelupDialog->setVisible(true);
|
||||||
|
break;
|
||||||
case GM_Name:
|
case GM_Name:
|
||||||
case GM_Race:
|
case GM_Race:
|
||||||
case GM_Class:
|
case GM_Class:
|
||||||
|
@ -395,7 +416,7 @@ void WindowManager::setValue (int parSkill, const MWMechanics::Stat<float>& valu
|
||||||
mPlayerSkillValues[parSkill] = value;
|
mPlayerSkillValues[parSkill] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
|
void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
mStatsWindow->setValue (id, value);
|
mStatsWindow->setValue (id, value);
|
||||||
mHud->setValue (id, value);
|
mHud->setValue (id, value);
|
||||||
|
@ -532,6 +553,8 @@ void WindowManager::onFrame (float frameDuration)
|
||||||
|
|
||||||
mStatsWindow->onFrame();
|
mStatsWindow->onFrame();
|
||||||
|
|
||||||
|
mWaitDialog->onFrame(frameDuration);
|
||||||
|
|
||||||
mHud->onFrame(frameDuration);
|
mHud->onFrame(frameDuration);
|
||||||
|
|
||||||
mDialogueWindow->checkReferenceAvailable();
|
mDialogueWindow->checkReferenceAvailable();
|
||||||
|
@ -547,7 +570,10 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
if (cell->cell->mName != "")
|
if (cell->cell->mName != "")
|
||||||
|
{
|
||||||
name = cell->cell->mName;
|
name = cell->cell->mName;
|
||||||
|
mMap->addVisitedLocation (name, cell->cell->getGridX (), cell->cell->getGridY ());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const ESM::Region* region = MWBase::Environment::get().getWorld()->getStore().regions.search(cell->cell->mRegion);
|
const ESM::Region* region = MWBase::Environment::get().getWorld()->getStore().regions.search(cell->cell->mRegion);
|
||||||
|
@ -923,3 +949,13 @@ void WindowManager::loadingDone ()
|
||||||
{
|
{
|
||||||
mLoadingScreen->loadingDone ();
|
mLoadingScreen->loadingDone ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WindowManager::getPlayerSleeping ()
|
||||||
|
{
|
||||||
|
return mWaitDialog->getSleeping();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::addVisitedLocation(const std::string& name, int x, int y)
|
||||||
|
{
|
||||||
|
mMap->addVisitedLocation (name, x, y);
|
||||||
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ namespace MWGui
|
||||||
class AlchemyWindow;
|
class AlchemyWindow;
|
||||||
class QuickKeysMenu;
|
class QuickKeysMenu;
|
||||||
class LoadingScreen;
|
class LoadingScreen;
|
||||||
|
class LevelupDialog;
|
||||||
|
class WaitDialog;
|
||||||
|
|
||||||
class WindowManager : public MWBase::WindowManager
|
class WindowManager : public MWBase::WindowManager
|
||||||
{
|
{
|
||||||
|
@ -117,7 +119,7 @@ namespace MWGui
|
||||||
///< Set value for the given ID.
|
///< Set value for the given ID.
|
||||||
virtual void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
|
virtual void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
|
||||||
virtual void setValue (int parSkill, const MWMechanics::Stat<float>& value);
|
virtual void setValue (int parSkill, const MWMechanics::Stat<float>& value);
|
||||||
virtual void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
virtual void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
||||||
virtual void setValue (const std::string& id, const std::string& value);
|
virtual void setValue (const std::string& id, const std::string& value);
|
||||||
virtual void setValue (const std::string& id, int value);
|
virtual void setValue (const std::string& id, int value);
|
||||||
|
|
||||||
|
@ -170,6 +172,8 @@ namespace MWGui
|
||||||
virtual void allowMouse();
|
virtual void allowMouse();
|
||||||
virtual void notifyInputActionBound();
|
virtual void notifyInputActionBound();
|
||||||
|
|
||||||
|
virtual void addVisitedLocation(const std::string& name, int x, int y);
|
||||||
|
|
||||||
virtual void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
|
virtual void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
|
||||||
|
|
||||||
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons);
|
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons);
|
||||||
|
@ -199,6 +203,11 @@ namespace MWGui
|
||||||
virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total);
|
virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total);
|
||||||
virtual void loadingDone();
|
virtual void loadingDone();
|
||||||
|
|
||||||
|
virtual void enableRest() { mRestAllowed = true; }
|
||||||
|
virtual bool getRestEnabled() { return mRestAllowed; }
|
||||||
|
|
||||||
|
virtual bool getPlayerSleeping();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OEngine::GUI::MyGUIManager *mGuiManager;
|
OEngine::GUI::MyGUIManager *mGuiManager;
|
||||||
HUD *mHud;
|
HUD *mHud;
|
||||||
|
@ -224,6 +233,8 @@ namespace MWGui
|
||||||
SpellWindow* mSpellWindow;
|
SpellWindow* mSpellWindow;
|
||||||
QuickKeysMenu* mQuickKeysMenu;
|
QuickKeysMenu* mQuickKeysMenu;
|
||||||
LoadingScreen* mLoadingScreen;
|
LoadingScreen* mLoadingScreen;
|
||||||
|
LevelupDialog* mLevelupDialog;
|
||||||
|
WaitDialog* mWaitDialog;
|
||||||
|
|
||||||
CharacterCreation* mCharGen;
|
CharacterCreation* mCharGen;
|
||||||
|
|
||||||
|
@ -241,7 +252,7 @@ namespace MWGui
|
||||||
std::map<int, MWMechanics::Stat<int> > mPlayerAttributes;
|
std::map<int, MWMechanics::Stat<int> > mPlayerAttributes;
|
||||||
SkillList mPlayerMajorSkills, mPlayerMinorSkills;
|
SkillList mPlayerMajorSkills, mPlayerMinorSkills;
|
||||||
std::map<int, MWMechanics::Stat<float> > mPlayerSkillValues;
|
std::map<int, MWMechanics::Stat<float> > mPlayerSkillValues;
|
||||||
MWMechanics::DynamicStat<int> mPlayerHealth, mPlayerMagicka, mPlayerFatigue;
|
MWMechanics::DynamicStat<float> mPlayerHealth, mPlayerMagicka, mPlayerFatigue;
|
||||||
|
|
||||||
|
|
||||||
MyGUI::Gui *mGui; // Gui
|
MyGUI::Gui *mGui; // Gui
|
||||||
|
@ -258,6 +269,8 @@ namespace MWGui
|
||||||
allow() and disableAll().
|
allow() and disableAll().
|
||||||
*/
|
*/
|
||||||
GuiWindow mAllowed;
|
GuiWindow mAllowed;
|
||||||
|
// is the rest window allowed?
|
||||||
|
bool mRestAllowed;
|
||||||
|
|
||||||
void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings
|
void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,9 @@ namespace MWInput
|
||||||
case A_ToggleWeapon:
|
case A_ToggleWeapon:
|
||||||
toggleWeapon ();
|
toggleWeapon ();
|
||||||
break;
|
break;
|
||||||
|
case A_Rest:
|
||||||
|
rest();
|
||||||
|
break;
|
||||||
case A_ToggleSpell:
|
case A_ToggleSpell:
|
||||||
toggleSpell ();
|
toggleSpell ();
|
||||||
break;
|
break;
|
||||||
|
@ -543,6 +546,15 @@ namespace MWInput
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputManager::rest()
|
||||||
|
{
|
||||||
|
if (!mWindows.getRestEnabled () || mWindows.isGuiMode ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/// \todo check if resting is currently allowed (enemies nearby?)
|
||||||
|
mWindows.pushGuiMode (MWGui::GM_Rest);
|
||||||
|
}
|
||||||
|
|
||||||
void InputManager::screenshot()
|
void InputManager::screenshot()
|
||||||
{
|
{
|
||||||
mEngine.screenshot();
|
mEngine.screenshot();
|
||||||
|
|
|
@ -168,6 +168,7 @@ namespace MWInput
|
||||||
void toggleWalking();
|
void toggleWalking();
|
||||||
void toggleAutoMove();
|
void toggleAutoMove();
|
||||||
void exitNow();
|
void exitNow();
|
||||||
|
void rest();
|
||||||
|
|
||||||
void quickKey (int index);
|
void quickKey (int index);
|
||||||
void showQuickKeysMenu();
|
void showQuickKeysMenu();
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace MWMechanics
|
||||||
creatureStats.getMagicEffects().get (EffectKey (84)).mMagnitude * 0.1 + 0.5;
|
creatureStats.getMagicEffects().get (EffectKey (84)).mMagnitude * 0.1 + 0.5;
|
||||||
|
|
||||||
creatureStats.getHealth().setBase(
|
creatureStats.getHealth().setBase(
|
||||||
static_cast<int> (0.5 * (strength + endurance)));
|
static_cast<int> (0.5 * (strength + endurance)) + creatureStats.getLevelHealthBonus ());
|
||||||
|
|
||||||
creatureStats.getMagicka().setBase(
|
creatureStats.getMagicka().setBase(
|
||||||
static_cast<int> (intelligence + magickaFactor * intelligence));
|
static_cast<int> (intelligence + magickaFactor * intelligence));
|
||||||
|
|
|
@ -9,6 +9,21 @@
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
CreatureStats::CreatureStats()
|
||||||
|
: mLevelHealthBonus(0.f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::increaseLevelHealthBonus (float value)
|
||||||
|
{
|
||||||
|
mLevelHealthBonus += value;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CreatureStats::getLevelHealthBonus () const
|
||||||
|
{
|
||||||
|
return mLevelHealthBonus;
|
||||||
|
}
|
||||||
|
|
||||||
const AiSequence& CreatureStats::getAiSequence() const
|
const AiSequence& CreatureStats::getAiSequence() const
|
||||||
{
|
{
|
||||||
return mAiSequence;
|
return mAiSequence;
|
||||||
|
@ -40,17 +55,17 @@ namespace MWMechanics
|
||||||
return mAttributes[index];
|
return mAttributes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DynamicStat<int> &CreatureStats::getHealth() const
|
const DynamicStat<float> &CreatureStats::getHealth() const
|
||||||
{
|
{
|
||||||
return mDynamic[0];
|
return mDynamic[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DynamicStat<int> &CreatureStats::getMagicka() const
|
const DynamicStat<float> &CreatureStats::getMagicka() const
|
||||||
{
|
{
|
||||||
return mDynamic[1];
|
return mDynamic[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DynamicStat<int> &CreatureStats::getFatigue() const
|
const DynamicStat<float> &CreatureStats::getFatigue() const
|
||||||
{
|
{
|
||||||
return mDynamic[2];
|
return mDynamic[2];
|
||||||
}
|
}
|
||||||
|
@ -103,22 +118,22 @@ namespace MWMechanics
|
||||||
return mAttributes[index];
|
return mAttributes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicStat<int> &CreatureStats::getHealth()
|
DynamicStat<float> &CreatureStats::getHealth()
|
||||||
{
|
{
|
||||||
return mDynamic[0];
|
return mDynamic[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicStat<int> &CreatureStats::getMagicka()
|
DynamicStat<float> &CreatureStats::getMagicka()
|
||||||
{
|
{
|
||||||
return mDynamic[1];
|
return mDynamic[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicStat<int> &CreatureStats::getFatigue()
|
DynamicStat<float> &CreatureStats::getFatigue()
|
||||||
{
|
{
|
||||||
return mDynamic[2];
|
return mDynamic[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicStat<int> &CreatureStats::getDynamic(int index)
|
DynamicStat<float> &CreatureStats::getDynamic(int index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index > 2) {
|
if (index < 0 || index > 2) {
|
||||||
throw std::runtime_error("dynamic stat index is out of range");
|
throw std::runtime_error("dynamic stat index is out of range");
|
||||||
|
@ -154,17 +169,17 @@ namespace MWMechanics
|
||||||
mAttributes[index] = value;
|
mAttributes[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureStats::setHealth(const DynamicStat<int> &value)
|
void CreatureStats::setHealth(const DynamicStat<float> &value)
|
||||||
{
|
{
|
||||||
mDynamic[0] = value;
|
mDynamic[0] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureStats::setMagicka(const DynamicStat<int> &value)
|
void CreatureStats::setMagicka(const DynamicStat<float> &value)
|
||||||
{
|
{
|
||||||
mDynamic[1] = value;
|
mDynamic[1] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureStats::setFatigue(const DynamicStat<int> &value)
|
void CreatureStats::setFatigue(const DynamicStat<float> &value)
|
||||||
{
|
{
|
||||||
mDynamic[2] = value;
|
mDynamic[2] = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace MWMechanics
|
||||||
class CreatureStats
|
class CreatureStats
|
||||||
{
|
{
|
||||||
Stat<int> mAttributes[8];
|
Stat<int> mAttributes[8];
|
||||||
DynamicStat<int> mDynamic[3]; // health, magicka, fatigue
|
DynamicStat<float> mDynamic[3]; // health, magicka, fatigue
|
||||||
int mLevel;
|
int mLevel;
|
||||||
Spells mSpells;
|
Spells mSpells;
|
||||||
ActiveSpells mActiveSpells;
|
ActiveSpells mActiveSpells;
|
||||||
|
@ -30,15 +30,18 @@ namespace MWMechanics
|
||||||
int mAlarm;
|
int mAlarm;
|
||||||
AiSequence mAiSequence;
|
AiSequence mAiSequence;
|
||||||
|
|
||||||
|
float mLevelHealthBonus;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CreatureStats();
|
||||||
|
|
||||||
const Stat<int> & getAttribute(int index) const;
|
const Stat<int> & getAttribute(int index) const;
|
||||||
|
|
||||||
const DynamicStat<int> & getHealth() const;
|
const DynamicStat<float> & getHealth() const;
|
||||||
|
|
||||||
const DynamicStat<int> & getMagicka() const;
|
const DynamicStat<float> & getMagicka() const;
|
||||||
|
|
||||||
const DynamicStat<int> & getFatigue() const;
|
const DynamicStat<float> & getFatigue() const;
|
||||||
|
|
||||||
const Spells & getSpells() const;
|
const Spells & getSpells() const;
|
||||||
|
|
||||||
|
@ -59,13 +62,13 @@ namespace MWMechanics
|
||||||
|
|
||||||
Stat<int> & getAttribute(int index);
|
Stat<int> & getAttribute(int index);
|
||||||
|
|
||||||
DynamicStat<int> & getHealth();
|
DynamicStat<float> & getHealth();
|
||||||
|
|
||||||
DynamicStat<int> & getMagicka();
|
DynamicStat<float> & getMagicka();
|
||||||
|
|
||||||
DynamicStat<int> & getFatigue();
|
DynamicStat<float> & getFatigue();
|
||||||
|
|
||||||
DynamicStat<int> & getDynamic(int index);
|
DynamicStat<float> & getDynamic(int index);
|
||||||
|
|
||||||
Spells & getSpells();
|
Spells & getSpells();
|
||||||
|
|
||||||
|
@ -76,11 +79,11 @@ namespace MWMechanics
|
||||||
|
|
||||||
void setAttribute(int index, const Stat<int> &value);
|
void setAttribute(int index, const Stat<int> &value);
|
||||||
|
|
||||||
void setHealth(const DynamicStat<int> &value);
|
void setHealth(const DynamicStat<float> &value);
|
||||||
|
|
||||||
void setMagicka(const DynamicStat<int> &value);
|
void setMagicka(const DynamicStat<float> &value);
|
||||||
|
|
||||||
void setFatigue(const DynamicStat<int> &value);
|
void setFatigue(const DynamicStat<float> &value);
|
||||||
|
|
||||||
void setSpells(const Spells &spells);
|
void setSpells(const Spells &spells);
|
||||||
|
|
||||||
|
@ -104,6 +107,10 @@ namespace MWMechanics
|
||||||
|
|
||||||
float getFatigueTerm() const;
|
float getFatigueTerm() const;
|
||||||
///< Return effective fatigue
|
///< Return effective fatigue
|
||||||
|
|
||||||
|
// small hack to allow the fact that Health permanently increases by 10% of endurance on each level up
|
||||||
|
void increaseLevelHealthBonus(float value);
|
||||||
|
float getLevelHealthBonus() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
#include <components/esm/loadclas.hpp>
|
#include <components/esm/loadclas.hpp>
|
||||||
#include <components/esm/loadgmst.hpp>
|
#include <components/esm/loadgmst.hpp>
|
||||||
|
@ -12,10 +14,17 @@
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
|
||||||
MWMechanics::NpcStats::NpcStats()
|
MWMechanics::NpcStats::NpcStats()
|
||||||
: mMovementFlags (0), mDrawState (DrawState_Nothing)
|
: mMovementFlags (0), mDrawState (DrawState_Nothing)
|
||||||
{}
|
, mLevelProgress(0)
|
||||||
|
{
|
||||||
|
mSkillIncreases.resize (ESM::Attribute::Length);
|
||||||
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
mSkillIncreases[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
MWMechanics::DrawState_ MWMechanics::NpcStats::getDrawState() const
|
MWMechanics::DrawState_ MWMechanics::NpcStats::getDrawState() const
|
||||||
{
|
{
|
||||||
|
@ -122,7 +131,7 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla
|
||||||
throw std::runtime_error ("invalid skill specialisation factor");
|
throw std::runtime_error ("invalid skill specialisation factor");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1.0 / (level +1) * (1.0 / skillFactor) * typeFactor * specialisationFactor;
|
return 1.0 / (level +1) * (1.0 / (skillFactor)) * typeFactor * specialisationFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType)
|
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType)
|
||||||
|
@ -134,7 +143,87 @@ void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_,
|
||||||
base += getSkillGain (skillIndex, class_, usageType);
|
base += getSkillGain (skillIndex, class_, usageType);
|
||||||
|
|
||||||
if (static_cast<int> (base)!=level)
|
if (static_cast<int> (base)!=level)
|
||||||
|
{
|
||||||
|
// skill leveled up
|
||||||
|
increaseSkill(skillIndex, class_, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
getSkill (skillIndex).setBase (base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &class_, bool preserveProgress)
|
||||||
|
{
|
||||||
|
float base = getSkill (skillIndex).getBase();
|
||||||
|
|
||||||
|
int level = static_cast<int> (base);
|
||||||
|
|
||||||
|
if (level >= 100)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (preserveProgress)
|
||||||
|
base += 1;
|
||||||
|
else
|
||||||
base = level+1;
|
base = level+1;
|
||||||
|
|
||||||
|
// if this is a major or minor skill of the class, increase level progress
|
||||||
|
bool levelProgress = false;
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
for (int j=0; j<5; ++j)
|
||||||
|
{
|
||||||
|
int skill = class_.mData.mSkills[j][i];
|
||||||
|
if (skill == skillIndex)
|
||||||
|
levelProgress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLevelProgress += levelProgress;
|
||||||
|
|
||||||
|
// check the attribute this skill belongs to
|
||||||
|
const ESM::Skill* skill = MWBase::Environment::get().getWorld ()->getStore ().skills.find(skillIndex);
|
||||||
|
++mSkillIncreases[skill->mData.mAttribute];
|
||||||
|
|
||||||
|
// Play sound & skill progress notification
|
||||||
|
/// \todo check if character is the player, if levelling is ever implemented for NPCs
|
||||||
|
MWBase::Environment::get().getSoundManager ()->playSound ("skillraise", 1, 1);
|
||||||
|
|
||||||
|
std::stringstream message;
|
||||||
|
message << boost::format(MWBase::Environment::get().getWindowManager ()->getGameSettingString ("sNotifyMessage39", ""))
|
||||||
|
% std::string("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}")
|
||||||
|
% base;
|
||||||
|
MWBase::Environment::get().getWindowManager ()->messageBox(message.str(), std::vector<std::string>());
|
||||||
|
|
||||||
|
if (mLevelProgress >= 10)
|
||||||
|
{
|
||||||
|
// levelup is possible now
|
||||||
|
MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", std::vector<std::string>());
|
||||||
|
}
|
||||||
|
|
||||||
getSkill (skillIndex).setBase (base);
|
getSkill (skillIndex).setBase (base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MWMechanics::NpcStats::getLevelProgress () const
|
||||||
|
{
|
||||||
|
return mLevelProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWMechanics::NpcStats::levelUp()
|
||||||
|
{
|
||||||
|
mLevelProgress -= 10;
|
||||||
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
mSkillIncreases[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MWMechanics::NpcStats::getLevelupAttributeMultiplier(int attribute) const
|
||||||
|
{
|
||||||
|
// Source: http://www.uesp.net/wiki/Morrowind:Level#How_to_Level_Up
|
||||||
|
int num = mSkillIncreases[attribute];
|
||||||
|
if (num <= 1)
|
||||||
|
return 1;
|
||||||
|
else if (num <= 4)
|
||||||
|
return 2;
|
||||||
|
else if (num <= 7)
|
||||||
|
return 3;
|
||||||
|
else if (num <= 9)
|
||||||
|
return 4;
|
||||||
|
else
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "stat.hpp"
|
#include "stat.hpp"
|
||||||
#include "drawstate.hpp"
|
#include "drawstate.hpp"
|
||||||
|
@ -45,6 +46,10 @@ namespace MWMechanics
|
||||||
unsigned int mMovementFlags;
|
unsigned int mMovementFlags;
|
||||||
Stat<float> mSkill[27];
|
Stat<float> mSkill[27];
|
||||||
|
|
||||||
|
int mLevelProgress; // 0-10
|
||||||
|
|
||||||
|
std::vector<int> mSkillIncreases; // number of skill increases for each attribute
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NpcStats();
|
NpcStats();
|
||||||
|
@ -73,6 +78,14 @@ namespace MWMechanics
|
||||||
|
|
||||||
void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1);
|
void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1);
|
||||||
///< Increase skill by usage.
|
///< Increase skill by usage.
|
||||||
|
|
||||||
|
void increaseSkill (int skillIndex, const ESM::Class& class_, bool preserveProgress);
|
||||||
|
|
||||||
|
int getLevelProgress() const;
|
||||||
|
|
||||||
|
int getLevelupAttributeMultiplier(int attribute) const;
|
||||||
|
|
||||||
|
void levelUp();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,8 @@ namespace MWRender
|
||||||
CharacterPreview::~CharacterPreview ()
|
CharacterPreview::~CharacterPreview ()
|
||||||
{
|
{
|
||||||
Ogre::TextureManager::getSingleton().remove(mName);
|
Ogre::TextureManager::getSingleton().remove(mName);
|
||||||
|
mSceneMgr->destroyCamera (mName);
|
||||||
|
delete mAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
148
apps/openmw/mwrender/globalmap.cpp
Normal file
148
apps/openmw/mwrender/globalmap.cpp
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
#include "globalmap.hpp"
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#include <OgreImage.h>
|
||||||
|
#include <OgreTextureManager.h>
|
||||||
|
#include <OgreColourValue.h>
|
||||||
|
#include <OgreHardwareVertexBuffer.h>
|
||||||
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
#include <components/esm_store/store.hpp>
|
||||||
|
#include <components/esm_store/reclists.hpp>
|
||||||
|
|
||||||
|
namespace MWRender
|
||||||
|
{
|
||||||
|
|
||||||
|
GlobalMap::GlobalMap(const std::string &cacheDir)
|
||||||
|
: mCacheDir(cacheDir)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlobalMap::render ()
|
||||||
|
{
|
||||||
|
Ogre::TexturePtr tex;
|
||||||
|
|
||||||
|
if (!boost::filesystem::exists(mCacheDir + "/GlobalMap.png"))
|
||||||
|
{
|
||||||
|
|
||||||
|
int cellSize = 24;
|
||||||
|
|
||||||
|
Ogre::Image image;
|
||||||
|
|
||||||
|
int width = cellSize*61;
|
||||||
|
int height = cellSize*61;
|
||||||
|
|
||||||
|
Ogre::uchar data[width * height * 3];
|
||||||
|
|
||||||
|
for (int x = -30; x <= 30; ++x)
|
||||||
|
{
|
||||||
|
for (int y = -30; y <= 30; ++y)
|
||||||
|
{
|
||||||
|
ESM::Land* land = MWBase::Environment::get().getWorld ()->getStore ().lands.search (x,y);
|
||||||
|
|
||||||
|
if (land)
|
||||||
|
{
|
||||||
|
if (!land->isDataLoaded(ESM::Land::DATA_VHGT))
|
||||||
|
{
|
||||||
|
land->loadData(ESM::Land::DATA_VHGT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int cellY=0; cellY<cellSize; ++cellY)
|
||||||
|
{
|
||||||
|
for (int cellX=0; cellX<cellSize; ++cellX)
|
||||||
|
{
|
||||||
|
int vertexX = float(cellX)/float(cellSize) * ESM::Land::LAND_SIZE;
|
||||||
|
int vertexY = float(cellY)/float(cellSize) * ESM::Land::LAND_SIZE;
|
||||||
|
|
||||||
|
|
||||||
|
int texelX = (x+30) * cellSize + cellX;
|
||||||
|
int texelY = (height-1) - ((y+30) * cellSize + cellY);
|
||||||
|
|
||||||
|
Ogre::ColourValue waterShallowColour(0.15, 0.2, 0.19);
|
||||||
|
Ogre::ColourValue waterDeepColour(0.1, 0.14, 0.13);
|
||||||
|
Ogre::ColourValue groundColour(0.254, 0.19, 0.13);
|
||||||
|
Ogre::ColourValue mountainColour(0.05, 0.05, 0.05);
|
||||||
|
Ogre::ColourValue hillColour(0.16, 0.12, 0.08);
|
||||||
|
|
||||||
|
float mountainHeight = 15000.f;
|
||||||
|
float hillHeight = 2500.f;
|
||||||
|
|
||||||
|
unsigned char r,g,b;
|
||||||
|
|
||||||
|
if (land)
|
||||||
|
{
|
||||||
|
float landHeight = land->mLandData->mHeights[vertexY * ESM::Land::LAND_SIZE + vertexX];
|
||||||
|
|
||||||
|
|
||||||
|
if (landHeight >= 0)
|
||||||
|
{
|
||||||
|
if (landHeight >= hillHeight)
|
||||||
|
{
|
||||||
|
float factor = std::min(1.f, float(landHeight-hillHeight)/mountainHeight);
|
||||||
|
r = (hillColour.r * (1-factor) + mountainColour.r * factor) * 255;
|
||||||
|
g = (hillColour.g * (1-factor) + mountainColour.g * factor) * 255;
|
||||||
|
b = (hillColour.b * (1-factor) + mountainColour.b * factor) * 255;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float factor = std::min(1.f, float(landHeight)/hillHeight);
|
||||||
|
r = (groundColour.r * (1-factor) + hillColour.r * factor) * 255;
|
||||||
|
g = (groundColour.g * (1-factor) + hillColour.g * factor) * 255;
|
||||||
|
b = (groundColour.b * (1-factor) + hillColour.b * factor) * 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (landHeight >= -100)
|
||||||
|
{
|
||||||
|
float factor = std::min(1.f, -1*landHeight/100.f);
|
||||||
|
r = (((waterShallowColour+groundColour)/2).r * (1-factor) + waterShallowColour.r * factor) * 255;
|
||||||
|
g = (((waterShallowColour+groundColour)/2).g * (1-factor) + waterShallowColour.g * factor) * 255;
|
||||||
|
b = (((waterShallowColour+groundColour)/2).b * (1-factor) + waterShallowColour.b * factor) * 255;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float factor = std::min(1.f, -1*(landHeight-100)/1000.f);
|
||||||
|
r = (waterShallowColour.r * (1-factor) + waterDeepColour.r * factor) * 255;
|
||||||
|
g = (waterShallowColour.g * (1-factor) + waterDeepColour.g * factor) * 255;
|
||||||
|
b = (waterShallowColour.b * (1-factor) + waterDeepColour.b * factor) * 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = waterDeepColour.r * 255;
|
||||||
|
g = waterDeepColour.g * 255;
|
||||||
|
b = waterDeepColour.b * 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[texelY * height * 3 + texelX * 3] = r;
|
||||||
|
data[texelY * height * 3 + texelX * 3+1] = g;
|
||||||
|
data[texelY * height * 3 + texelX * 3+2] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
image.loadDynamicImage (data, width, height, Ogre::PF_B8G8R8);
|
||||||
|
|
||||||
|
image.save (mCacheDir + "/GlobalMap.png");
|
||||||
|
|
||||||
|
tex = Ogre::TextureManager::getSingleton ().createManual ("GlobalMap.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||||
|
Ogre::TEX_TYPE_2D, width, height, 0, Ogre::PF_B8G8R8, Ogre::TU_DEFAULT);
|
||||||
|
tex->loadImage(image);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tex = Ogre::TextureManager::getSingleton ().getByName ("GlobalMap.png");
|
||||||
|
|
||||||
|
tex->load();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
23
apps/openmw/mwrender/globalmap.hpp
Normal file
23
apps/openmw/mwrender/globalmap.hpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef _GAME_RENDER_GLOBALMAP_H
|
||||||
|
#define _GAME_RENDER_GLOBALMAP_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace MWRender
|
||||||
|
{
|
||||||
|
|
||||||
|
class GlobalMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GlobalMap(const std::string& cacheDir);
|
||||||
|
|
||||||
|
void render();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mCacheDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -77,12 +77,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
|
||||||
bodyRaceID = "b_n_"+ref->base->mRace;
|
bodyRaceID = "b_n_"+ref->base->mRace;
|
||||||
std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower);
|
std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower);
|
||||||
|
|
||||||
/*std::cout << "Race: " << ref->base->race ;
|
|
||||||
if(female)
|
|
||||||
std::cout << " Sex: Female" << " Height: " << race->data.height.female << "\n";
|
|
||||||
else
|
|
||||||
std::cout << " Sex: Male" << " Height: " << race->data.height.male << "\n";
|
|
||||||
*/
|
|
||||||
|
|
||||||
mInsert = node;
|
mInsert = node;
|
||||||
assert(mInsert);
|
assert(mInsert);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "compositors.hpp"
|
#include "compositors.hpp"
|
||||||
#include "npcanimation.hpp"
|
#include "npcanimation.hpp"
|
||||||
#include "externalrendering.hpp"
|
#include "externalrendering.hpp"
|
||||||
|
#include "globalmap.hpp"
|
||||||
|
|
||||||
using namespace MWRender;
|
using namespace MWRender;
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
@ -100,7 +101,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
||||||
MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
|
MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
|
||||||
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
|
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
|
||||||
|
|
||||||
// Load resources
|
ResourceGroupManager::getSingleton ().declareResource ("GlobalMap.png", "Texture", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||||
|
|
||||||
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
||||||
|
|
||||||
// causes light flicker in opengl when moving..
|
// causes light flicker in opengl when moving..
|
||||||
|
@ -129,6 +131,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
||||||
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
|
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
|
||||||
sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2)));
|
sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2)));
|
||||||
sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6)));
|
sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6)));
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(
|
||||||
|
Settings::Manager::getFloat ("gamma", "Video"))));
|
||||||
|
|
||||||
applyCompositors();
|
applyCompositors();
|
||||||
|
|
||||||
|
@ -160,6 +164,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
||||||
mDebugging = new Debugging(mMwRoot, engine);
|
mDebugging = new Debugging(mMwRoot, engine);
|
||||||
mLocalMap = new MWRender::LocalMap(&mRendering, this);
|
mLocalMap = new MWRender::LocalMap(&mRendering, this);
|
||||||
|
|
||||||
|
mGlobalMap = new GlobalMap(cacheDir.string());
|
||||||
|
|
||||||
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
|
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,6 +182,7 @@ RenderingManager::~RenderingManager ()
|
||||||
delete mOcclusionQuery;
|
delete mOcclusionQuery;
|
||||||
delete mCompositors;
|
delete mCompositors;
|
||||||
delete mWater;
|
delete mWater;
|
||||||
|
delete mGlobalMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWRender::SkyManager* RenderingManager::getSkyManager()
|
MWRender::SkyManager* RenderingManager::getSkyManager()
|
||||||
|
@ -275,6 +282,7 @@ RenderingManager::rotateObject(
|
||||||
float *f = ptr.getRefData().getPosition().rot;
|
float *f = ptr.getRefData().getPosition().rot;
|
||||||
rot.x += f[0], rot.y += f[1], rot.z += f[2];
|
rot.x += f[0], rot.y += f[1], rot.z += f[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isPlayer && isActive) {
|
if (!isPlayer && isActive) {
|
||||||
Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X);
|
Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X);
|
||||||
Ogre::Quaternion yr(Ogre::Radian(rot.y), Ogre::Vector3::UNIT_Y);
|
Ogre::Quaternion yr(Ogre::Radian(rot.y), Ogre::Vector3::UNIT_Y);
|
||||||
|
@ -282,6 +290,7 @@ RenderingManager::rotateObject(
|
||||||
|
|
||||||
ptr.getRefData().getBaseNode()->setOrientation(xr * yr * zr);
|
ptr.getRefData().getBaseNode()->setOrientation(xr * yr * zr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return force;
|
return force;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,6 +756,11 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
|
||||||
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));
|
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));
|
||||||
mObjects.rebuildStaticGeometry ();
|
mObjects.rebuildStaticGeometry ();
|
||||||
}
|
}
|
||||||
|
else if (it->second == "gamma" && it->first == "Video")
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(
|
||||||
|
Settings::Manager::getFloat ("gamma", "Video"))));
|
||||||
|
}
|
||||||
else if (it->second == "shader mode" && it->first == "General")
|
else if (it->second == "shader mode" && it->first == "General")
|
||||||
{
|
{
|
||||||
sh::Language lang;
|
sh::Language lang;
|
||||||
|
@ -887,4 +901,9 @@ void RenderingManager::setupExternalRendering (MWRender::ExternalRendering& rend
|
||||||
rendering.setup (mRendering.getScene());
|
rendering.setup (mRendering.getScene());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingManager::renderGlobalMap ()
|
||||||
|
{
|
||||||
|
mGlobalMap->render ();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace MWRender
|
||||||
class Water;
|
class Water;
|
||||||
class Compositors;
|
class Compositors;
|
||||||
class ExternalRendering;
|
class ExternalRendering;
|
||||||
|
class GlobalMap;
|
||||||
|
|
||||||
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener {
|
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener {
|
||||||
|
|
||||||
|
@ -194,6 +195,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
||||||
|
|
||||||
void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
||||||
|
|
||||||
|
void renderGlobalMap();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void windowResized(Ogre::RenderWindow* rw);
|
virtual void windowResized(Ogre::RenderWindow* rw);
|
||||||
virtual void windowClosed(Ogre::RenderWindow* rw);
|
virtual void windowClosed(Ogre::RenderWindow* rw);
|
||||||
|
@ -218,6 +221,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
||||||
|
|
||||||
MWRender::Water *mWater;
|
MWRender::Water *mWater;
|
||||||
|
|
||||||
|
GlobalMap* mGlobalMap;
|
||||||
|
|
||||||
OEngine::Render::OgreRenderer &mRendering;
|
OEngine::Render::OgreRenderer &mRendering;
|
||||||
|
|
||||||
MWRender::Objects mObjects;
|
MWRender::Objects mObjects;
|
||||||
|
|
|
@ -31,7 +31,7 @@ op 0x2000e: PCGetRank implicit
|
||||||
op 0x2000f: PCGetRank explicit
|
op 0x2000f: PCGetRank explicit
|
||||||
op 0x20010: AiWander
|
op 0x20010: AiWander
|
||||||
op 0x20011: AiWander, explicit reference
|
op 0x20011: AiWander, explicit reference
|
||||||
opcodes 0x20012-0x3ffff unused
|
op s 0x20012-0x3ffff unused
|
||||||
|
|
||||||
Segment 4:
|
Segment 4:
|
||||||
(not implemented yet)
|
(not implemented yet)
|
||||||
|
@ -183,4 +183,27 @@ op 0x2000172: GetStartingAngle
|
||||||
op 0x2000173: GetStartingAngle, explicit reference
|
op 0x2000173: GetStartingAngle, explicit reference
|
||||||
op 0x2000174: ToggleVanityMode
|
op 0x2000174: ToggleVanityMode
|
||||||
op 0x2000175-0x200018B: Get controls disabled
|
op 0x2000175-0x200018B: Get controls disabled
|
||||||
opcodes 0x200018C-0x3ffffff unused
|
op 0x200018C: GetLevel
|
||||||
|
op 0x200018D: GetLevel, explicit reference
|
||||||
|
op 0x200018E: SetLevel
|
||||||
|
op 0x200018F: SetLevel, explicit reference
|
||||||
|
op 0x2000190: GetPos
|
||||||
|
op 0x2000191: GetPosExplicit
|
||||||
|
op 0x2000192: SetPos
|
||||||
|
op 0x2000193: SetPosExplicit
|
||||||
|
op 0x2000194: GetStartingPos
|
||||||
|
op 0x2000195: GetStartingPosExplicit
|
||||||
|
op 0x2000196: Position
|
||||||
|
op 0x2000197: Position Explicit
|
||||||
|
op 0x2000198: PositionCell
|
||||||
|
op 0x2000199: PositionCell Explicit
|
||||||
|
op 0x200019a: PlaceItemCell
|
||||||
|
op 0x200019b: PlaceItem
|
||||||
|
op 0x200019c: PlaceAtPc
|
||||||
|
op 0x200019d: PlaceAtMe
|
||||||
|
op 0x200019e: PlaceAtMe Explicit
|
||||||
|
op 0x200019f: GetPcSleep
|
||||||
|
op 0x20001a0: ShowMap
|
||||||
|
op 0x20001a1: FillMap
|
||||||
|
opcodes 0x20001a2-0x3ffffff unused
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
|
|
||||||
#include "guiextensions.hpp"
|
#include "guiextensions.hpp"
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include <components/compiler/extensions.hpp>
|
#include <components/compiler/extensions.hpp>
|
||||||
|
|
||||||
#include <components/interpreter/interpreter.hpp>
|
#include <components/interpreter/interpreter.hpp>
|
||||||
#include <components/interpreter/runtime.hpp>
|
#include <components/interpreter/runtime.hpp>
|
||||||
#include <components/interpreter/opcodes.hpp>
|
#include <components/interpreter/opcodes.hpp>
|
||||||
|
|
||||||
|
#include <components/esm_store/store.hpp>
|
||||||
|
#include <components/esm_store/reclists.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
|
@ -30,6 +35,16 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OpEnableRest : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->enableRest();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class OpShowDialogue : public Interpreter::Opcode0
|
class OpShowDialogue : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
MWGui::GuiMode mDialogue;
|
MWGui::GuiMode mDialogue;
|
||||||
|
@ -81,6 +96,47 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OpShowMap : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
std::string cell = (runtime.getStringLiteral (runtime[0].mInteger));
|
||||||
|
boost::algorithm::to_lower(cell);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
// "Will match complete or partial cells, so ShowMap, "Vivec" will show cells Vivec and Vivec, Fred's House as well."
|
||||||
|
// http://www.uesp.net/wiki/Tes3Mod:ShowMap
|
||||||
|
|
||||||
|
const ESMS::CellList::ExtCells& extCells = MWBase::Environment::get().getWorld ()->getStore ().cells.extCells;
|
||||||
|
for (ESMS::CellList::ExtCells::const_iterator it = extCells.begin(); it != extCells.end(); ++it)
|
||||||
|
{
|
||||||
|
std::string name = it->second->mName;
|
||||||
|
boost::algorithm::to_lower(name);
|
||||||
|
if (name.find(cell) != std::string::npos)
|
||||||
|
MWBase::Environment::get().getWindowManager()->addVisitedLocation (it->second->mName, it->first.first, it->first.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpFillMap : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
const ESMS::CellList::ExtCells& extCells = MWBase::Environment::get().getWorld ()->getStore ().cells.extCells;
|
||||||
|
for (ESMS::CellList::ExtCells::const_iterator it = extCells.begin(); it != extCells.end(); ++it)
|
||||||
|
{
|
||||||
|
std::string name = it->second->mName;
|
||||||
|
if (name != "")
|
||||||
|
MWBase::Environment::get().getWindowManager()->addVisitedLocation (name, it->first.first, it->first.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const int opcodeEnableBirthMenu = 0x200000e;
|
const int opcodeEnableBirthMenu = 0x200000e;
|
||||||
const int opcodeEnableClassMenu = 0x200000f;
|
const int opcodeEnableClassMenu = 0x200000f;
|
||||||
const int opcodeEnableNameMenu = 0x2000010;
|
const int opcodeEnableNameMenu = 0x2000010;
|
||||||
|
@ -95,6 +151,8 @@ namespace MWScript
|
||||||
const int opcodeGetButtonPressed = 0x2000137;
|
const int opcodeGetButtonPressed = 0x2000137;
|
||||||
const int opcodeToggleFogOfWar = 0x2000145;
|
const int opcodeToggleFogOfWar = 0x2000145;
|
||||||
const int opcodeToggleFullHelp = 0x2000151;
|
const int opcodeToggleFullHelp = 0x2000151;
|
||||||
|
const int opcodeShowMap = 0x20001a0;
|
||||||
|
const int opcodeFillMap = 0x20001a1;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
@ -122,6 +180,9 @@ opcodeEnableStatsReviewMenu);
|
||||||
|
|
||||||
extensions.registerInstruction ("togglefullhelp", "", opcodeToggleFullHelp);
|
extensions.registerInstruction ("togglefullhelp", "", opcodeToggleFullHelp);
|
||||||
extensions.registerInstruction ("tfh", "", opcodeToggleFullHelp);
|
extensions.registerInstruction ("tfh", "", opcodeToggleFullHelp);
|
||||||
|
|
||||||
|
extensions.registerInstruction ("showmap", "S", opcodeShowMap);
|
||||||
|
extensions.registerInstruction ("fillmap", "", opcodeFillMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -146,21 +207,20 @@ opcodeEnableStatsReviewMenu);
|
||||||
interpreter.installSegment5 (opcodeEnableStatsMenu,
|
interpreter.installSegment5 (opcodeEnableStatsMenu,
|
||||||
new OpEnableWindow (MWGui::GW_Stats));
|
new OpEnableWindow (MWGui::GW_Stats));
|
||||||
|
|
||||||
/* Not done yet. Enabling rest mode is not really a gui
|
|
||||||
issue, it's a gameplay issue.
|
|
||||||
|
|
||||||
interpreter.installSegment5 (opcodeEnableRest,
|
interpreter.installSegment5 (opcodeEnableRest,
|
||||||
new OpEnableDialogue (MWGui::GM_Rest));
|
new OpEnableRest ());
|
||||||
*/
|
|
||||||
|
|
||||||
interpreter.installSegment5 (opcodeShowRestMenu,
|
interpreter.installSegment5 (opcodeShowRestMenu,
|
||||||
new OpShowDialogue (MWGui::GM_Rest));
|
new OpShowDialogue (MWGui::GM_RestBed));
|
||||||
|
|
||||||
interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed);
|
interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed);
|
||||||
|
|
||||||
interpreter.installSegment5 (opcodeToggleFogOfWar, new OpToggleFogOfWar);
|
interpreter.installSegment5 (opcodeToggleFogOfWar, new OpToggleFogOfWar);
|
||||||
|
|
||||||
interpreter.installSegment5 (opcodeToggleFullHelp, new OpToggleFullHelp);
|
interpreter.installSegment5 (opcodeToggleFullHelp, new OpToggleFullHelp);
|
||||||
|
|
||||||
|
interpreter.installSegment5 (opcodeShowMap, new OpShowMap);
|
||||||
|
interpreter.installSegment5 (opcodeFillMap, new OpFillMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <components/interpreter/opcodes.hpp>
|
#include <components/interpreter/opcodes.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
@ -20,6 +21,16 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
namespace Misc
|
namespace Misc
|
||||||
{
|
{
|
||||||
|
class OpGetPcSleep : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
runtime.push (MWBase::Environment::get().getWindowManager ()->getPlayerSleeping());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class OpXBox : public Interpreter::Opcode0
|
class OpXBox : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -249,6 +260,7 @@ namespace MWScript
|
||||||
const int opcodeTogglePathgrid = 0x2000146;
|
const int opcodeTogglePathgrid = 0x2000146;
|
||||||
const int opcodeDontSaveObject = 0x2000153;
|
const int opcodeDontSaveObject = 0x2000153;
|
||||||
const int opcodeToggleVanityMode = 0x2000174;
|
const int opcodeToggleVanityMode = 0x2000174;
|
||||||
|
const int opcodeGetPcSleep = 0x200019f;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
@ -273,6 +285,7 @@ namespace MWScript
|
||||||
extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
|
extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
|
||||||
extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode);
|
extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode);
|
||||||
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
|
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
|
||||||
|
extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -293,6 +306,7 @@ namespace MWScript
|
||||||
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater);
|
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater);
|
||||||
interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject);
|
interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject);
|
||||||
interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode);
|
interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode);
|
||||||
|
interpreter.installSegment5 (opcodeGetPcSleep, new OpGetPcSleep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,42 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
namespace Stats
|
namespace Stats
|
||||||
{
|
{
|
||||||
|
template<class R>
|
||||||
|
class OpGetLevel : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
|
Interpreter::Type_Integer value =
|
||||||
|
MWWorld::Class::get (ptr)
|
||||||
|
.getCreatureStats (ptr)
|
||||||
|
.getLevel();
|
||||||
|
|
||||||
|
runtime.push (value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpSetLevel : 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)
|
||||||
|
.setLevel(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<class R>
|
template<class R>
|
||||||
class OpGetAttribute : public Interpreter::Opcode0
|
class OpGetAttribute : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
|
@ -592,6 +628,11 @@ namespace MWScript
|
||||||
const int opcodeModDisposition = 0x200014d;
|
const int opcodeModDisposition = 0x200014d;
|
||||||
const int opcodeModDispositionExplicit = 0x200014e;
|
const int opcodeModDispositionExplicit = 0x200014e;
|
||||||
|
|
||||||
|
const int opcodeGetLevel = 0x200018c;
|
||||||
|
const int opcodeGetLevelExplicit = 0x200018d;
|
||||||
|
const int opcodeSetLevel = 0x200018e;
|
||||||
|
const int opcodeSetLevelExplicit = 0x200018f;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
static const char *attributes[numberOfAttributes] =
|
static const char *attributes[numberOfAttributes] =
|
||||||
|
@ -674,6 +715,9 @@ namespace MWScript
|
||||||
extensions.registerInstruction("moddisposition","l",opcodeModDisposition,
|
extensions.registerInstruction("moddisposition","l",opcodeModDisposition,
|
||||||
opcodeModDispositionExplicit);
|
opcodeModDispositionExplicit);
|
||||||
extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit);
|
extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit);
|
||||||
|
|
||||||
|
extensions.registerInstruction("setlevel", "l", opcodeSetLevel, opcodeSetLevelExplicit);
|
||||||
|
extensions.registerFunction("getlevel", 'l', "", opcodeGetLevel, opcodeGetLevelExplicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -745,6 +789,12 @@ namespace MWScript
|
||||||
interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition<ExplicitRef>);
|
interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition<ExplicitRef>);
|
||||||
interpreter.installSegment3(opcodeGetPCRank,new OpGetPCRank<ImplicitRef>);
|
interpreter.installSegment3(opcodeGetPCRank,new OpGetPCRank<ImplicitRef>);
|
||||||
interpreter.installSegment3(opcodeGetPCRankExplicit,new OpGetPCRank<ExplicitRef>);
|
interpreter.installSegment3(opcodeGetPCRankExplicit,new OpGetPCRank<ExplicitRef>);
|
||||||
|
|
||||||
|
interpreter.installSegment5 (opcodeGetLevel, new OpGetLevel<ImplicitRef>);
|
||||||
|
interpreter.installSegment5 (opcodeGetLevelExplicit, new OpGetLevel<ExplicitRef>);
|
||||||
|
interpreter.installSegment5 (opcodeSetLevel, new OpSetLevel<ImplicitRef>);
|
||||||
|
interpreter.installSegment5 (opcodeSetLevelExplicit, new OpSetLevel<ExplicitRef>);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#include <OgreMath.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
#include <components/esm_store/store.hpp>
|
#include <components/esm_store/store.hpp>
|
||||||
|
#include <components/esm/loadcell.hpp>
|
||||||
|
|
||||||
#include <components/compiler/extensions.hpp>
|
#include <components/compiler/extensions.hpp>
|
||||||
|
|
||||||
|
@ -11,10 +15,11 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/player.hpp"
|
||||||
|
#include "../mwworld/manualref.hpp"
|
||||||
|
|
||||||
#include "interpretercontext.hpp"
|
#include "interpretercontext.hpp"
|
||||||
#include "ref.hpp"
|
#include "ref.hpp"
|
||||||
#include "OgreSceneNode.h"
|
|
||||||
|
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
{
|
{
|
||||||
|
@ -141,6 +146,368 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpGetPos : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
|
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
if(axis == "x")
|
||||||
|
{
|
||||||
|
runtime.push(ptr.getRefData().getPosition().pos[0]);
|
||||||
|
}
|
||||||
|
else if(axis == "y")
|
||||||
|
{
|
||||||
|
runtime.push(ptr.getRefData().getPosition().pos[1]);
|
||||||
|
}
|
||||||
|
else if(axis == "z")
|
||||||
|
{
|
||||||
|
runtime.push(ptr.getRefData().getPosition().pos[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error ("invalid rotation axis: " + axis);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpSetPos : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
|
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float pos = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
float ax = ptr.getRefData().getPosition().pos[0];
|
||||||
|
float ay = ptr.getRefData().getPosition().pos[1];
|
||||||
|
float az = ptr.getRefData().getPosition().pos[2];
|
||||||
|
|
||||||
|
if(axis == "x")
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld()->moveObject(ptr,pos,ay,az);
|
||||||
|
}
|
||||||
|
else if(axis == "y")
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld()->moveObject(ptr,ax,pos,az);
|
||||||
|
}
|
||||||
|
else if(axis == "z")
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld()->moveObject(ptr,ax,ay,pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error ("invalid axis: " + axis);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpGetStartingPos : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
|
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
if(axis == "x")
|
||||||
|
{
|
||||||
|
runtime.push(ptr.getCellRef().mPos.pos[0]);
|
||||||
|
}
|
||||||
|
else if(axis == "y")
|
||||||
|
{
|
||||||
|
runtime.push(ptr.getCellRef().mPos.pos[1]);
|
||||||
|
}
|
||||||
|
else if(axis == "z")
|
||||||
|
{
|
||||||
|
runtime.push(ptr.getCellRef().mPos.pos[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error ("invalid axis: " + axis);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpPositionCell : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
|
Interpreter::Type_Float x = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float y = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float z = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float zRot = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
std::string cellID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
MWWorld::CellStore* store = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
store = MWBase::Environment::get().getWorld()->getInterior(cellID);
|
||||||
|
}
|
||||||
|
catch(std::exception &e)
|
||||||
|
{
|
||||||
|
const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID);
|
||||||
|
if(cell)
|
||||||
|
{
|
||||||
|
int cx,cy;
|
||||||
|
MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
|
||||||
|
store = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(store)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld()->moveObject(ptr,*store,x,y,z);
|
||||||
|
float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees();
|
||||||
|
float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees();
|
||||||
|
if(ptr.getTypeName() == typeid(ESM::NPC).name())//some morrowind oddity
|
||||||
|
{
|
||||||
|
ax = ax/60.;
|
||||||
|
ay = ay/60.;
|
||||||
|
zRot = zRot/60.;
|
||||||
|
}
|
||||||
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error ("unknown cell");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpPosition : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
|
Interpreter::Type_Float x = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float y = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float z = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float zRot = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
int cx,cy;
|
||||||
|
MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
|
||||||
|
MWBase::Environment::get().getWorld()->moveObject(ptr,
|
||||||
|
*MWBase::Environment::get().getWorld()->getExterior(cx,cy),x,y,z);
|
||||||
|
float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees();
|
||||||
|
float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees();
|
||||||
|
if(ptr.getTypeName() == typeid(ESM::NPC).name())//some morrowind oddity
|
||||||
|
{
|
||||||
|
ax = ax/60.;
|
||||||
|
ay = ay/60.;
|
||||||
|
zRot = zRot/60.;
|
||||||
|
}
|
||||||
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpPlaceItemCell : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
std::string itemID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
std::string cellID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
Interpreter::Type_Float x = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float y = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float z = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float zRot = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
MWWorld::CellStore* store = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
store = MWBase::Environment::get().getWorld()->getInterior(cellID);
|
||||||
|
}
|
||||||
|
catch(std::exception &e)
|
||||||
|
{
|
||||||
|
const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID);
|
||||||
|
if(cell)
|
||||||
|
{
|
||||||
|
int cx,cy;
|
||||||
|
MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
|
||||||
|
store = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(store)
|
||||||
|
{
|
||||||
|
ESM::Position pos;
|
||||||
|
pos.pos[0] = x;
|
||||||
|
pos.pos[1] = y;
|
||||||
|
pos.pos[2] = z;
|
||||||
|
pos.rot[0] = pos.rot[1] = 0;
|
||||||
|
pos.rot[2] = zRot;
|
||||||
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
|
||||||
|
ref.getPtr().getCellRef().mPos = pos;
|
||||||
|
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),*store,pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error ("unknown cell");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpPlaceItem : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
std::string itemID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
Interpreter::Type_Float x = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float y = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float z = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float zRot = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
int cx,cy;
|
||||||
|
MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
|
||||||
|
MWWorld::CellStore* store = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
|
||||||
|
if(store)
|
||||||
|
{
|
||||||
|
ESM::Position pos;
|
||||||
|
pos.pos[0] = x;
|
||||||
|
pos.pos[1] = y;
|
||||||
|
pos.pos[2] = z;
|
||||||
|
pos.rot[0] = pos.rot[1] = 0;
|
||||||
|
pos.rot[2] = zRot;
|
||||||
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
|
||||||
|
ref.getPtr().getCellRef().mPos = pos;
|
||||||
|
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),*store,pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error ("unknown cell");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpPlaceAtPc : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
std::string itemID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
Interpreter::Type_Integer count = runtime[0].mInteger;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float distance = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Integer direction = runtime[0].mInteger;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
ESM::Position ipos = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getRefData().getPosition();
|
||||||
|
Ogre::Vector3 pos(ipos.pos[0],ipos.pos[1],ipos.pos[2]);
|
||||||
|
Ogre::Quaternion rot(Ogre::Radian(ipos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||||
|
if(direction == 0) pos = pos + distance*rot.yAxis();
|
||||||
|
else if(direction == 1) pos = pos - distance*rot.yAxis();
|
||||||
|
else if(direction == 2) pos = pos - distance*rot.xAxis();
|
||||||
|
else if(direction == 3) pos = pos + distance*rot.xAxis();
|
||||||
|
else throw std::runtime_error ("direction must be 0,1,2 or 3");
|
||||||
|
|
||||||
|
ipos.pos[0] = pos.x;
|
||||||
|
ipos.pos[1] = pos.y;
|
||||||
|
ipos.pos[2] = pos.z;
|
||||||
|
ipos.rot[0] = 0;
|
||||||
|
ipos.rot[1] = 0;
|
||||||
|
ipos.rot[2] = 0;
|
||||||
|
|
||||||
|
MWWorld::CellStore* store = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell();
|
||||||
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
|
||||||
|
ref.getPtr().getCellRef().mPos = ipos;
|
||||||
|
ref.getPtr().getRefData().setCount(count);
|
||||||
|
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),*store,ipos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class OpPlaceAtMe : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr me = R()(runtime);
|
||||||
|
|
||||||
|
std::string itemID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
Interpreter::Type_Integer count = runtime[0].mInteger;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Float distance = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
Interpreter::Type_Integer direction = runtime[0].mInteger;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
ESM::Position ipos = me.getRefData().getPosition();
|
||||||
|
Ogre::Vector3 pos(ipos.pos[0],ipos.pos[1],ipos.pos[2]);
|
||||||
|
Ogre::Quaternion rot(Ogre::Radian(ipos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||||
|
if(direction == 0) pos = pos + distance*rot.yAxis();
|
||||||
|
else if(direction == 1) pos = pos - distance*rot.yAxis();
|
||||||
|
else if(direction == 2) pos = pos - distance*rot.xAxis();
|
||||||
|
else if(direction == 3) pos = pos + distance*rot.xAxis();
|
||||||
|
else throw std::runtime_error ("direction must be 0,1,2 or 3");
|
||||||
|
|
||||||
|
ipos.pos[0] = pos.x;
|
||||||
|
ipos.pos[1] = pos.y;
|
||||||
|
ipos.pos[2] = pos.z;
|
||||||
|
ipos.rot[0] = 0;
|
||||||
|
ipos.rot[1] = 0;
|
||||||
|
ipos.rot[2] = 0;
|
||||||
|
|
||||||
|
MWWorld::CellStore* store = me.getCell();
|
||||||
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
|
||||||
|
ref.getPtr().getCellRef().mPos = ipos;
|
||||||
|
ref.getPtr().getRefData().setCount(count);
|
||||||
|
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),*store,ipos);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const int opcodeSetScale = 0x2000164;
|
const int opcodeSetScale = 0x2000164;
|
||||||
const int opcodeSetScaleExplicit = 0x2000165;
|
const int opcodeSetScaleExplicit = 0x2000165;
|
||||||
const int opcodeSetAngle = 0x2000166;
|
const int opcodeSetAngle = 0x2000166;
|
||||||
|
@ -149,8 +516,22 @@ namespace MWScript
|
||||||
const int opcodeGetScaleExplicit = 0x2000169;
|
const int opcodeGetScaleExplicit = 0x2000169;
|
||||||
const int opcodeGetAngle = 0x200016a;
|
const int opcodeGetAngle = 0x200016a;
|
||||||
const int opcodeGetAngleExplicit = 0x200016b;
|
const int opcodeGetAngleExplicit = 0x200016b;
|
||||||
const int opcodeGetStartingAngle = 0x2000172;
|
const int opcodeGetPos = 0x2000190;
|
||||||
const int opcodeGetStartingAngleExplicit = 0x2000173;
|
const int opcodeGetPosExplicit = 0x2000191;
|
||||||
|
const int opcodeSetPos = 0x2000192;
|
||||||
|
const int opcodeSetPosExplicit = 0x2000193;
|
||||||
|
const int opcodeGetStartingPos = 0x2000194;
|
||||||
|
const int opcodeGetStartingPosExplicit = 0x2000195;
|
||||||
|
const int opcodePosition = 0x2000196;
|
||||||
|
const int opcodePositionExplicit = 0x2000197;
|
||||||
|
const int opcodePositionCell = 0x2000198;
|
||||||
|
const int opcodePositionCellExplicit = 0x2000199;
|
||||||
|
|
||||||
|
const int opcodePlaceItemCell = 0x200019a;
|
||||||
|
const int opcodePlaceItem = 0x200019b;
|
||||||
|
const int opcodePlaceAtPc = 0x200019c;
|
||||||
|
const int opcodePlaceAtMe = 0x200019d;
|
||||||
|
const int opcodePlaceAtMeExplicit = 0x200019e;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
@ -158,7 +539,15 @@ namespace MWScript
|
||||||
extensions.registerFunction("getscale",'f',"",opcodeGetScale,opcodeGetScaleExplicit);
|
extensions.registerFunction("getscale",'f',"",opcodeGetScale,opcodeGetScaleExplicit);
|
||||||
extensions.registerInstruction("setangle","cf",opcodeSetAngle,opcodeSetAngleExplicit);
|
extensions.registerInstruction("setangle","cf",opcodeSetAngle,opcodeSetAngleExplicit);
|
||||||
extensions.registerFunction("getangle",'f',"c",opcodeGetAngle,opcodeGetAngleExplicit);
|
extensions.registerFunction("getangle",'f',"c",opcodeGetAngle,opcodeGetAngleExplicit);
|
||||||
extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit);
|
extensions.registerInstruction("setpos","cf",opcodeSetPos,opcodeSetPosExplicit);
|
||||||
|
extensions.registerFunction("getpos",'f',"c",opcodeGetPos,opcodeGetPosExplicit);
|
||||||
|
extensions.registerFunction("getstartingpos",'f',"c",opcodeGetStartingPos,opcodeGetStartingPosExplicit);
|
||||||
|
extensions.registerInstruction("position","ffff",opcodePosition,opcodePositionExplicit);
|
||||||
|
extensions.registerInstruction("positioncell","ffffc",opcodePositionCell,opcodePositionCellExplicit);
|
||||||
|
extensions.registerInstruction("placeitemcell","ccffff",opcodePlaceItemCell);
|
||||||
|
extensions.registerInstruction("placeitem","cffff",opcodePlaceItem);
|
||||||
|
extensions.registerInstruction("placeatpc","clfl",opcodePlaceAtPc);
|
||||||
|
extensions.registerInstruction("placeatme","clfl",opcodePlaceAtMe,opcodePlaceAtMeExplicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -171,8 +560,21 @@ namespace MWScript
|
||||||
interpreter.installSegment5(opcodeGetScaleExplicit,new OpGetScale<ExplicitRef>);
|
interpreter.installSegment5(opcodeGetScaleExplicit,new OpGetScale<ExplicitRef>);
|
||||||
interpreter.installSegment5(opcodeGetAngle,new OpGetAngle<ImplicitRef>);
|
interpreter.installSegment5(opcodeGetAngle,new OpGetAngle<ImplicitRef>);
|
||||||
interpreter.installSegment5(opcodeGetAngleExplicit,new OpGetAngle<ExplicitRef>);
|
interpreter.installSegment5(opcodeGetAngleExplicit,new OpGetAngle<ExplicitRef>);
|
||||||
interpreter.installSegment5(opcodeGetStartingAngle,new OpGetStartingAngle<ImplicitRef>);
|
interpreter.installSegment5(opcodeGetPos,new OpGetPos<ImplicitRef>);
|
||||||
interpreter.installSegment5(opcodeGetStartingAngleExplicit,new OpGetStartingAngle<ExplicitRef>);
|
interpreter.installSegment5(opcodeGetPosExplicit,new OpGetPos<ExplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodeSetPos,new OpSetPos<ImplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodeSetPosExplicit,new OpSetPos<ExplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodeGetStartingPos,new OpGetStartingPos<ImplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodeGetStartingPosExplicit,new OpGetStartingPos<ExplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodePosition,new OpPosition<ImplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodePositionExplicit,new OpPosition<ExplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodePositionCell,new OpPositionCell<ImplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodePositionCellExplicit,new OpPositionCell<ExplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodePlaceItemCell,new OpPlaceItemCell<ImplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodePlaceItem,new OpPlaceItem<ImplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodePlaceAtPc,new OpPlaceAtPc<ImplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodePlaceAtMe,new OpPlaceAtMe<ImplicitRef>);
|
||||||
|
interpreter.installSegment5(opcodePlaceAtMeExplicit,new OpPlaceAtMe<ExplicitRef>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,18 @@
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/player.hpp"
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
#include "../mwgui/bookwindow.hpp"
|
#include "../mwgui/bookwindow.hpp"
|
||||||
#include "../mwgui/scrollwindow.hpp"
|
#include "../mwgui/scrollwindow.hpp"
|
||||||
|
|
||||||
|
#include <components/esm_store/store.hpp>
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
ActionRead::ActionRead (const MWWorld::Ptr& object) : Action (false, object)
|
ActionRead::ActionRead (const MWWorld::Ptr& object) : Action (false, object)
|
||||||
|
@ -26,5 +34,23 @@ namespace MWWorld
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Book);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Book);
|
||||||
MWBase::Environment::get().getWindowManager()->getBookWindow()->open(getTarget());
|
MWBase::Environment::get().getWindowManager()->getBookWindow()->open(getTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Skill gain from books
|
||||||
|
if (ref->base->data.skillID >= 0 && ref->base->data.skillID < ESM::Skill::Length)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
|
||||||
|
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
MWWorld::LiveCellRef<ESM::NPC> *playerRef = player.get<ESM::NPC>();
|
||||||
|
const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find (
|
||||||
|
playerRef->base->cls);
|
||||||
|
|
||||||
|
npcStats.increaseSkill (ref->base->data.skillID, *class_, true);
|
||||||
|
|
||||||
|
/// \todo Remove skill from the book. Right now you can read as many times as you want
|
||||||
|
/// and the skill will still increase.
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,10 @@ namespace MWWorld
|
||||||
if(hasWater){
|
if(hasWater){
|
||||||
playerphysics->waterHeight = waterHeight;
|
playerphysics->waterHeight = waterHeight;
|
||||||
}
|
}
|
||||||
|
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
||||||
|
{
|
||||||
|
it->second->setCurrentWater(hasWater, waterHeight);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,18 +176,21 @@ namespace MWWorld
|
||||||
//set the DebugRenderingMode. To disable it,set it to 0
|
//set the DebugRenderingMode. To disable it,set it to 0
|
||||||
//eng->setDebugRenderingMode(1);
|
//eng->setDebugRenderingMode(1);
|
||||||
|
|
||||||
//set the walkdirection to 0 (no movement) for every actor)
|
//set the movement keys to 0 (no movement) for every actor)
|
||||||
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
||||||
{
|
{
|
||||||
OEngine::Physic::PhysicActor* act = it->second;
|
OEngine::Physic::PhysicActor* act = it->second;
|
||||||
act->setWalkDirection(btVector3(0,0,0));
|
act->setMovement(0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerMove::playercmd& pm_ref = playerphysics->cmd;
|
playerMove::playercmd& pm_ref = playerphysics->cmd;
|
||||||
|
|
||||||
|
|
||||||
pm_ref.rightmove = 0;
|
pm_ref.rightmove = 0;
|
||||||
pm_ref.forwardmove = 0;
|
pm_ref.forwardmove = 0;
|
||||||
pm_ref.upmove = 0;
|
pm_ref.upmove = 0;
|
||||||
|
|
||||||
|
|
||||||
//playerphysics->ps.move_type = PM_NOCLIP;
|
//playerphysics->ps.move_type = PM_NOCLIP;
|
||||||
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
|
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
|
||||||
iter!=actors.end(); ++iter)
|
iter!=actors.end(); ++iter)
|
||||||
|
@ -193,10 +200,12 @@ namespace MWWorld
|
||||||
playerphysics->ps.viewangles.x =
|
playerphysics->ps.viewangles.x =
|
||||||
Ogre::Radian(mPlayerData.pitch).valueDegrees();
|
Ogre::Radian(mPlayerData.pitch).valueDegrees();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
playerphysics->ps.viewangles.y =
|
playerphysics->ps.viewangles.y =
|
||||||
Ogre::Radian(mPlayerData.yaw).valueDegrees() + 90;
|
Ogre::Radian(mPlayerData.yaw).valueDegrees() + 90;
|
||||||
|
|
||||||
pm_ref.rightmove = -iter->second.x;
|
pm_ref.rightmove = iter->second.x;
|
||||||
pm_ref.forwardmove = -iter->second.y;
|
pm_ref.forwardmove = -iter->second.y;
|
||||||
pm_ref.upmove = iter->second.z;
|
pm_ref.upmove = iter->second.z;
|
||||||
}
|
}
|
||||||
|
@ -209,15 +218,16 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
Pmove(playerphysics);
|
Pmove(playerphysics);
|
||||||
|
|
||||||
|
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> > response;
|
std::vector< std::pair<std::string, Ogre::Vector3> > response;
|
||||||
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
||||||
{
|
{
|
||||||
btVector3 newPos = it->second->getPosition();
|
|
||||||
|
|
||||||
Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
|
Ogre::Vector3 coord = it->second->getPosition();
|
||||||
if(it->first == "player"){
|
if(it->first == "player"){
|
||||||
|
|
||||||
coord = playerphysics->ps.origin ;
|
coord = playerphysics->ps.origin ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -243,21 +253,15 @@ namespace MWWorld
|
||||||
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
|
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
|
||||||
{
|
{
|
||||||
handleToMesh[handle] = mesh;
|
handleToMesh[handle] = mesh;
|
||||||
OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale);
|
OEngine::Physic::RigidBody* body = mEngine->createAndAdjustRigidBody(mesh,handle,scale, position, rotation);
|
||||||
mEngine->addRigidBody(body);
|
mEngine->addRigidBody(body);
|
||||||
btTransform tr;
|
|
||||||
tr.setOrigin(btVector3(position.x,position.y,position.z));
|
|
||||||
tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w));
|
|
||||||
body->setWorldTransform(tr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::addActor (const std::string& handle, const std::string& mesh,
|
void PhysicsSystem::addActor (const std::string& handle, const std::string& mesh,
|
||||||
const Ogre::Vector3& position)
|
const Ogre::Vector3& position, float scale, const Ogre::Quaternion& rotation)
|
||||||
{
|
{
|
||||||
//TODO:optimize this. Searching the std::map isn't very efficient i think.
|
//TODO:optimize this. Searching the std::map isn't very efficient i think.
|
||||||
mEngine->addCharacter(handle);
|
mEngine->addCharacter(handle, mesh, position, scale, rotation);
|
||||||
OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle);
|
|
||||||
act->setPosition(btVector3(position.x,position.y,position.z));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::removeObject (const std::string& handle)
|
void PhysicsSystem::removeObject (const std::string& handle)
|
||||||
|
@ -268,16 +272,26 @@ namespace MWWorld
|
||||||
mEngine->deleteRigidBody(handle);
|
mEngine->deleteRigidBody(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::moveObject (const std::string& handle, const Ogre::Vector3& position)
|
void PhysicsSystem::moveObject (const std::string& handle, Ogre::SceneNode* node)
|
||||||
{
|
{
|
||||||
|
Ogre::Vector3 position = node->getPosition();
|
||||||
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
|
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
|
||||||
{
|
{
|
||||||
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
|
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
|
||||||
// start positions others than 0, 0, 0
|
// start positions others than 0, 0, 0
|
||||||
|
|
||||||
|
|
||||||
|
if(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL){
|
||||||
btTransform tr = body->getWorldTransform();
|
btTransform tr = body->getWorldTransform();
|
||||||
tr.setOrigin(btVector3(position.x,position.y,position.z));
|
tr.setOrigin(btVector3(position.x,position.y,position.z));
|
||||||
body->setWorldTransform(tr);
|
body->setWorldTransform(tr);
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
//For objects that contain a box shape.
|
||||||
|
//Do any such objects exist? Perhaps animated objects?
|
||||||
|
mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, position, node->getOrientation());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
|
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
|
||||||
{
|
{
|
||||||
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
|
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
|
||||||
|
@ -288,34 +302,45 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
act->setPosition(btVector3(position.x,position.y,position.z));
|
act->setPosition(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation)
|
void PhysicsSystem::rotateObject (const std::string& handle, Ogre::SceneNode* node)
|
||||||
{
|
{
|
||||||
|
Ogre::Quaternion rotation = node->getOrientation();
|
||||||
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
|
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
|
||||||
{
|
{
|
||||||
act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
|
//Needs to be changed
|
||||||
|
act->setRotation(rotation);
|
||||||
}
|
}
|
||||||
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
|
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
|
||||||
{
|
{
|
||||||
|
if(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL)
|
||||||
body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
|
body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
|
||||||
|
else
|
||||||
|
mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::scaleObject (const std::string& handle, float scale)
|
void PhysicsSystem::scaleObject (const std::string& handle, Ogre::SceneNode* node)
|
||||||
{
|
{
|
||||||
if(handleToMesh.find(handle) != handleToMesh.end())
|
if(handleToMesh.find(handle) != handleToMesh.end())
|
||||||
{
|
{
|
||||||
btTransform transform = mEngine->getRigidBody(handle)->getWorldTransform();
|
|
||||||
removeObject(handle);
|
removeObject(handle);
|
||||||
|
|
||||||
Ogre::Quaternion quat = Ogre::Quaternion(transform.getRotation().getW(), transform.getRotation().getX(), transform.getRotation().getY(), transform.getRotation().getZ());
|
float scale = node->getScale().x;
|
||||||
Ogre::Vector3 vec = Ogre::Vector3(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ());
|
Ogre::Quaternion quat = node->getOrientation();
|
||||||
|
Ogre::Vector3 vec = node->getPosition();
|
||||||
addObject(handle, handleToMesh[handle], quat, scale, vec);
|
addObject(handle, handleToMesh[handle], quat, scale, vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
|
||||||
|
{
|
||||||
|
float scale = node->getScale().x;
|
||||||
|
act->setScale(scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsSystem::toggleCollisionMode()
|
bool PhysicsSystem::toggleCollisionMode()
|
||||||
|
@ -335,8 +360,6 @@ namespace MWWorld
|
||||||
if(cmode)
|
if(cmode)
|
||||||
{
|
{
|
||||||
act->enableCollisions(false);
|
act->enableCollisions(false);
|
||||||
act->setGravity(0.);
|
|
||||||
act->setVerticalVelocity(0);
|
|
||||||
mFreeFly = true;
|
mFreeFly = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -344,8 +367,6 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
mFreeFly = false;
|
mFreeFly = false;
|
||||||
act->enableCollisions(true);
|
act->enableCollisions(true);
|
||||||
act->setGravity(4.);
|
|
||||||
act->setVerticalVelocity(0);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,7 +389,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){
|
void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){
|
||||||
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
|
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
|
||||||
addActor (node->getName(), model, node->getPosition());
|
addActor (node->getName(), model, node->getPosition(), node->getScale().x, node->getOrientation());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsSystem::getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max)
|
bool PhysicsSystem::getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max)
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace MWWorld
|
||||||
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
|
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
|
||||||
|
|
||||||
void addActor (const std::string& handle, const std::string& mesh,
|
void addActor (const std::string& handle, const std::string& mesh,
|
||||||
const Ogre::Vector3& position);
|
const Ogre::Vector3& position, float scale, const Ogre::Quaternion& rotation);
|
||||||
|
|
||||||
void addHeightField (float* heights,
|
void addHeightField (float* heights,
|
||||||
int x, int y, float yoffset,
|
int x, int y, float yoffset,
|
||||||
|
@ -34,11 +34,11 @@ namespace MWWorld
|
||||||
|
|
||||||
void removeObject (const std::string& handle);
|
void removeObject (const std::string& handle);
|
||||||
|
|
||||||
void moveObject (const std::string& handle, const Ogre::Vector3& position);
|
void moveObject (const std::string& handle, Ogre::SceneNode* node);
|
||||||
|
|
||||||
void rotateObject (const std::string& handle, const Ogre::Quaternion& rotation);
|
void rotateObject (const std::string& handle, Ogre::SceneNode* node);
|
||||||
|
|
||||||
void scaleObject (const std::string& handle, float scale);
|
void scaleObject (const std::string& handle, Ogre::SceneNode* node);
|
||||||
|
|
||||||
bool toggleCollisionMode();
|
bool toggleCollisionMode();
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,9 @@ namespace MWWorld
|
||||||
mPlayer = new MWWorld::Player (mStore.npcs.find ("player"), *this);
|
mPlayer = new MWWorld::Player (mStore.npcs.find ("player"), *this);
|
||||||
mRendering->attachCameraTo(mPlayer->getPlayer());
|
mRendering->attachCameraTo(mPlayer->getPlayer());
|
||||||
|
|
||||||
mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0));
|
std::string playerCollisionFile = "meshes\\base_anim.nif"; //This is used to make a collision shape for our player
|
||||||
|
//We will need to support the 1st person file too in the future
|
||||||
|
mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), playerCollisionFile, Ogre::Vector3 (0, 0, 0), 1, Ogre::Quaternion::ZERO);
|
||||||
|
|
||||||
// global variables
|
// global variables
|
||||||
mGlobalVariables = new Globals (mStore);
|
mGlobalVariables = new Globals (mStore);
|
||||||
|
@ -450,6 +452,16 @@ namespace MWWorld
|
||||||
mRendering->skySetDate (mGlobalVariables->getInt ("day"), month);
|
mRendering->skySetDate (mGlobalVariables->getInt ("day"), month);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int World::getDay()
|
||||||
|
{
|
||||||
|
return mGlobalVariables->getInt("day");
|
||||||
|
}
|
||||||
|
|
||||||
|
int World::getMonth()
|
||||||
|
{
|
||||||
|
return mGlobalVariables->getInt("month");
|
||||||
|
}
|
||||||
|
|
||||||
TimeStamp World::getTimeStamp() const
|
TimeStamp World::getTimeStamp() const
|
||||||
{
|
{
|
||||||
return TimeStamp (mGlobalVariables->getFloat ("gamehour"),
|
return TimeStamp (mGlobalVariables->getFloat ("gamehour"),
|
||||||
|
@ -541,6 +553,16 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string toLower (const std::string& name)
|
||||||
|
{
|
||||||
|
std::string lowerCase;
|
||||||
|
|
||||||
|
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
|
||||||
|
(int(*)(int)) std::tolower);
|
||||||
|
|
||||||
|
return lowerCase;
|
||||||
|
}
|
||||||
|
|
||||||
void World::moveObject(const Ptr &ptr, CellStore &newCell, float x, float y, float z)
|
void World::moveObject(const Ptr &ptr, CellStore &newCell, float x, float y, float z)
|
||||||
{
|
{
|
||||||
ESM::Position &pos = ptr.getRefData().getPosition();
|
ESM::Position &pos = ptr.getRefData().getPosition();
|
||||||
|
@ -550,11 +572,10 @@ namespace MWWorld
|
||||||
CellStore *currCell = ptr.getCell();
|
CellStore *currCell = ptr.getCell();
|
||||||
bool isPlayer = ptr == mPlayer->getPlayer();
|
bool isPlayer = ptr == mPlayer->getPlayer();
|
||||||
bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer;
|
bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer;
|
||||||
|
|
||||||
if (*currCell != newCell) {
|
if (*currCell != newCell) {
|
||||||
if (isPlayer) {
|
if (isPlayer) {
|
||||||
if (!newCell.isExterior()) {
|
if (!newCell.isExterior()) {
|
||||||
changeToInteriorCell(newCell.cell->mName, pos);
|
changeToInteriorCell(toLower(newCell.cell->mName), pos);
|
||||||
} else {
|
} else {
|
||||||
int cellX = newCell.cell->mData.mX;
|
int cellX = newCell.cell->mData.mX;
|
||||||
int cellY = newCell.cell->mData.mY;
|
int cellY = newCell.cell->mData.mY;
|
||||||
|
@ -594,7 +615,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
if (haveToMove) {
|
if (haveToMove) {
|
||||||
mRendering->moveObject(ptr, vec);
|
mRendering->moveObject(ptr, vec);
|
||||||
mPhysics->moveObject(ptr.getRefData().getHandle(), vec);
|
mPhysics->moveObject (ptr.getRefData().getHandle(), ptr.getRefData().getBaseNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,6 +636,8 @@ namespace MWWorld
|
||||||
void World::moveObject (const Ptr& ptr, float x, float y, float z)
|
void World::moveObject (const Ptr& ptr, float x, float y, float z)
|
||||||
{
|
{
|
||||||
moveObjectImp(ptr, x, y, z);
|
moveObjectImp(ptr, x, y, z);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::scaleObject (const Ptr& ptr, float scale)
|
void World::scaleObject (const Ptr& ptr, float scale)
|
||||||
|
@ -624,7 +647,7 @@ namespace MWWorld
|
||||||
ptr.getCellRef().mScale = scale;
|
ptr.getCellRef().mScale = scale;
|
||||||
//scale = scale/ptr.getRefData().getBaseNode()->getScale().x;
|
//scale = scale/ptr.getRefData().getBaseNode()->getScale().x;
|
||||||
ptr.getRefData().getBaseNode()->setScale(scale,scale,scale);
|
ptr.getRefData().getBaseNode()->setScale(scale,scale,scale);
|
||||||
mPhysics->scaleObject( ptr.getRefData().getHandle(), scale );
|
mPhysics->scaleObject( ptr.getRefData().getHandle(), ptr.getRefData().getBaseNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
|
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
|
||||||
|
@ -638,13 +661,20 @@ namespace MWWorld
|
||||||
float *objRot = ptr.getRefData().getPosition().rot;
|
float *objRot = ptr.getRefData().getPosition().rot;
|
||||||
objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
|
objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
|
||||||
|
|
||||||
|
|
||||||
if (ptr.getRefData().getBaseNode() != 0) {
|
if (ptr.getRefData().getBaseNode() != 0) {
|
||||||
mPhysics->rotateObject(
|
mPhysics->rotateObject(
|
||||||
ptr.getRefData().getHandle(),
|
ptr.getRefData().getHandle(),
|
||||||
ptr.getRefData().getBaseNode()->getOrientation()
|
ptr.getRefData().getBaseNode()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)
|
||||||
|
{
|
||||||
|
copyObjectToCell(ptr,Cell,pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const
|
void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const
|
||||||
|
@ -1223,8 +1253,37 @@ namespace MWWorld
|
||||||
mRendering->renderPlayer(mPlayer->getPlayer());
|
mRendering->renderPlayer(mPlayer->getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::renderGlobalMap ()
|
||||||
|
{
|
||||||
|
mRendering->renderGlobalMap ();
|
||||||
|
}
|
||||||
|
|
||||||
void World::setupExternalRendering (MWRender::ExternalRendering& rendering)
|
void World::setupExternalRendering (MWRender::ExternalRendering& rendering)
|
||||||
{
|
{
|
||||||
mRendering->setupExternalRendering (rendering);
|
mRendering->setupExternalRendering (rendering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int World::canRest ()
|
||||||
|
{
|
||||||
|
Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
|
||||||
|
|
||||||
|
Ogre::Vector3 playerPos;
|
||||||
|
float* pos = mPlayer->getPlayer ().getRefData ().getPosition ().pos;
|
||||||
|
playerPos.x = pos[0];
|
||||||
|
playerPos.y = pos[1];
|
||||||
|
playerPos.z = pos[2];
|
||||||
|
|
||||||
|
std::pair<bool, Ogre::Vector3> hit =
|
||||||
|
mPhysics->castRay(playerPos, Ogre::Vector3(0,0,-1), 50);
|
||||||
|
bool isOnGround = (hit.first ? (hit.second.distance (playerPos) < 25) : false);
|
||||||
|
|
||||||
|
if (!isOnGround || isUnderwater (*currentCell->cell, playerPos))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
if (currentCell->cell->mData.mFlags & ESM::Cell::NoSleep)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,6 +179,9 @@ namespace MWWorld
|
||||||
virtual void setDay (int day);
|
virtual void setDay (int day);
|
||||||
///< Set in-game time day.
|
///< Set in-game time day.
|
||||||
|
|
||||||
|
virtual int getDay();
|
||||||
|
virtual int getMonth();
|
||||||
|
|
||||||
virtual TimeStamp getTimeStamp() const;
|
virtual TimeStamp getTimeStamp() const;
|
||||||
///< Return current in-game time stamp.
|
///< Return current in-game time stamp.
|
||||||
|
|
||||||
|
@ -223,6 +226,9 @@ namespace MWWorld
|
||||||
/// \param adjust indicates rotation should be set or adjusted
|
/// \param adjust indicates rotation should be set or adjusted
|
||||||
virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false);
|
virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false);
|
||||||
|
|
||||||
|
virtual void safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos);
|
||||||
|
///< place an object in a "safe" location (ie not in the void, etc). Makes a copy of the Ptr.
|
||||||
|
|
||||||
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
|
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
|
||||||
const;
|
const;
|
||||||
///< Convert cell numbers to position.
|
///< Convert cell numbers to position.
|
||||||
|
@ -307,8 +313,16 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void renderPlayer();
|
virtual void renderPlayer();
|
||||||
|
virtual void renderGlobalMap();
|
||||||
|
|
||||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
||||||
|
|
||||||
|
virtual int canRest();
|
||||||
|
///< check if the player is allowed to rest \n
|
||||||
|
/// 0 - yes \n
|
||||||
|
/// 1 - only waiting \n
|
||||||
|
/// 2 - player is underwater \n
|
||||||
|
/// 3 - enemies are nearby (not implemented)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
#include "esm_reader.hpp"
|
#include "esm_reader.hpp"
|
||||||
#include "esm_writer.hpp"
|
#include "esm_writer.hpp"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const int NumberOfHardcodedFlags = 143;
|
const int NumberOfHardcodedFlags = 143;
|
||||||
|
|
|
@ -72,6 +72,9 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
||||||
cShape = static_cast<BulletShape *>(resource);
|
cShape = static_cast<BulletShape *>(resource);
|
||||||
resourceName = cShape->getName();
|
resourceName = cShape->getName();
|
||||||
cShape->collide = false;
|
cShape->collide = false;
|
||||||
|
mBoundingBox = NULL;
|
||||||
|
cShape->boxTranslation = Ogre::Vector3(0,0,0);
|
||||||
|
cShape->boxRotation = Ogre::Quaternion::IDENTITY;
|
||||||
|
|
||||||
mTriMesh = new btTriangleMesh();
|
mTriMesh = new btTriangleMesh();
|
||||||
|
|
||||||
|
@ -125,10 +128,15 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
||||||
delete m_meshInterface;
|
delete m_meshInterface;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if(mBoundingBox != NULL)
|
||||||
|
cShape->Shape = mBoundingBox;
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
currentShape = new TriangleMeshShape(mTriMesh,true);
|
currentShape = new TriangleMeshShape(mTriMesh,true);
|
||||||
cShape->Shape = currentShape;
|
cShape->Shape = currentShape;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node)
|
bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node)
|
||||||
{
|
{
|
||||||
|
@ -218,6 +226,17 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(node->hasBounds)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
btVector3 boxsize = getbtVector((node->boundXYZ));
|
||||||
|
cShape->boxTranslation = node->boundPos;
|
||||||
|
cShape->boxRotation = node->boundRot;
|
||||||
|
|
||||||
|
mBoundingBox = new btBoxShape(boxsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// For NiNodes, loop through children
|
// For NiNodes, loop through children
|
||||||
if (node->recType == Nif::RC_NiNode)
|
if (node->recType == Nif::RC_NiNode)
|
||||||
|
|
|
@ -102,8 +102,11 @@ private:
|
||||||
std::string resourceName;
|
std::string resourceName;
|
||||||
std::string resourceGroup;
|
std::string resourceGroup;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BulletShape* cShape;//current shape
|
BulletShape* cShape;//current shape
|
||||||
btTriangleMesh *mTriMesh;
|
btTriangleMesh *mTriMesh;
|
||||||
|
btBoxShape *mBoundingBox;
|
||||||
btBvhTriangleMeshShape* currentShape;//the shape curently under construction
|
btBvhTriangleMeshShape* currentShape;//the shape curently under construction
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
#define gammaCorrectRead(v) pow(v, float3(gammaCorrection,gammaCorrection,gammaCorrection))
|
||||||
|
#define gammaCorrectOutput(v) pow(v, float3(1.f/gammaCorrection,1.f/gammaCorrection,1.f/gammaCorrection))
|
||||||
|
|
||||||
|
|
||||||
#if SH_HLSL == 1 || SH_CG == 1
|
#if SH_HLSL == 1 || SH_CG == 1
|
||||||
|
|
||||||
#define shTexture2D sampler2D
|
#define shTexture2D sampler2D
|
||||||
|
|
|
@ -112,6 +112,8 @@
|
||||||
shUniform(float, far) @shAutoConstant(far, far_clip_distance)
|
shUniform(float, far) @shAutoConstant(far, far_clip_distance)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection)
|
||||||
|
|
||||||
#if LIGHTING
|
#if LIGHTING
|
||||||
shInput(float3, normalPassthrough)
|
shInput(float3, normalPassthrough)
|
||||||
shInput(float3, objSpacePositionPassthrough)
|
shInput(float3, objSpacePositionPassthrough)
|
||||||
|
@ -173,6 +175,7 @@
|
||||||
SH_START_PROGRAM
|
SH_START_PROGRAM
|
||||||
{
|
{
|
||||||
shOutputColour(0) = shSample(diffuseMap, UV);
|
shOutputColour(0) = shSample(diffuseMap, UV);
|
||||||
|
shOutputColour(0).xyz = gammaCorrectRead(shOutputColour(0).xyz);
|
||||||
|
|
||||||
#if LIGHTING
|
#if LIGHTING
|
||||||
float3 normal = normalize(normalPassthrough);
|
float3 normal = normalize(normalPassthrough);
|
||||||
|
@ -259,7 +262,7 @@
|
||||||
// regular fog only if fragment is above water
|
// regular fog only if fragment is above water
|
||||||
if (worldPos.y > waterLevel)
|
if (worldPos.y > waterLevel)
|
||||||
#endif
|
#endif
|
||||||
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue);
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// prevent negative colour output (for example with negative lights)
|
// prevent negative colour output (for example with negative lights)
|
||||||
|
@ -274,12 +277,11 @@
|
||||||
|
|
||||||
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
|
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
|
||||||
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
|
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
|
||||||
float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5;
|
float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85)) *waterSunGradient * 0.5;
|
||||||
|
|
||||||
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
|
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
|
||||||
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
|
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
|
||||||
float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0;
|
float3 watercolour = ( gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0;
|
||||||
float3 waterext = float3(0.6, 0.9, 1.0);//water extinction
|
|
||||||
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
|
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
|
||||||
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3;
|
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3;
|
||||||
|
|
||||||
|
@ -292,6 +294,8 @@
|
||||||
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled);
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz);
|
||||||
|
|
||||||
#if MRT
|
#if MRT
|
||||||
shOutputColour(1) = float4(depthPassthrough / far,1,1,1);
|
shOutputColour(1) = float4(depthPassthrough / far,1,1,1);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -137,6 +137,8 @@
|
||||||
|
|
||||||
shSampler2D(normalMap) // global normal map
|
shSampler2D(normalMap) // global normal map
|
||||||
|
|
||||||
|
shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection)
|
||||||
|
|
||||||
|
|
||||||
@shForeach(@shPropertyString(num_blendmaps))
|
@shForeach(@shPropertyString(num_blendmaps))
|
||||||
shSampler2D(blendMap@shIterator)
|
shSampler2D(blendMap@shIterator)
|
||||||
|
@ -247,9 +249,9 @@
|
||||||
|
|
||||||
#if IS_FIRST_PASS == 1 && @shIterator == 0
|
#if IS_FIRST_PASS == 1 && @shIterator == 0
|
||||||
// first layer of first pass doesn't need a blend map
|
// first layer of first pass doesn't need a blend map
|
||||||
albedo = shSample(diffuseMap0, UV * 10).rgb;
|
albedo = gammaCorrectRead(shSample(diffuseMap0, UV * 10).rgb);
|
||||||
#else
|
#else
|
||||||
albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator));
|
albedo = shLerp(albedo, gammaCorrectRead(shSample(diffuseMap@shIterator, UV * 10).rgb), blendValues@shPropertyString(blendmap_component_@shIterator));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@shEndForeach
|
@shEndForeach
|
||||||
|
@ -336,7 +338,7 @@
|
||||||
// regular fog only if fragment is above water
|
// regular fog only if fragment is above water
|
||||||
if (worldPos.y > waterLevel)
|
if (worldPos.y > waterLevel)
|
||||||
#endif
|
#endif
|
||||||
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue);
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// prevent negative colour output (for example with negative lights)
|
// prevent negative colour output (for example with negative lights)
|
||||||
|
@ -351,12 +353,12 @@
|
||||||
|
|
||||||
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
|
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
|
||||||
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
|
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
|
||||||
float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5;
|
float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85))*waterSunGradient * 0.5;
|
||||||
|
|
||||||
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
|
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
|
||||||
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
|
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
|
||||||
float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0;
|
float3 watercolour = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0;
|
||||||
float3 waterext = float3(0.6, 0.9, 1.0);//water extinction
|
float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction
|
||||||
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
|
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
|
||||||
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3;
|
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3;
|
||||||
|
|
||||||
|
@ -369,6 +371,8 @@
|
||||||
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater);
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz);
|
||||||
|
|
||||||
|
|
||||||
#if MRT
|
#if MRT
|
||||||
shOutputColour(1) = float4(depth / far,1,1,1);
|
shOutputColour(1) = float4(depth / far,1,1,1);
|
||||||
|
|
|
@ -35,7 +35,7 @@ set(MYGUI_FILES
|
||||||
openmw_dialogue_window.layout
|
openmw_dialogue_window.layout
|
||||||
openmw_dialogue_window_skin.xml
|
openmw_dialogue_window_skin.xml
|
||||||
openmw_edit.skin.xml
|
openmw_edit.skin.xml
|
||||||
openmw.font.xml
|
openmw_font.xml
|
||||||
openmw_hud_box.skin.xml
|
openmw_hud_box.skin.xml
|
||||||
openmw_hud_energybar.skin.xml
|
openmw_hud_energybar.skin.xml
|
||||||
openmw_hud.layout
|
openmw_hud.layout
|
||||||
|
@ -51,7 +51,7 @@ set(MYGUI_FILES
|
||||||
openmw_map_window.layout
|
openmw_map_window.layout
|
||||||
openmw_map_window_skin.xml
|
openmw_map_window_skin.xml
|
||||||
openmw_messagebox.layout
|
openmw_messagebox.layout
|
||||||
openmw.pointer.xml
|
openmw_pointer.xml
|
||||||
openmw_progress.skin.xml
|
openmw_progress.skin.xml
|
||||||
openmw_resources.xml
|
openmw_resources.xml
|
||||||
openmw_scroll.layout
|
openmw_scroll.layout
|
||||||
|
@ -72,6 +72,9 @@ set(MYGUI_FILES
|
||||||
openmw_magicselection_dialog.layout
|
openmw_magicselection_dialog.layout
|
||||||
openmw_spell_buying_window.layout
|
openmw_spell_buying_window.layout
|
||||||
openmw_loading_screen.layout
|
openmw_loading_screen.layout
|
||||||
|
openmw_levelup_dialog.layout
|
||||||
|
openmw_wait_dialog.layout
|
||||||
|
openmw_wait_dialog_progressbar.layout
|
||||||
smallbars.png
|
smallbars.png
|
||||||
VeraMono.ttf
|
VeraMono.ttf
|
||||||
markers.png
|
markers.png
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
<List file="core.skin" />
|
<List file="core.skin" />
|
||||||
<List file="openmw_resources.xml" />
|
<List file="openmw_resources.xml" />
|
||||||
<List file="openmw_layers.xml" />
|
<List file="openmw_layers.xml" />
|
||||||
<List file="openmw.pointer.xml" />
|
<List file="openmw_pointer.xml" />
|
||||||
<List file="openmw.font.xml" />
|
<List file="openmw_font.xml" />
|
||||||
<List file="openmw_text.skin.xml" />
|
<List file="openmw_text.skin.xml" />
|
||||||
<List file="openmw_windows.skin.xml" />
|
<List file="openmw_windows.skin.xml" />
|
||||||
<List file="openmw_button.skin.xml" />
|
<List file="openmw_button.skin.xml" />
|
||||||
|
|
|
@ -77,8 +77,9 @@
|
||||||
|
|
||||||
<!-- Buttons -->
|
<!-- Buttons -->
|
||||||
<Widget type="HBox" skin="" position="160 370 380 24">
|
<Widget type="HBox" skin="" position="160 370 380 24">
|
||||||
<Widget type="Widget"/> <!-- spacer -->
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="CreateButton">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="CreateButton">
|
||||||
<Property key="Caption" value="#{sCreate}"/>
|
<Property key="Caption" value="#{sCreate}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
|
|
||||||
<!-- Dialog buttons -->
|
<!-- Dialog buttons -->
|
||||||
<Widget type="HBox" position="0 340 473 24">
|
<Widget type="HBox" position="0 340 473 24">
|
||||||
<Widget type="Widget"/> <!-- spacer -->
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
|
||||||
<Property key="Caption" value="#{sBack}"/>
|
<Property key="Caption" value="#{sBack}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -61,7 +61,9 @@
|
||||||
|
|
||||||
<!-- Dialog buttons -->
|
<!-- Dialog buttons -->
|
||||||
<Widget type="HBox" position="0 265 476 24">
|
<Widget type="HBox" position="0 265 476 24">
|
||||||
<Widget type="Widget"/> <!-- spacer -->
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
|
||||||
<Property key="Caption" value="#{sBack}"/>
|
<Property key="Caption" value="#{sBack}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -59,7 +59,9 @@
|
||||||
|
|
||||||
<!-- Dialog buttons -->
|
<!-- Dialog buttons -->
|
||||||
<Widget type="HBox" position="0 158 459 24">
|
<Widget type="HBox" position="0 158 459 24">
|
||||||
<Widget type="Widget"/> <!-- spacer -->
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="DescriptionButton">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="DescriptionButton">
|
||||||
<Property key="Caption" value="#{sCreateClassMenu1}"/>
|
<Property key="Caption" value="#{sCreateClassMenu1}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
|
|
||||||
<!-- Dialog buttons -->
|
<!-- Dialog buttons -->
|
||||||
<Widget type="HBox" position="0 219 319 24">
|
<Widget type="HBox" position="0 219 319 24">
|
||||||
<Widget type="Widget"/> <!-- spacer -->
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
|
||||||
<Property key="Caption" value="#{sBack}"/>
|
<Property key="Caption" value="#{sBack}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -57,7 +57,10 @@
|
||||||
|
|
||||||
<!-- Dialog buttons -->
|
<!-- Dialog buttons -->
|
||||||
<Widget type="HBox" position="0 397 574 24">
|
<Widget type="HBox" position="0 397 574 24">
|
||||||
<Widget type="Widget"/>
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" position="471 397 53 23" name="BackButton">
|
<Widget type="AutoSizedButton" skin="MW_Button" position="471 397 53 23" name="BackButton">
|
||||||
<Property key="Caption" value="#{sBack}"/>
|
<Property key="Caption" value="#{sBack}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -112,7 +112,9 @@
|
||||||
|
|
||||||
<!-- Dialog buttons -->
|
<!-- Dialog buttons -->
|
||||||
<Widget type="HBox" position="0 372 502 24">
|
<Widget type="HBox" position="0 372 502 24">
|
||||||
<Widget type="Widget"/>
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
|
||||||
<Property key="Caption" value="#{sBack}"/>
|
<Property key="Caption" value="#{sBack}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<Widget type="HBox" position="0 84 272 24" align="Right Bottom">
|
<Widget type="HBox" position="0 84 272 24" align="Right Bottom">
|
||||||
<Widget type="Widget"/> <!-- spacer -->
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton" align="Right Bottom">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton" align="Right Bottom">
|
||||||
<Property key="Caption" value="#{sCancel}"/>
|
<Property key="Caption" value="#{sCancel}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<Widget type="HBox" position="0 235 580 24" align="Right Bottom">
|
<Widget type="HBox" position="0 235 580 24" align="Right Bottom">
|
||||||
<Widget type="Widget"/>
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="TakeButton" align="Right Bottom">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="TakeButton" align="Right Bottom">
|
||||||
<Property key="Caption" value="#{sTakeAll}"/>
|
<Property key="Caption" value="#{sTakeAll}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
|
|
||||||
|
|
||||||
<Widget type="HBox" position="0 90 572 24" align="Right Bottom">
|
<Widget type="HBox" position="0 90 572 24" align="Right Bottom">
|
||||||
<Widget type="Widget"/> <!-- spacer -->
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" position="417 90 60 24" name="CancelButton" align="Right Top">
|
<Widget type="AutoSizedButton" skin="MW_Button" position="417 90 60 24" name="CancelButton" align="Right Top">
|
||||||
<Property key="Caption" value="#{sCancel}"/>
|
<Property key="Caption" value="#{sCancel}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
138
files/mygui/openmw_levelup_dialog.layout
Normal file
138
files/mygui/openmw_levelup_dialog.layout
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<MyGUI type="Layout">
|
||||||
|
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 440 438" name="_Main">
|
||||||
|
|
||||||
|
<Widget type="Widget" skin="MW_Box" position="28 14 391 198">
|
||||||
|
<Widget type="ImageBox" skin="ImageBox" name="ClassImage" position="4 4 383 190">
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="SandText" position="28 218 391 24" name="LevelText">
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="Widget" skin="" position="36 280 400 400">
|
||||||
|
<Widget type="TextBox" skin="SandText" position="0 0 100 24" name="AttribMultiplier1"/>
|
||||||
|
<Widget type="TextBox" skin="SandText" position="0 24 100 24" name="AttribMultiplier2"/>
|
||||||
|
<Widget type="TextBox" skin="SandText" position="0 48 100 24" name="AttribMultiplier3"/>
|
||||||
|
<Widget type="TextBox" skin="SandText" position="0 72 100 24" name="AttribMultiplier4"/>
|
||||||
|
<Widget type="TextBox" skin="SandText" position="200 0 100 24" name="AttribMultiplier5"/>
|
||||||
|
<Widget type="TextBox" skin="SandText" position="200 24 100 24" name="AttribMultiplier6"/>
|
||||||
|
<Widget type="TextBox" skin="SandText" position="200 48 100 24" name="AttribMultiplier7"/>
|
||||||
|
<Widget type="TextBox" skin="SandText" position="200 72 100 24" name="AttribMultiplier8"/>
|
||||||
|
|
||||||
|
<Widget type="HBox" position="22 0 200 24">
|
||||||
|
<Widget type="AutoSizedButton" skin="SandTextButton" name="Attrib1">
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||||
|
<UserString key="Caption_AttributeName" value="#{sAttributeStrength}"/>
|
||||||
|
<UserString key="Caption_AttributeDescription" value="#{sStrDesc}"/>
|
||||||
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_strength.dds"/>
|
||||||
|
<Property key="Caption" value="#{sAttributeStrength}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal1">
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="HBox" position="22 24 200 24">
|
||||||
|
<Widget type="AutoSizedButton" skin="SandTextButton" name="Attrib2">
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||||
|
<UserString key="Caption_AttributeName" value="#{sAttributeIntelligence}"/>
|
||||||
|
<UserString key="Caption_AttributeDescription" value="#{sIntDesc}"/>
|
||||||
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_int.dds"/>
|
||||||
|
<Property key="Caption" value="#{sAttributeIntelligence}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal2">
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="HBox" position="22 48 200 24">
|
||||||
|
<Widget type="AutoSizedButton" skin="SandTextButton" name="Attrib3">
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||||
|
<UserString key="Caption_AttributeName" value="#{sAttributeWillpower}"/>
|
||||||
|
<UserString key="Caption_AttributeDescription" value="#{sWilDesc}"/>
|
||||||
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_wilpower.dds"/>
|
||||||
|
<Property key="Caption" value="#{sAttributeWillpower}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal3">
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="HBox" position="22 72 200 24">
|
||||||
|
<Widget type="AutoSizedButton" skin="SandTextButton" name="Attrib4">
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||||
|
<UserString key="Caption_AttributeName" value="#{sAttributeAgility}"/>
|
||||||
|
<UserString key="Caption_AttributeDescription" value="#{sAgiDesc}"/>
|
||||||
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_agility.dds"/>
|
||||||
|
<Property key="Caption" value="#{sAttributeAgility}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal4">
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
|
||||||
|
<Widget type="HBox" position="222 0 200 24">
|
||||||
|
<Widget type="AutoSizedButton" skin="SandTextButton" name="Attrib5">
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||||
|
<UserString key="Caption_AttributeName" value="#{sAttributeSpeed}"/>
|
||||||
|
<UserString key="Caption_AttributeDescription" value="#{sSpdDesc}"/>
|
||||||
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_speed.dds"/>
|
||||||
|
<Property key="Caption" value="#{sAttributeSpeed}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal5">
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="HBox" position="222 24 200 24">
|
||||||
|
<Widget type="AutoSizedButton" skin="SandTextButton" name="Attrib6">
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||||
|
<UserString key="Caption_AttributeName" value="#{sAttributeEndurance}"/>
|
||||||
|
<UserString key="Caption_AttributeDescription" value="#{sEndDesc}"/>
|
||||||
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_endurance.dds"/>
|
||||||
|
<Property key="Caption" value="#{sAttributeEndurance}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal6">
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="HBox" position="222 48 200 24">
|
||||||
|
<Widget type="AutoSizedButton" skin="SandTextButton" name="Attrib7">
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||||
|
<UserString key="Caption_AttributeName" value="#{sAttributePersonality}"/>
|
||||||
|
<UserString key="Caption_AttributeDescription" value="#{sPerDesc}"/>
|
||||||
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_personality.dds"/>
|
||||||
|
<Property key="Caption" value="#{sAttributePersonality}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal7">
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="HBox" position="222 72 200 24">
|
||||||
|
<Widget type="AutoSizedButton" skin="SandTextButton" name="Attrib8">
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||||
|
<UserString key="Caption_AttributeName" value="#{sAttributeLuck}"/>
|
||||||
|
<UserString key="Caption_AttributeDescription" value="#{sLucDesc}"/>
|
||||||
|
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_luck.dds"/>
|
||||||
|
<Property key="Caption" value="#{sAttributeLuck}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="AttribVal8">
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
|
||||||
|
<Widget type="AutoSizedButton" skin="MW_Button" position="422 398 0 24" name="OkButton">
|
||||||
|
<Property key="ExpandDirection" value="Left"/>
|
||||||
|
<Property key="Caption" value="#{sOk}"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
</MyGUI>
|
|
@ -3,21 +3,32 @@
|
||||||
<MyGUI type="Layout">
|
<MyGUI type="Layout">
|
||||||
<Widget type="Window" skin="MW_Window_Pinnable" layer="Windows" position="0 0 300 300" name="_Main">
|
<Widget type="Window" skin="MW_Window_Pinnable" layer="Windows" position="0 0 300 300" name="_Main">
|
||||||
|
|
||||||
<!-- Global map -->
|
|
||||||
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="GlobalMap">
|
|
||||||
</Widget>
|
|
||||||
|
|
||||||
<!-- Local map -->
|
<!-- Local map -->
|
||||||
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="LocalMap">
|
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="LocalMap">
|
||||||
<Property key="CanvasSize" value="1536 1536"/>
|
<Property key="CanvasSize" value="1536 1536"/>
|
||||||
|
|
||||||
<Widget type="ImageBox" skin="RotatingSkin" position="0 0 32 32" align="ALIGN_TOP ALIGN_LEFT" name="Compass">
|
<Widget type="ImageBox" skin="RotatingSkin" position="0 0 32 32" align="ALIGN_TOP ALIGN_LEFT" name="CompassLocal">
|
||||||
<Property key="ImageTexture" value="textures\compass.dds"/>
|
<Property key="ImageTexture" value="textures\compass.dds"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<Widget type="Button" skin="" position="0 0 1536 1536" name="EventBox" align="ALIGN_STRETCH"/>
|
<Widget type="Button" skin="" position_real="0 0 1 1" name="EventBoxLocal" align="ALIGN_STRETCH"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
<!-- Global map -->
|
||||||
|
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="GlobalMap">
|
||||||
|
<Property key="CanvasSize" value="1536 1536"/>
|
||||||
|
|
||||||
|
<Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Stretch" name="GlobalMapImage">
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="ImageBox" skin="RotatingSkin" position="0 0 32 32" align="ALIGN_TOP ALIGN_LEFT" name="CompassGlobal">
|
||||||
|
<Property key="ImageTexture" value="textures\compass.dds"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="Button" skin="" position_real="0 0 1 1" name="EventBoxGlobal" align="ALIGN_STRETCH"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
|
||||||
<!-- World button -->
|
<!-- World button -->
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" position="213 233 61 22" align="ALIGN_BOTTOM ALIGN_RIGHT" name="WorldButton">
|
<Widget type="AutoSizedButton" skin="MW_Button" position="213 233 61 22" align="ALIGN_BOTTOM ALIGN_RIGHT" name="WorldButton">
|
||||||
<Property key="ExpandDirection" value="Left"/>
|
<Property key="ExpandDirection" value="Left"/>
|
||||||
|
|
|
@ -157,7 +157,7 @@
|
||||||
<Widget type="TabItem" skin="" position="4 28 344 272">
|
<Widget type="TabItem" skin="" position="4 28 344 272">
|
||||||
<Property key="Caption" value=" Video "/>
|
<Property key="Caption" value=" Video "/>
|
||||||
|
|
||||||
<Widget type="ListBox" skin="MW_List" position="4 4 200 150" align="Left Top" name="ResolutionList"/>
|
<Widget type="ListBox" skin="MW_List" position="4 4 200 120" align="Left Top" name="ResolutionList"/>
|
||||||
|
|
||||||
|
|
||||||
<Widget type="HBox" position="212 4 300 24">
|
<Widget type="HBox" position="212 4 300 24">
|
||||||
|
@ -174,20 +174,37 @@
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<Widget type="HBox" position="212 104 300 24">
|
<Widget type="HBox" position="212 64 300 24">
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="ShadersButton"/>
|
<Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="ShadersButton"/>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" align="Left Top">
|
<Widget type="AutoSizedTextBox" skin="SandText" align="Left Top">
|
||||||
<Property key="Caption" value="Shaders"/>
|
<Property key="Caption" value="Shaders"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<Widget type="HBox" position="4 163 300 24">
|
<Widget type="HBox" position="212 94 300 24">
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="FPSButton"/>
|
<Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="FPSButton"/>
|
||||||
<Widget type="AutoSizedTextBox" skin="SandText" align="Left Top">
|
<Widget type="AutoSizedTextBox" skin="SandText" align="Left Top">
|
||||||
<Property key="Caption" value="Show frames per second"/>
|
<Property key="Caption" value="FPS"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="NormalText" position="4 128 329 18" align="Left Top" name="GammaText">
|
||||||
|
<Property key="Caption" value="Gamma"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="ScrollBar" skin="MW_HSlider" position="4 152 329 18" align="Left Top" name="GammaSlider">
|
||||||
|
<Property key="Range" value="1000000"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="TextBox" skin="SandText" position="4 176 329 18" align="Left Top">
|
||||||
|
<Property key="Caption" value="#{sDark_Gamma}"/>
|
||||||
|
<Property key="TextAlign" value="Left"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="TextBox" skin="SandText" position="4 176 329 18" align="Left Top">
|
||||||
|
<Property key="Caption" value="#{sLight_Gamma}"/>
|
||||||
|
<Property key="TextAlign" value="Right"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
|
||||||
<Widget type="TextBox" skin="NormalText" position="4 198 329 18" align="Left Top" name="FovText">
|
<Widget type="TextBox" skin="NormalText" position="4 198 329 18" align="Left Top" name="FovText">
|
||||||
<Property key="Caption" value="Field of View"/>
|
<Property key="Caption" value="Field of View"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -56,7 +56,9 @@
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<Widget type="HBox" position="0 60 566 24" align="Right Bottom">
|
<Widget type="HBox" position="0 60 566 24" align="Right Bottom">
|
||||||
<Widget type="Widget"/>
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="OfferButton" align="Right Top">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="OfferButton" align="Right Top">
|
||||||
<Property key="Caption" value="#{sBarterDialog8}"/>
|
<Property key="Caption" value="#{sBarterDialog8}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
42
files/mygui/openmw_wait_dialog.layout
Normal file
42
files/mygui/openmw_wait_dialog.layout
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<MyGUI type="Layout">
|
||||||
|
<Widget type="VBox" skin="MW_Dialog" layer="Windows" position="0 0 600 200" name="_Main">
|
||||||
|
<Property key="Padding" value="12"/>
|
||||||
|
<Property key="Spacing" value="8"/>
|
||||||
|
<Property key="AutoResize" value="true"/>
|
||||||
|
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="DateTimeText">
|
||||||
|
<Property key="Caption" value="24 Herzfeuer (Tag 24) 2 a.m."/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="RestText">
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="AutoSizedTextBox" skin="SandText" name="HourText">
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="ScrollBar" skin="MW_HScroll" name="HourSlider" position="0 0 0 18">
|
||||||
|
<Property key="MoveToClick" value="true"/>
|
||||||
|
<Property key="Range" value="24"/>
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="HBox">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
<Widget type="Widget">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="AutoSizedButton" skin="MW_Button" name="UntilHealedButton">
|
||||||
|
<Property key="Caption" value="#{sUntilHealed}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedButton" skin="MW_Button" name="WaitButton">
|
||||||
|
<Property key="Caption" value="#{sRest}"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
|
||||||
|
<Property key="Caption" value="#{sCancel}"/>
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
</MyGUI>
|
13
files/mygui/openmw_wait_dialog_progressbar.layout
Normal file
13
files/mygui/openmw_wait_dialog_progressbar.layout
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<MyGUI type="Layout">
|
||||||
|
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 219 40" name="_Main">
|
||||||
|
|
||||||
|
<Widget type="ProgressBar" skin="MW_Progress_Blue" position="5 6 199 20" name="ProgressBar">
|
||||||
|
<Widget type="TextBox" skin="SandText" position="0 0 199 20" name="ProgressText">
|
||||||
|
<Property key="TextAlign" value="Center"/>
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
</Widget>
|
||||||
|
</MyGUI>
|
|
@ -24,6 +24,12 @@ antialiasing = none
|
||||||
|
|
||||||
vsync = false
|
vsync = false
|
||||||
|
|
||||||
|
# opengl render to texture mode, valid options:
|
||||||
|
# PBuffer, FBO, Copy
|
||||||
|
opengl rtt mode = FBO
|
||||||
|
|
||||||
|
gamma = 2.2
|
||||||
|
|
||||||
[GUI]
|
[GUI]
|
||||||
# 1 is fully opaque
|
# 1 is fully opaque
|
||||||
menu transparency = 0.84
|
menu transparency = 0.84
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <OgreResource.h>
|
#include <OgreResource.h>
|
||||||
#include <OgreResourceManager.h>
|
#include <OgreResourceManager.h>
|
||||||
#include <btBulletCollisionCommon.h>
|
#include <btBulletCollisionCommon.h>
|
||||||
|
#include <OgreVector3.h>
|
||||||
//For some reason, Ogre Singleton cannot be used in another namespace, that's why there is no namespace here.
|
//For some reason, Ogre Singleton cannot be used in another namespace, that's why there is no namespace here.
|
||||||
//But the risk of name collision seems pretty low here.
|
//But the risk of name collision seems pretty low here.
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@ public:
|
||||||
virtual ~BulletShape();
|
virtual ~BulletShape();
|
||||||
|
|
||||||
btCollisionShape* Shape;
|
btCollisionShape* Shape;
|
||||||
|
Ogre::Vector3 boxTranslation;
|
||||||
|
Ogre::Quaternion boxRotation;
|
||||||
//this flag indicate if the shape is used for collision or if it's for raycasting only.
|
//this flag indicate if the shape is used for collision or if it's for raycasting only.
|
||||||
bool collide;
|
bool collide;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <btBulletDynamicsCommon.h>
|
#include <btBulletDynamicsCommon.h>
|
||||||
#include <btBulletCollisionCommon.h>
|
#include <btBulletCollisionCommon.h>
|
||||||
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
||||||
|
#include "pmove.h"
|
||||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||||
#include "CMotionState.h"
|
#include "CMotionState.h"
|
||||||
#include "OgreRoot.h"
|
#include "OgreRoot.h"
|
||||||
|
@ -26,111 +27,139 @@ namespace Physic
|
||||||
COL_RAYCASTING = BIT(3)
|
COL_RAYCASTING = BIT(3)
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicActor::PhysicActor(std::string name)
|
PhysicActor::PhysicActor(std::string name, std::string mesh, PhysicEngine* engine, Ogre::Vector3 position, Ogre::Quaternion rotation, float scale):
|
||||||
|
mName(name), mEngine(engine), mMesh(mesh), mBoxScaledTranslation(0,0,0), mBoxRotationInverse(0,0,0,0), mBody(0), collisionMode(false), mBoxRotation(0,0,0,0)
|
||||||
{
|
{
|
||||||
mName = name;
|
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation);
|
||||||
|
Ogre::Quaternion inverse = mBoxRotation.Inverse();
|
||||||
// The capsule is at the origin
|
mBoxRotationInverse = btQuaternion(inverse.x, inverse.y, inverse.z,inverse.w);
|
||||||
btTransform transform;
|
mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map
|
||||||
transform.setIdentity();
|
pmove = new playerMove;
|
||||||
|
pmove->mEngine = mEngine;
|
||||||
// External capsule
|
btBoxShape* box = static_cast<btBoxShape*> (mBody->getCollisionShape());
|
||||||
externalGhostObject = new PairCachingGhostObject(name);
|
if(box != NULL){
|
||||||
externalGhostObject->setWorldTransform( transform );
|
btVector3 size = box->getHalfExtentsWithMargin();
|
||||||
|
Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ());
|
||||||
btScalar externalCapsuleHeight = 120;
|
pmove->ps.halfExtents = halfExtents;
|
||||||
btScalar externalCapsuleWidth = 19;
|
}
|
||||||
|
|
||||||
externalCollisionShape = new btCapsuleShapeZ( externalCapsuleWidth, externalCapsuleHeight );
|
|
||||||
externalCollisionShape->setMargin( 0.1 );
|
|
||||||
|
|
||||||
externalGhostObject->setCollisionShape( externalCollisionShape );
|
|
||||||
externalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT );
|
|
||||||
|
|
||||||
// Internal capsule
|
|
||||||
internalGhostObject = new PairCachingGhostObject(name);
|
|
||||||
internalGhostObject->setWorldTransform( transform );
|
|
||||||
//internalGhostObject->getBroadphaseHandle()->s
|
|
||||||
btScalar internalCapsuleHeight = 110;
|
|
||||||
btScalar internalCapsuleWidth = 17;
|
|
||||||
|
|
||||||
internalCollisionShape = new btCapsuleShapeZ( internalCapsuleWidth, internalCapsuleHeight );
|
|
||||||
internalCollisionShape->setMargin( 0.1 );
|
|
||||||
|
|
||||||
internalGhostObject->setCollisionShape( internalCollisionShape );
|
|
||||||
internalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT );
|
|
||||||
|
|
||||||
mCharacter = new btKinematicCharacterController( externalGhostObject,internalGhostObject,btScalar( 40 ),1,4,20,9.8,0.2 );
|
|
||||||
mCharacter->setUpAxis(btKinematicCharacterController::Z_AXIS);
|
|
||||||
mCharacter->setUseGhostSweepTest(false);
|
|
||||||
|
|
||||||
mCharacter->mCollision = false;
|
|
||||||
setGravity(0);
|
|
||||||
|
|
||||||
mTranslation = btVector3(0,0,70);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicActor::~PhysicActor()
|
PhysicActor::~PhysicActor()
|
||||||
{
|
{
|
||||||
delete mCharacter;
|
if(mBody){
|
||||||
delete internalGhostObject;
|
mEngine->dynamicsWorld->removeRigidBody(mBody);
|
||||||
delete internalCollisionShape;
|
delete mBody;
|
||||||
delete externalGhostObject;
|
}
|
||||||
delete externalCollisionShape;
|
delete pmove;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicActor::setCurrentWater(bool hasWater, int waterHeight){
|
||||||
|
pmove->hasWater = hasWater;
|
||||||
|
if(hasWater){
|
||||||
|
pmove->waterHeight = waterHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::setGravity(float gravity)
|
void PhysicActor::setGravity(float gravity)
|
||||||
{
|
{
|
||||||
mCharacter->setGravity(gravity);
|
pmove->ps.gravity = gravity;
|
||||||
//mCharacter->
|
}
|
||||||
|
|
||||||
|
void PhysicActor::setSpeed(float speed)
|
||||||
|
{
|
||||||
|
pmove->ps.speed = speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::enableCollisions(bool collision)
|
void PhysicActor::enableCollisions(bool collision)
|
||||||
{
|
{
|
||||||
mCharacter->mCollision = collision;
|
collisionMode = collision;
|
||||||
|
if(collisionMode)
|
||||||
|
pmove->ps.move_type=PM_NORMAL;
|
||||||
|
else
|
||||||
|
pmove->ps.move_type=PM_NOCLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::setVerticalVelocity(float z)
|
void PhysicActor::setJumpVelocity(float velocity)
|
||||||
{
|
{
|
||||||
mCharacter->setVerticalVelocity(z);
|
pmove->ps.jump_velocity = velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicActor::getCollisionMode()
|
bool PhysicActor::getCollisionMode()
|
||||||
{
|
{
|
||||||
return mCharacter->mCollision;
|
return collisionMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::setWalkDirection(const btVector3& mvt)
|
void PhysicActor::setMovement(signed char rightmove, signed char forwardmove, signed char upmove)
|
||||||
{
|
{
|
||||||
mCharacter->setWalkDirection( mvt );
|
playerMove::playercmd& pm_ref = pmove->cmd;
|
||||||
|
pm_ref.rightmove = rightmove;
|
||||||
|
pm_ref.forwardmove = forwardmove;
|
||||||
|
pm_ref.upmove = upmove;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::Rotate(const btQuaternion& quat)
|
void PhysicActor::setPmoveViewAngles(float pitch, float yaw, float roll){
|
||||||
{
|
pmove->ps.viewangles.x = pitch;
|
||||||
externalGhostObject->getWorldTransform().setRotation( externalGhostObject->getWorldTransform().getRotation() * quat );
|
pmove->ps.viewangles.y = yaw;
|
||||||
internalGhostObject->getWorldTransform().setRotation( internalGhostObject->getWorldTransform().getRotation() * quat );
|
pmove->ps.viewangles.z = roll;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::setRotation(const btQuaternion& quat)
|
|
||||||
|
|
||||||
|
void PhysicActor::setRotation(const Ogre::Quaternion quat)
|
||||||
{
|
{
|
||||||
externalGhostObject->getWorldTransform().setRotation( quat );
|
if(!quat.equals(getRotation(), Ogre::Radian(0))){
|
||||||
internalGhostObject->getWorldTransform().setRotation( quat );
|
mEngine->adjustRigidBody(mBody, getPosition(), quat, mBoxScaledTranslation, mBoxRotation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
btVector3 PhysicActor::getPosition(void)
|
Ogre::Vector3 PhysicActor::getPosition()
|
||||||
{
|
{
|
||||||
return internalGhostObject->getWorldTransform().getOrigin() -mTranslation;
|
btVector3 vec = mBody->getWorldTransform().getOrigin();
|
||||||
|
Ogre::Quaternion rotation = Ogre::Quaternion(mBody->getWorldTransform().getRotation().getW(), mBody->getWorldTransform().getRotation().getX(),
|
||||||
|
mBody->getWorldTransform().getRotation().getY(), mBody->getWorldTransform().getRotation().getZ());
|
||||||
|
Ogre::Vector3 transrot = rotation * mBoxScaledTranslation;
|
||||||
|
Ogre::Vector3 visualPosition = Ogre::Vector3(vec.getX(), vec.getY(), vec.getZ()) - transrot;
|
||||||
|
return visualPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
btQuaternion PhysicActor::getRotation(void)
|
Ogre::Quaternion PhysicActor::getRotation()
|
||||||
{
|
{
|
||||||
return internalGhostObject->getWorldTransform().getRotation();
|
btQuaternion quat = mBody->getWorldTransform().getRotation() * mBoxRotationInverse;
|
||||||
|
return Ogre::Quaternion(quat.getW(), quat.getX(), quat.getY(), quat.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::setPosition(const btVector3& pos)
|
void PhysicActor::setPosition(const Ogre::Vector3 pos)
|
||||||
{
|
{
|
||||||
internalGhostObject->getWorldTransform().setOrigin(pos+mTranslation);
|
mEngine->adjustRigidBody(mBody, pos, getRotation(), mBoxScaledTranslation, mBoxRotation);
|
||||||
externalGhostObject->getWorldTransform().setOrigin(pos+mTranslation);
|
btVector3 vec = mBody->getWorldTransform().getOrigin();
|
||||||
|
pmove->ps.origin = Ogre::Vector3(vec.getX(), vec.getY(), vec.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicActor::setScale(float scale){
|
||||||
|
Ogre::Vector3 position = getPosition();
|
||||||
|
Ogre::Quaternion rotation = getRotation();
|
||||||
|
//We only need to change the scaled box translation, box rotations remain the same.
|
||||||
|
mBoxScaledTranslation = mBoxScaledTranslation / mBody->getCollisionShape()->getLocalScaling().getX();
|
||||||
|
mBoxScaledTranslation *= scale;
|
||||||
|
if(mBody){
|
||||||
|
mEngine->dynamicsWorld->removeRigidBody(mBody);
|
||||||
|
delete mBody;
|
||||||
|
}
|
||||||
|
//Create the newly scaled rigid body
|
||||||
|
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation);
|
||||||
|
mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map
|
||||||
|
btBoxShape* box = static_cast<btBoxShape*> (mBody->getCollisionShape());
|
||||||
|
if(box != NULL){
|
||||||
|
btVector3 size = box->getHalfExtentsWithMargin();
|
||||||
|
Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ());
|
||||||
|
pmove->ps.halfExtents = halfExtents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicActor::runPmove(){
|
||||||
|
Pmove(pmove);
|
||||||
|
Ogre::Vector3 newpos = pmove->ps.origin;
|
||||||
|
mBody->getWorldTransform().setOrigin(btVector3(newpos.x, newpos.y, newpos.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -230,8 +259,8 @@ namespace Physic
|
||||||
delete hf_it->second.mBody;
|
delete hf_it->second.mBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBodyContainer::iterator rb_it = RigidBodyMap.begin();
|
RigidBodyContainer::iterator rb_it = ObjectMap.begin();
|
||||||
for (; rb_it != RigidBodyMap.end(); ++rb_it)
|
for (; rb_it != ObjectMap.end(); ++rb_it)
|
||||||
{
|
{
|
||||||
if (rb_it->second != NULL)
|
if (rb_it->second != NULL)
|
||||||
{
|
{
|
||||||
|
@ -247,9 +276,7 @@ namespace Physic
|
||||||
{
|
{
|
||||||
if (pa_it->second != NULL)
|
if (pa_it->second != NULL)
|
||||||
{
|
{
|
||||||
dynamicsWorld->removeCollisionObject(pa_it->second->externalGhostObject);
|
|
||||||
dynamicsWorld->removeCollisionObject(pa_it->second->internalGhostObject);
|
|
||||||
dynamicsWorld->removeAction(pa_it->second->mCharacter);
|
|
||||||
|
|
||||||
delete pa_it->second;
|
delete pa_it->second;
|
||||||
pa_it->second = NULL;
|
pa_it->second = NULL;
|
||||||
|
@ -332,18 +359,42 @@ namespace Physic
|
||||||
mHeightFieldMap.erase(name);
|
mHeightFieldMap.erase(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale)
|
void PhysicEngine::adjustRigidBody(RigidBody* body, Ogre::Vector3 position, Ogre::Quaternion rotation,
|
||||||
{
|
Ogre::Vector3 scaledBoxTranslation, Ogre::Quaternion boxRotation){
|
||||||
|
btTransform tr;
|
||||||
|
rotation = rotation * boxRotation;
|
||||||
|
Ogre::Vector3 transrot = rotation * scaledBoxTranslation;
|
||||||
|
Ogre::Vector3 newPosition = transrot + position;
|
||||||
|
|
||||||
|
tr.setOrigin(btVector3(newPosition.x, newPosition.y, newPosition.z));
|
||||||
|
tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w));
|
||||||
|
body->setWorldTransform(tr);
|
||||||
|
}
|
||||||
|
void PhysicEngine::boxAdjustExternal(std::string mesh, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation){
|
||||||
std::string sid = (boost::format("%07.3f") % scale).str();
|
std::string sid = (boost::format("%07.3f") % scale).str();
|
||||||
std::string outputstring = mesh + sid;
|
std::string outputstring = mesh + sid;
|
||||||
//std::cout << "The string" << outputstring << "\n";
|
//std::cout << "The string" << outputstring << "\n";
|
||||||
|
|
||||||
|
//get the shape from the .nif
|
||||||
|
mShapeLoader->load(outputstring,"General");
|
||||||
|
BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
|
||||||
|
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
|
||||||
|
|
||||||
|
adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation,
|
||||||
|
Ogre::Vector3* scaledBoxTranslation, Ogre::Quaternion* boxRotation)
|
||||||
|
{
|
||||||
|
std::string sid = (boost::format("%07.3f") % scale).str();
|
||||||
|
std::string outputstring = mesh + sid;
|
||||||
|
|
||||||
//get the shape from the .nif
|
//get the shape from the .nif
|
||||||
mShapeLoader->load(outputstring,"General");
|
mShapeLoader->load(outputstring,"General");
|
||||||
BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
|
BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
|
||||||
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
|
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
|
||||||
shape->Shape->setLocalScaling( btVector3(scale,scale,scale));
|
shape->Shape->setLocalScaling( btVector3(scale,scale,scale));
|
||||||
//btScaledBvhTriangleMeshShape* scaled = new btScaledBvhTriangleMeshShape(dynamic_cast<btBvhTriangleMeshShape*> (shape->Shape), btVector3(scale,scale,scale));
|
|
||||||
|
|
||||||
//create the motionState
|
//create the motionState
|
||||||
CMotionState* newMotionState = new CMotionState(this,name);
|
CMotionState* newMotionState = new CMotionState(this,name);
|
||||||
|
@ -352,11 +403,19 @@ namespace Physic
|
||||||
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape);
|
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape);
|
||||||
RigidBody* body = new RigidBody(CI,name);
|
RigidBody* body = new RigidBody(CI,name);
|
||||||
body->collide = shape->collide;
|
body->collide = shape->collide;
|
||||||
|
|
||||||
|
if(scaledBoxTranslation != 0)
|
||||||
|
*scaledBoxTranslation = shape->boxTranslation * scale;
|
||||||
|
if(boxRotation != 0)
|
||||||
|
*boxRotation = shape->boxRotation;
|
||||||
|
|
||||||
|
adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation);
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicEngine::addRigidBody(RigidBody* body)
|
void PhysicEngine::addRigidBody(RigidBody* body, bool addToMap)
|
||||||
{
|
{
|
||||||
if(body)
|
if(body)
|
||||||
{
|
{
|
||||||
|
@ -369,21 +428,23 @@ namespace Physic
|
||||||
dynamicsWorld->addRigidBody(body,COL_RAYCASTING,COL_RAYCASTING|COL_WORLD);
|
dynamicsWorld->addRigidBody(body,COL_RAYCASTING,COL_RAYCASTING|COL_WORLD);
|
||||||
}
|
}
|
||||||
body->setActivationState(DISABLE_DEACTIVATION);
|
body->setActivationState(DISABLE_DEACTIVATION);
|
||||||
RigidBody* oldBody = RigidBodyMap[body->mName];
|
if(addToMap){
|
||||||
|
RigidBody* oldBody = ObjectMap[body->mName];
|
||||||
if (oldBody != NULL)
|
if (oldBody != NULL)
|
||||||
{
|
{
|
||||||
dynamicsWorld->removeRigidBody(oldBody);
|
dynamicsWorld->removeRigidBody(oldBody);
|
||||||
delete oldBody;
|
delete oldBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBodyMap[body->mName] = body;
|
ObjectMap[body->mName] = body;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicEngine::removeRigidBody(std::string name)
|
void PhysicEngine::removeRigidBody(std::string name)
|
||||||
{
|
{
|
||||||
RigidBodyContainer::iterator it = RigidBodyMap.find(name);
|
RigidBodyContainer::iterator it = ObjectMap.find(name);
|
||||||
if (it != RigidBodyMap.end() )
|
if (it != ObjectMap.end() )
|
||||||
{
|
{
|
||||||
RigidBody* body = it->second;
|
RigidBody* body = it->second;
|
||||||
if(body != NULL)
|
if(body != NULL)
|
||||||
|
@ -402,8 +463,8 @@ namespace Physic
|
||||||
|
|
||||||
void PhysicEngine::deleteRigidBody(std::string name)
|
void PhysicEngine::deleteRigidBody(std::string name)
|
||||||
{
|
{
|
||||||
RigidBodyContainer::iterator it = RigidBodyMap.find(name);
|
RigidBodyContainer::iterator it = ObjectMap.find(name);
|
||||||
if (it != RigidBodyMap.end() )
|
if (it != ObjectMap.end() )
|
||||||
{
|
{
|
||||||
RigidBody* body = it->second;
|
RigidBody* body = it->second;
|
||||||
//btScaledBvhTriangleMeshShape* scaled = dynamic_cast<btScaledBvhTriangleMeshShape*> (body->getCollisionShape());
|
//btScaledBvhTriangleMeshShape* scaled = dynamic_cast<btScaledBvhTriangleMeshShape*> (body->getCollisionShape());
|
||||||
|
@ -416,16 +477,16 @@ namespace Physic
|
||||||
{
|
{
|
||||||
delete scaled;
|
delete scaled;
|
||||||
}*/
|
}*/
|
||||||
RigidBodyMap.erase(it);
|
ObjectMap.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBody* PhysicEngine::getRigidBody(std::string name)
|
RigidBody* PhysicEngine::getRigidBody(std::string name)
|
||||||
{
|
{
|
||||||
RigidBodyContainer::iterator it = RigidBodyMap.find(name);
|
RigidBodyContainer::iterator it = ObjectMap.find(name);
|
||||||
if (it != RigidBodyMap.end() )
|
if (it != ObjectMap.end() )
|
||||||
{
|
{
|
||||||
RigidBody* body = RigidBodyMap[name];
|
RigidBody* body = ObjectMap[name];
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -443,16 +504,17 @@ namespace Physic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicEngine::addCharacter(std::string name)
|
void PhysicEngine::addCharacter(std::string name, std::string mesh,
|
||||||
|
Ogre::Vector3 position, float scale, Ogre::Quaternion rotation)
|
||||||
{
|
{
|
||||||
// Remove character with given name, so we don't make memory
|
// Remove character with given name, so we don't make memory
|
||||||
// leak when character would be added twice
|
// leak when character would be added twice
|
||||||
removeCharacter(name);
|
removeCharacter(name);
|
||||||
|
|
||||||
PhysicActor* newActor = new PhysicActor(name);
|
PhysicActor* newActor = new PhysicActor(name, mesh, this, position, rotation, scale);
|
||||||
dynamicsWorld->addCollisionObject( newActor->externalGhostObject, COL_ACTOR_EXTERNAL, COL_WORLD |COL_ACTOR_EXTERNAL );
|
|
||||||
dynamicsWorld->addCollisionObject( newActor->internalGhostObject, COL_ACTOR_INTERNAL, COL_WORLD |COL_ACTOR_INTERNAL );
|
|
||||||
dynamicsWorld->addAction( newActor->mCharacter );
|
//dynamicsWorld->addAction( newActor->mCharacter );
|
||||||
PhysicActorMap[name] = newActor;
|
PhysicActorMap[name] = newActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,25 +527,11 @@ namespace Physic
|
||||||
PhysicActor* act = it->second;
|
PhysicActor* act = it->second;
|
||||||
if(act != NULL)
|
if(act != NULL)
|
||||||
{
|
{
|
||||||
/*broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
|
|
||||||
broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
|
|
||||||
PhysicActorContainer::iterator it2 = PhysicActorMap.begin();
|
|
||||||
for(;it2!=PhysicActorMap.end();it++)
|
|
||||||
{
|
|
||||||
it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
|
|
||||||
it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
|
|
||||||
it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
|
|
||||||
it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
|
|
||||||
}*/
|
|
||||||
//act->externalGhostObject->
|
|
||||||
dynamicsWorld->removeCollisionObject(act->externalGhostObject);
|
|
||||||
dynamicsWorld->removeCollisionObject(act->internalGhostObject);
|
|
||||||
dynamicsWorld->removeAction(act->mCharacter);
|
|
||||||
delete act;
|
delete act;
|
||||||
}
|
}
|
||||||
PhysicActorMap.erase(it);
|
PhysicActorMap.erase(it);
|
||||||
}
|
}
|
||||||
//std::cout << "ok";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicActor* PhysicEngine::getCharacter(std::string name)
|
PhysicActor* PhysicEngine::getCharacter(std::string name)
|
||||||
|
|
|
@ -9,14 +9,16 @@
|
||||||
#include "BulletShapeLoader.h"
|
#include "BulletShapeLoader.h"
|
||||||
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
|
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class btRigidBody;
|
class btRigidBody;
|
||||||
class btBroadphaseInterface;
|
class btBroadphaseInterface;
|
||||||
class btDefaultCollisionConfiguration;
|
class btDefaultCollisionConfiguration;
|
||||||
class btSequentialImpulseConstraintSolver;
|
class btSequentialImpulseConstraintSolver;
|
||||||
class btCollisionDispatcher;
|
class btCollisionDispatcher;
|
||||||
class btDiscreteDynamicsWorld;
|
class btDiscreteDynamicsWorld;
|
||||||
class btKinematicCharacterController;
|
|
||||||
class btHeightfieldTerrainShape;
|
class btHeightfieldTerrainShape;
|
||||||
|
struct playerMove;
|
||||||
|
|
||||||
namespace BtOgre
|
namespace BtOgre
|
||||||
{
|
{
|
||||||
|
@ -28,11 +30,14 @@ namespace MWWorld
|
||||||
class World;
|
class World;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace OEngine {
|
namespace OEngine {
|
||||||
namespace Physic
|
namespace Physic
|
||||||
{
|
{
|
||||||
class CMotionState;
|
class CMotionState;
|
||||||
struct PhysicEvent;
|
struct PhysicEvent;
|
||||||
|
class PhysicEngine;
|
||||||
|
class RigidBody;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*This is just used to be able to name objects.
|
*This is just used to be able to name objects.
|
||||||
|
@ -50,55 +55,88 @@ namespace Physic
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A physic Actor use a modifed KinematicCharacterController taken in the bullet forum.
|
* A physic actor uses a rigid body based on box shapes.
|
||||||
|
* Pmove is used to move the physic actor around the dynamic world.
|
||||||
*/
|
*/
|
||||||
class PhysicActor
|
class PhysicActor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PhysicActor(std::string name);
|
PhysicActor(std::string name, std::string mesh, PhysicEngine *engine, Ogre::Vector3 position, Ogre::Quaternion rotation, float scale);
|
||||||
|
|
||||||
~PhysicActor();
|
~PhysicActor();
|
||||||
|
|
||||||
|
void setCurrentWater(bool hasWater, int waterHeight);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function set the walkDirection. This is not relative to the actor orientation.
|
* This function sets the movement keys for pmove
|
||||||
* I think it's also needed to take time into account. A typical call should look like this:
|
|
||||||
* setWalkDirection( mvt * orientation * dt)
|
|
||||||
*/
|
*/
|
||||||
void setWalkDirection(const btVector3& mvt);
|
void setMovement(signed char rightmove, signed char forwardmove, signed char upmove);
|
||||||
|
|
||||||
void Rotate(const btQuaternion& quat);
|
/**
|
||||||
|
* This adjusts the rotation of a PhysicActor
|
||||||
void setRotation(const btQuaternion& quat);
|
* If we have any problems with this (getting stuck in pmove) we should change it
|
||||||
|
* from setting the visual orientation to setting the orientation of the rigid body directly.
|
||||||
|
*/
|
||||||
|
void setRotation(const Ogre::Quaternion quat);
|
||||||
|
|
||||||
void setGravity(float gravity);
|
void setGravity(float gravity);
|
||||||
|
|
||||||
void setVerticalVelocity(float z);
|
void setSpeed(float speed);
|
||||||
|
|
||||||
|
void setJumpVelocity(float velocity);
|
||||||
|
|
||||||
void enableCollisions(bool collision);
|
void enableCollisions(bool collision);
|
||||||
|
|
||||||
bool getCollisionMode();
|
bool getCollisionMode();
|
||||||
|
|
||||||
btVector3 getPosition(void);
|
/**
|
||||||
|
* This returns the visual position of the PhysicActor (used to position a scenenode).
|
||||||
btQuaternion getRotation(void);
|
* Note - this is different from the position of the contained mBody.
|
||||||
|
*/
|
||||||
void setPosition(const btVector3& pos);
|
Ogre::Vector3 getPosition();
|
||||||
|
|
||||||
btKinematicCharacterController* mCharacter;
|
|
||||||
|
|
||||||
PairCachingGhostObject* internalGhostObject;
|
|
||||||
btCollisionShape* internalCollisionShape;
|
|
||||||
|
|
||||||
PairCachingGhostObject* externalGhostObject;
|
|
||||||
btCollisionShape* externalCollisionShape;
|
|
||||||
|
|
||||||
std::string mName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*NPC scenenode is located on there feet, and you can't simply translate a btShape, so this vector is used
|
* Returns the visual orientation of the PhysicActor
|
||||||
*each time get/setposition is called.
|
|
||||||
*/
|
*/
|
||||||
btVector3 mTranslation;
|
Ogre::Quaternion getRotation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of mBody from a visual position input.
|
||||||
|
* For most cases this should not be used. We should instead let pmove move the PhysicActor around for us
|
||||||
|
*/
|
||||||
|
void setPosition(const Ogre::Vector3 pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the view angles for pmove directly.
|
||||||
|
* Remember, add 90 for yaw. Set roll to 0.
|
||||||
|
*/
|
||||||
|
void setPmoveViewAngles(float pitch, float yaw, float roll);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the scale of the PhysicActor
|
||||||
|
*/
|
||||||
|
void setScale(float scale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs pmove for this PhysicActor
|
||||||
|
*/
|
||||||
|
void runPmove();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
OEngine::Physic::RigidBody* mBody;
|
||||||
|
Ogre::Vector3 mBoxScaledTranslation;
|
||||||
|
btQuaternion mBoxRotationInverse;
|
||||||
|
Ogre::Quaternion mBoxRotation;
|
||||||
|
bool collisionMode;
|
||||||
|
std::string mMesh;
|
||||||
|
PhysicEngine* mEngine;
|
||||||
|
std::string mName;
|
||||||
|
playerMove* pmove;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,11 +181,22 @@ namespace Physic
|
||||||
~PhysicEngine();
|
~PhysicEngine();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a RigidBody.It does not add it to the simulation, but it does add it to the rigidBody Map,
|
* Creates a RigidBody. It does not add it to the simulation.
|
||||||
* so you can get it with the getRigidBody function.
|
* After created, the body is set to the correct rotation, position, and scale
|
||||||
*/
|
*/
|
||||||
RigidBody* createRigidBody(std::string mesh,std::string name,float scale);
|
RigidBody* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation,
|
||||||
|
Ogre::Vector3* scaledBoxTranslation = 0, Ogre::Quaternion* boxRotation = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts a rigid body to the right position and rotation
|
||||||
|
*/
|
||||||
|
|
||||||
|
void adjustRigidBody(RigidBody* body, Ogre::Vector3 position, Ogre::Quaternion rotation,
|
||||||
|
Ogre::Vector3 scaledBoxTranslation = Ogre::Vector3::ZERO, Ogre::Quaternion boxRotation = Ogre::Quaternion::IDENTITY);
|
||||||
|
/**
|
||||||
|
Mainly used to (but not limited to) adjust rigid bodies based on box shapes to the right position and rotation.
|
||||||
|
*/
|
||||||
|
void boxAdjustExternal(std::string mesh, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation);
|
||||||
/**
|
/**
|
||||||
* Add a HeightField to the simulation
|
* Add a HeightField to the simulation
|
||||||
*/
|
*/
|
||||||
|
@ -163,7 +212,7 @@ namespace Physic
|
||||||
/**
|
/**
|
||||||
* Add a RigidBody to the simulation
|
* Add a RigidBody to the simulation
|
||||||
*/
|
*/
|
||||||
void addRigidBody(RigidBody* body);
|
void addRigidBody(RigidBody* body, bool addToMap = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap.
|
* Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap.
|
||||||
|
@ -184,7 +233,8 @@ namespace Physic
|
||||||
/**
|
/**
|
||||||
* Create and add a character to the scene, and add it to the ActorMap.
|
* Create and add a character to the scene, and add it to the ActorMap.
|
||||||
*/
|
*/
|
||||||
void addCharacter(std::string name);
|
void addCharacter(std::string name, std::string mesh,
|
||||||
|
Ogre::Vector3 position, float scale, Ogre::Quaternion rotation);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a character from the scene. TODO:delete it! for now, a small memory leak^^ done?
|
* Remove a character from the scene. TODO:delete it! for now, a small memory leak^^ done?
|
||||||
|
@ -254,7 +304,7 @@ namespace Physic
|
||||||
HeightFieldContainer mHeightFieldMap;
|
HeightFieldContainer mHeightFieldMap;
|
||||||
|
|
||||||
typedef std::map<std::string,RigidBody*> RigidBodyContainer;
|
typedef std::map<std::string,RigidBody*> RigidBodyContainer;
|
||||||
RigidBodyContainer RigidBodyMap;
|
RigidBodyContainer ObjectMap;
|
||||||
|
|
||||||
typedef std::map<std::string, PhysicActor*> PhysicActorContainer;
|
typedef std::map<std::string, PhysicActor*> PhysicActorContainer;
|
||||||
PhysicActorContainer PhysicActorMap;
|
PhysicActorContainer PhysicActorMap;
|
||||||
|
@ -263,6 +313,7 @@ namespace Physic
|
||||||
BtOgre::DebugDrawer* mDebugDrawer;
|
BtOgre::DebugDrawer* mDebugDrawer;
|
||||||
bool isDebugCreated;
|
bool isDebugCreated;
|
||||||
bool mDebugActive;
|
bool mDebugActive;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ bool PM_SlideMove( bool gravity )
|
||||||
// see if we can make it there
|
// see if we can make it there
|
||||||
//pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemaskg);
|
//pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemaskg);
|
||||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&(end), *(const D3DXVECTOR3* const)&(pm->ps.velocity), 0, pml.traceObj);
|
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&(end), *(const D3DXVECTOR3* const)&(pm->ps.velocity), 0, pml.traceObj);
|
||||||
newtrace(&trace, pm->ps.origin, end, halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
newtrace(&trace, pm->ps.origin, end, pm->ps.halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||||
|
|
||||||
if (trace.allsolid)
|
if (trace.allsolid)
|
||||||
{
|
{
|
||||||
|
@ -301,7 +301,7 @@ bool PM_SlideMove( bool gravity )
|
||||||
|
|
||||||
if(planes[i].x >= .70)
|
if(planes[i].x >= .70)
|
||||||
{
|
{
|
||||||
pm->ps.velocity = Ogre::Vector3(0,0,0);
|
pm->ps.velocity.z = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// see how hard we are hitting things
|
// see how hard we are hitting things
|
||||||
|
@ -449,7 +449,7 @@ int PM_StepSlideMove( bool gravity )
|
||||||
//pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
|
//pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
|
||||||
//tracefunc(&trace, start_o, down, , 0, pml.scene);
|
//tracefunc(&trace, start_o, down, , 0, pml.scene);
|
||||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj);
|
//tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj);
|
||||||
newtrace(&trace, start_o, down, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
newtrace(&trace, down, start_o, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||||
|
|
||||||
// up = vec3(0, 0, 1)
|
// up = vec3(0, 0, 1)
|
||||||
//VectorSet(up, 0, 0, 1);
|
//VectorSet(up, 0, 0, 1);
|
||||||
|
@ -479,7 +479,7 @@ int PM_StepSlideMove( bool gravity )
|
||||||
// test the player position if they were a stepheight higher
|
// test the player position if they were a stepheight higher
|
||||||
//pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
|
//pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
|
||||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&up, D3DXVECTOR3(0.0f, STEPSIZE, 0.0f), 0, pml.traceObj);
|
//tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&up, D3DXVECTOR3(0.0f, STEPSIZE, 0.0f), 0, pml.traceObj);
|
||||||
newtrace(&trace, start_o, up, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
newtrace(&trace, start_o, up, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||||
if ( trace.allsolid )
|
if ( trace.allsolid )
|
||||||
{
|
{
|
||||||
//if ( pm->debugLevel )
|
//if ( pm->debugLevel )
|
||||||
|
@ -510,7 +510,7 @@ int PM_StepSlideMove( bool gravity )
|
||||||
|
|
||||||
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
|
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
|
||||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj);
|
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj);
|
||||||
newtrace(&trace, pm->ps.origin, down, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
newtrace(&trace, pm->ps.origin, down, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||||
if ( !trace.allsolid )
|
if ( !trace.allsolid )
|
||||||
//VectorCopy (trace.endpos, pm->ps->origin);
|
//VectorCopy (trace.endpos, pm->ps->origin);
|
||||||
pm->ps.origin = trace.endpos;
|
pm->ps.origin = trace.endpos;
|
||||||
|
@ -527,7 +527,7 @@ int PM_StepSlideMove( bool gravity )
|
||||||
delta = pm->ps.origin.z - start_o.z;
|
delta = pm->ps.origin.z - start_o.z;
|
||||||
if ( delta > 2 )
|
if ( delta > 2 )
|
||||||
{
|
{
|
||||||
pm->ps.counter = 5;
|
pm->ps.counter = 10;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (gravity)
|
if (gravity)
|
||||||
|
@ -657,6 +657,7 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel
|
||||||
// int i;
|
// int i;
|
||||||
float addspeed, accelspeed, currentspeed;
|
float addspeed, accelspeed, currentspeed;
|
||||||
|
|
||||||
|
|
||||||
// currentspeed = pm->ps->velocity dot wishdir
|
// currentspeed = pm->ps->velocity dot wishdir
|
||||||
//currentspeed = DotProduct (pm->ps->velocity, wishdir);
|
//currentspeed = DotProduct (pm->ps->velocity, wishdir);
|
||||||
currentspeed = pm->ps.velocity.dotProduct(wishdir);
|
currentspeed = pm->ps.velocity.dotProduct(wishdir);
|
||||||
|
@ -675,6 +676,8 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel
|
||||||
//for (i=0 ; i<3 ; i++)
|
//for (i=0 ; i<3 ; i++)
|
||||||
//pm->ps->velocity[i] += accelspeed * wishdir[i];
|
//pm->ps->velocity[i] += accelspeed * wishdir[i];
|
||||||
pm->ps.velocity += (wishdir * accelspeed);
|
pm->ps.velocity += (wishdir * accelspeed);
|
||||||
|
//pm->ps.velocity = wishdir * wishspeed; //New, for instant acceleration
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PM_CheckJump(void)
|
static bool PM_CheckJump(void)
|
||||||
|
@ -701,7 +704,7 @@ static bool PM_CheckJump(void)
|
||||||
//pm->ps->pm_flags |= PMF_JUMP_HELD;
|
//pm->ps->pm_flags |= PMF_JUMP_HELD;
|
||||||
|
|
||||||
pm->ps.groundEntityNum = ENTITYNUM_NONE;
|
pm->ps.groundEntityNum = ENTITYNUM_NONE;
|
||||||
pm->ps.velocity.z = JUMP_VELOCITY;
|
pm->ps.velocity.z = pm->ps.jump_velocity;
|
||||||
pm->ps.bSnap = false;
|
pm->ps.bSnap = false;
|
||||||
//PM_AddEvent( EV_JUMP );
|
//PM_AddEvent( EV_JUMP );
|
||||||
|
|
||||||
|
@ -899,7 +902,7 @@ static void PM_WalkMove( playerMove* const pmove )
|
||||||
if (pmove->hasWater )
|
if (pmove->hasWater )
|
||||||
{
|
{
|
||||||
const float waterHeight = pmove->waterHeight;
|
const float waterHeight = pmove->waterHeight;
|
||||||
const float waterSoundStepHeight = waterHeight + halfExtents.y;
|
const float waterSoundStepHeight = waterHeight + pm->ps.halfExtents.y;
|
||||||
if (pmove->ps.origin.y < waterSoundStepHeight)
|
if (pmove->ps.origin.y < waterSoundStepHeight)
|
||||||
step_underwater = true;
|
step_underwater = true;
|
||||||
}
|
}
|
||||||
|
@ -1179,7 +1182,7 @@ void PM_GroundTraceMissed()
|
||||||
|
|
||||||
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
||||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -64.0f, 0.0f), 0, pml.traceObj);
|
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -64.0f, 0.0f), 0, pml.traceObj);
|
||||||
newtrace(&trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
newtrace(&trace, pm->ps.origin, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||||
//It hit the ground below
|
//It hit the ground below
|
||||||
if ( trace.fraction < 1.0 && pm->ps.origin.z > trace.endpos.z)
|
if ( trace.fraction < 1.0 && pm->ps.origin.z > trace.endpos.z)
|
||||||
{
|
{
|
||||||
|
@ -1225,7 +1228,7 @@ static bool PM_CorrectAllSolid(traceResults* const trace)
|
||||||
|
|
||||||
//pm->trace (trace, point, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
//pm->trace (trace, point, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
||||||
//tracefunc(trace, *(const D3DXVECTOR3* const)&point, *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, 0.0f, 0.0f), 0, pml.traceObj);
|
//tracefunc(trace, *(const D3DXVECTOR3* const)&point, *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, 0.0f, 0.0f), 0, pml.traceObj);
|
||||||
newtrace(trace, point, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
newtrace(trace, point, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||||
|
|
||||||
if ( !trace->allsolid )
|
if ( !trace->allsolid )
|
||||||
{
|
{
|
||||||
|
@ -1237,7 +1240,7 @@ static bool PM_CorrectAllSolid(traceResults* const trace)
|
||||||
|
|
||||||
//pm->trace (trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
//pm->trace (trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
||||||
//tracefunc(trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
|
//tracefunc(trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
|
||||||
newtrace(trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
newtrace(trace, pm->ps.origin, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||||
pml.groundTrace = *trace;
|
pml.groundTrace = *trace;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1338,7 +1341,7 @@ static void PM_CrashLand( void )
|
||||||
{
|
{
|
||||||
|
|
||||||
const float waterHeight = pm->waterHeight;
|
const float waterHeight = pm->waterHeight;
|
||||||
const float waterHeightSplash = waterHeight + halfExtents.y;
|
const float waterHeightSplash = waterHeight + pm->ps.halfExtents.y;
|
||||||
if (pm->ps.origin.z < waterHeightSplash)
|
if (pm->ps.origin.z < waterHeightSplash)
|
||||||
{
|
{
|
||||||
splashSound = true;
|
splashSound = true;
|
||||||
|
@ -1413,7 +1416,7 @@ static void PM_GroundTrace( void )
|
||||||
|
|
||||||
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
||||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
|
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
|
||||||
newtrace(&trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
newtrace(&trace, pm->ps.origin, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||||
pml.groundTrace = trace;
|
pml.groundTrace = trace;
|
||||||
|
|
||||||
// do something corrective if the trace starts in a solid...
|
// do something corrective if the trace starts in a solid...
|
||||||
|
|
|
@ -23,7 +23,7 @@ Quake 3 Arena is copyright (C) 1999-2005 Id Software, Inc.
|
||||||
extern SceneInstance* global_lastscene;
|
extern SceneInstance* global_lastscene;
|
||||||
#endif*/
|
#endif*/
|
||||||
|
|
||||||
static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
|
static const Ogre::Vector3 halfExtentsDefault(14.64f * 2, 14.24f * 2, 33.25f * 2);
|
||||||
|
|
||||||
#define MAX_CLIP_PLANES 5
|
#define MAX_CLIP_PLANES 5
|
||||||
#define OVERCLIP 1.001f
|
#define OVERCLIP 1.001f
|
||||||
|
@ -42,7 +42,6 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
|
||||||
#define ENTITYNUM_NONE (MAX_GENTITIES - 1)
|
#define ENTITYNUM_NONE (MAX_GENTITIES - 1)
|
||||||
#define ENTITYNUM_WORLD (MAX_GENTITIES - 2)
|
#define ENTITYNUM_WORLD (MAX_GENTITIES - 2)
|
||||||
#define MIN_WALK_NORMAL .7f // can't walk on very steep slopes
|
#define MIN_WALK_NORMAL .7f // can't walk on very steep slopes
|
||||||
#define JUMP_VELOCITY (270)
|
|
||||||
#define PS_PMOVEFRAMECOUNTBITS 6
|
#define PS_PMOVEFRAMECOUNTBITS 6
|
||||||
#define MINS_Z -24
|
#define MINS_Z -24
|
||||||
#define DEFAULT_VIEWHEIGHT 26
|
#define DEFAULT_VIEWHEIGHT 26
|
||||||
|
@ -90,9 +89,9 @@ struct playerMove
|
||||||
{
|
{
|
||||||
struct playerStruct
|
struct playerStruct
|
||||||
{
|
{
|
||||||
playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1)
|
playerStruct() : gravity(800.0f), speed(480.0f), jump_velocity(270), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1), halfExtents(halfExtentsDefault)
|
||||||
{
|
{
|
||||||
origin = Ogre::Vector3(733.164f,900.0f, 839.432f);
|
origin = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||||
velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||||
|
@ -117,11 +116,13 @@ struct playerMove
|
||||||
|
|
||||||
Ogre::Vector3 velocity;
|
Ogre::Vector3 velocity;
|
||||||
Ogre::Vector3 origin;
|
Ogre::Vector3 origin;
|
||||||
|
Ogre::Vector3 halfExtents;
|
||||||
bool bSnap;
|
bool bSnap;
|
||||||
bool snappingImplemented;
|
bool snappingImplemented;
|
||||||
int counter;
|
int counter;
|
||||||
float gravity; // default = 800
|
float gravity; // default = 800
|
||||||
float speed; // default = 320
|
float speed; // default = 320
|
||||||
|
float jump_velocity; //default = 270
|
||||||
|
|
||||||
int commandTime; // the time at which this command was issued (in milliseconds)
|
int commandTime; // the time at which this command was issued (in milliseconds)
|
||||||
|
|
||||||
|
|
|
@ -13,18 +13,22 @@
|
||||||
|
|
||||||
void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass) //Traceobj was a Aedra Object
|
void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass) //Traceobj was a Aedra Object
|
||||||
{
|
{
|
||||||
|
static float lastyaw = 0.0f;
|
||||||
|
static float lastpitch = 0.0f;
|
||||||
//if (!traceobj)
|
//if (!traceobj)
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
//if (!traceobj->incellptr)
|
//if (!traceobj->incellptr)
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
|
|
||||||
const Ogre::Vector3 rayDir = end - start;
|
const Ogre::Vector3 rayDir = end - start;
|
||||||
|
|
||||||
// Nudge starting point backwards
|
|
||||||
//const Position3D nudgestart = start + (rayDir * -0.1f); // by 10% (isn't that too much?)
|
|
||||||
//const Position3D nudgestart = start;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NewPhysTraceResults out;
|
NewPhysTraceResults out;
|
||||||
//std::cout << "Starting trace\n";
|
//std::cout << "Starting trace\n";
|
||||||
|
@ -32,7 +36,7 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr
|
||||||
//Ogre::Vector3 endReplace = startReplace;
|
//Ogre::Vector3 endReplace = startReplace;
|
||||||
//endReplace.z -= .25;
|
//endReplace.z -= .25;
|
||||||
|
|
||||||
const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0, rotation), isInterior, enginePass);
|
const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0f, 0.0f), isInterior, enginePass);
|
||||||
|
|
||||||
if (out.fraction < 0.001f)
|
if (out.fraction < 0.001f)
|
||||||
results->startsolid = true;
|
results->startsolid = true;
|
||||||
|
@ -102,6 +106,7 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
|
||||||
const btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z
|
const btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z
|
||||||
|
|
||||||
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
|
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
|
||||||
|
//const btCapsuleShapeZ newshape(BBHalfExtents.x, BBHalfExtents.z * 2 - BBHalfExtents.x * 2);
|
||||||
const btTransform from(btrot, btstart);
|
const btTransform from(btrot, btstart);
|
||||||
const btTransform to(btrot, btend);
|
const btTransform to(btrot, btend);
|
||||||
|
|
||||||
|
@ -176,7 +181,8 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
|
||||||
if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) )
|
if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) )
|
||||||
{
|
{
|
||||||
//We're solid
|
//We're solid
|
||||||
out->startSolid = true;
|
//THIS NEEDS TO BE TURNED OFF IF WE WANT FALLING IN EXTERIORS TO WORK CORRECTLY!!!!!!!
|
||||||
|
//out->startSolid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
#include <btBulletDynamicsCommon.h>
|
#include <btBulletDynamicsCommon.h>
|
||||||
#include <btBulletCollisionCommon.h>
|
#include <btBulletCollisionCommon.h>
|
||||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||||
#include <openengine/bullet/pmove.h>
|
|
||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
|
#include "pmove.h"
|
||||||
|
|
||||||
|
|
||||||
enum traceWorldType
|
enum traceWorldType
|
||||||
|
|
|
@ -1,52 +1,50 @@
|
||||||
#include "fader.hpp"
|
#include "fader.hpp"
|
||||||
|
|
||||||
#include <OgreOverlayManager.h>
|
|
||||||
#include <OgreOverlayContainer.h>
|
|
||||||
#include <OgreOverlay.h>
|
|
||||||
#include <OgreMaterial.h>
|
#include <OgreMaterial.h>
|
||||||
#include <OgreTechnique.h>
|
#include <OgreTechnique.h>
|
||||||
#include <OgreMaterialManager.h>
|
#include <OgreMaterialManager.h>
|
||||||
#include <OgreResourceGroupManager.h>
|
#include <OgreResourceGroupManager.h>
|
||||||
|
#include <OgreRectangle2D.h>
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
#define FADE_OVERLAY_NAME "FadeInOutOverlay"
|
|
||||||
#define FADE_OVERLAY_PANEL_NAME "FadeInOutOverlayPanel"
|
|
||||||
#define FADE_MATERIAL_NAME "FadeInOutMaterial"
|
|
||||||
|
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
using namespace OEngine::Render;
|
using namespace OEngine::Render;
|
||||||
|
|
||||||
Fader::Fader() :
|
Fader::Fader(Ogre::SceneManager* sceneMgr)
|
||||||
mMode(FadingMode_In),
|
: mSceneMgr(sceneMgr)
|
||||||
mRemainingTime(0.f),
|
, mMode(FadingMode_In)
|
||||||
mTargetTime(0.f),
|
, mRemainingTime(0.f)
|
||||||
mTargetAlpha(0.f),
|
, mTargetTime(0.f)
|
||||||
mCurrentAlpha(0.f),
|
, mTargetAlpha(0.f)
|
||||||
mStartAlpha(0.f)
|
, mCurrentAlpha(0.f)
|
||||||
|
, mStartAlpha(0.f)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Create the fading material
|
// Create the fading material
|
||||||
MaterialPtr material = MaterialManager::getSingleton().create( FADE_MATERIAL_NAME, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
|
MaterialPtr material = MaterialManager::getSingleton().create("FadeInOutMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
|
||||||
Pass* pass = material->getTechnique(0)->getPass(0);
|
Pass* pass = material->getTechnique(0)->getPass(0);
|
||||||
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
||||||
mFadeTextureUnit = pass->createTextureUnitState();
|
mFadeTextureUnit = pass->createTextureUnitState();
|
||||||
mFadeTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(0.f, 0.f, 0.f)); // always black colour
|
mFadeTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(0.f, 0.f, 0.f)); // always black colour
|
||||||
|
|
||||||
// Create the overlay
|
mRectangle = new Ogre::Rectangle2D(true);
|
||||||
OverlayManager& ovm = OverlayManager::getSingleton();
|
mRectangle->setCorners(-1.0, 1.0, 1.0, -1.0);
|
||||||
|
mRectangle->setMaterial("FadeInOutMaterial");
|
||||||
|
mRectangle->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY-1);
|
||||||
|
// Use infinite AAB to always stay visible
|
||||||
|
Ogre::AxisAlignedBox aabInf;
|
||||||
|
aabInf.setInfinite();
|
||||||
|
mRectangle->setBoundingBox(aabInf);
|
||||||
|
// Attach background to the scene
|
||||||
|
Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
|
||||||
|
node->attachObject(mRectangle);
|
||||||
|
mRectangle->setVisible(false);
|
||||||
|
mRectangle->setVisibilityFlags (0x01);
|
||||||
|
}
|
||||||
|
|
||||||
mOverlay = ovm.create( FADE_OVERLAY_NAME );
|
Fader::~Fader()
|
||||||
|
{
|
||||||
OverlayContainer* overlay_panel;
|
delete mRectangle;
|
||||||
overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", FADE_OVERLAY_PANEL_NAME);
|
|
||||||
|
|
||||||
// position it over the whole screen
|
|
||||||
overlay_panel->_setPosition(0, 0);
|
|
||||||
overlay_panel->_setDimensions(1, 1);
|
|
||||||
|
|
||||||
overlay_panel->setMaterialName( FADE_MATERIAL_NAME );
|
|
||||||
overlay_panel->show();
|
|
||||||
mOverlay->add2D(overlay_panel);
|
|
||||||
mOverlay->hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fader::update(float dt)
|
void Fader::update(float dt)
|
||||||
|
@ -69,12 +67,12 @@ void Fader::update(float dt)
|
||||||
mRemainingTime -= dt;
|
mRemainingTime -= dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCurrentAlpha == 0.f) mOverlay->hide();
|
if (mCurrentAlpha == 0.f) mRectangle->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fader::applyAlpha()
|
void Fader::applyAlpha()
|
||||||
{
|
{
|
||||||
mOverlay->show();
|
mRectangle->setVisible(true);
|
||||||
mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, mCurrentAlpha);
|
mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, mCurrentAlpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,14 @@
|
||||||
/*
|
/*
|
||||||
A class that handles fading in the screen from black or fading it out to black.
|
A class that handles fading in the screen from black or fading it out to black.
|
||||||
|
|
||||||
To achieve this, it uses a full-screen Ogre::Overlay
|
To achieve this, it uses a full-screen Rectangle2d
|
||||||
|
|
||||||
inspired by http://www.ogre3d.org/tikiwiki/FadeEffectOverlay (heavily adjusted)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class TextureUnitState;
|
class TextureUnitState;
|
||||||
class Overlay;
|
class Rectangle2D;
|
||||||
|
class SceneManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace OEngine {
|
namespace OEngine {
|
||||||
|
@ -21,7 +20,8 @@ namespace Render
|
||||||
class Fader
|
class Fader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Fader();
|
Fader(Ogre::SceneManager* sceneMgr);
|
||||||
|
~Fader();
|
||||||
|
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ namespace Render
|
||||||
void applyAlpha();
|
void applyAlpha();
|
||||||
|
|
||||||
Ogre::TextureUnitState* mFadeTextureUnit;
|
Ogre::TextureUnitState* mFadeTextureUnit;
|
||||||
Ogre::Overlay* mOverlay;
|
Ogre::Rectangle2D* mRectangle;
|
||||||
|
|
||||||
FadingMode mMode;
|
FadingMode mMode;
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ namespace Render
|
||||||
float mCurrentAlpha;
|
float mCurrentAlpha;
|
||||||
float mStartAlpha;
|
float mStartAlpha;
|
||||||
|
|
||||||
protected:
|
Ogre::SceneManager* mSceneMgr;
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,8 +44,10 @@ void OgreRenderer::cleanup()
|
||||||
delete mFader;
|
delete mFader;
|
||||||
mFader = NULL;
|
mFader = NULL;
|
||||||
|
|
||||||
OGRE_DELETE mRoot;
|
delete mRoot;
|
||||||
mRoot = NULL;
|
mRoot = NULL;
|
||||||
|
|
||||||
|
unloadPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgreRenderer::start()
|
void OgreRenderer::start()
|
||||||
|
@ -78,7 +80,7 @@ void OgreRenderer::start()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OgreRenderer::loadPlugins()
|
void OgreRenderer::loadPlugins()
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_PLUGIN_GL
|
#ifdef ENABLE_PLUGIN_GL
|
||||||
mGLPlugin = new Ogre::GLPlugin();
|
mGLPlugin = new Ogre::GLPlugin();
|
||||||
|
@ -100,7 +102,30 @@ bool OgreRenderer::loadPlugins()
|
||||||
mParticleFXPlugin = new Ogre::ParticleFXPlugin();
|
mParticleFXPlugin = new Ogre::ParticleFXPlugin();
|
||||||
mRoot->installPlugin(mParticleFXPlugin);
|
mRoot->installPlugin(mParticleFXPlugin);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
void OgreRenderer::unloadPlugins()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_PLUGIN_GL
|
||||||
|
delete mGLPlugin;
|
||||||
|
mGLPlugin = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_PLUGIN_Direct3D9
|
||||||
|
delete mD3D9Plugin;
|
||||||
|
mD3D9Plugin = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_PLUGIN_CgProgramManager
|
||||||
|
delete mCgPlugin;
|
||||||
|
mCgPlugin = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_PLUGIN_OctreeSceneManager
|
||||||
|
delete mOctreePlugin;
|
||||||
|
mOctreePlugin = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_PLUGIN_ParticleFX
|
||||||
|
delete mParticleFXPlugin;
|
||||||
|
mParticleFXPlugin = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgreRenderer::update(float dt)
|
void OgreRenderer::update(float dt)
|
||||||
|
@ -120,6 +145,7 @@ float OgreRenderer::getFPS()
|
||||||
|
|
||||||
void OgreRenderer::configure(const std::string &logPath,
|
void OgreRenderer::configure(const std::string &logPath,
|
||||||
const std::string& renderSystem,
|
const std::string& renderSystem,
|
||||||
|
const std::string& rttMode,
|
||||||
bool _logging)
|
bool _logging)
|
||||||
{
|
{
|
||||||
// Set up logging first
|
// Set up logging first
|
||||||
|
@ -173,6 +199,9 @@ void OgreRenderer::configure(const std::string &logPath,
|
||||||
if (rs == 0)
|
if (rs == 0)
|
||||||
throw std::runtime_error ("RenderSystem with name " + renderSystem + " not found, make sure the plugins are loaded");
|
throw std::runtime_error ("RenderSystem with name " + renderSystem + " not found, make sure the plugins are loaded");
|
||||||
mRoot->setRenderSystem(rs);
|
mRoot->setRenderSystem(rs);
|
||||||
|
|
||||||
|
if (rs->getName().find("OpenGL") != std::string::npos)
|
||||||
|
rs->setConfigOption ("RTT Preferred Mode", rttMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgreRenderer::createWindow(const std::string &title, const WindowSettings& settings)
|
void OgreRenderer::createWindow(const std::string &title, const WindowSettings& settings)
|
||||||
|
@ -218,7 +247,7 @@ void OgreRenderer::createScene(const std::string& camName, float fov, float near
|
||||||
// Alter the camera aspect ratio to match the viewport
|
// Alter the camera aspect ratio to match the viewport
|
||||||
mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight()));
|
mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight()));
|
||||||
|
|
||||||
mFader = new Fader();
|
mFader = new Fader(mScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgreRenderer::adjustViewport()
|
void OgreRenderer::adjustViewport()
|
||||||
|
|
|
@ -132,6 +132,7 @@ namespace OEngine
|
||||||
void configure(
|
void configure(
|
||||||
const std::string &logPath, // Path to directory where to store log files
|
const std::string &logPath, // Path to directory where to store log files
|
||||||
const std::string &renderSystem,
|
const std::string &renderSystem,
|
||||||
|
const std::string &rttMode,
|
||||||
bool _logging); // Enable or disable logging
|
bool _logging); // Enable or disable logging
|
||||||
|
|
||||||
/// Create a window with the given title
|
/// Create a window with the given title
|
||||||
|
@ -151,7 +152,9 @@ namespace OEngine
|
||||||
/// Start the main rendering loop
|
/// Start the main rendering loop
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
bool loadPlugins() ;
|
void loadPlugins();
|
||||||
|
|
||||||
|
void unloadPlugins();
|
||||||
|
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <OgreRenderTexture.h>
|
#include <OgreRenderTexture.h>
|
||||||
#include <OgreSubEntity.h>
|
#include <OgreSubEntity.h>
|
||||||
#include <OgreEntity.h>
|
#include <OgreEntity.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <extern/shiny/Main/Factory.hpp>
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ namespace Render
|
||||||
int id = Ogre::any_cast<int>(subEntity->getParent ()->getUserObjectBindings().getUserAny());
|
int id = Ogre::any_cast<int>(subEntity->getParent ()->getUserObjectBindings().getUserAny());
|
||||||
bool found = false;
|
bool found = false;
|
||||||
Ogre::ColourValue colour;
|
Ogre::ColourValue colour;
|
||||||
for (std::map<Ogre::ColourValue, int>::iterator it = mColourMap.begin(); it != mColourMap.end(); ++it)
|
for (std::map<Ogre::ColourValue, int, cmp_ColourValue>::iterator it = mColourMap.begin(); it != mColourMap.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->second == id)
|
if (it->second == id)
|
||||||
{
|
{
|
||||||
|
|
35
readme.txt
35
readme.txt
|
@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind
|
||||||
OpenMW is an attempt at recreating the engine for the popular role-playing game
|
OpenMW is an attempt at recreating the engine for the popular role-playing game
|
||||||
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
|
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
|
||||||
|
|
||||||
Version: 0.17.0
|
Version: 0.18.0
|
||||||
License: GPL (see GPL3.txt for more information)
|
License: GPL (see GPL3.txt for more information)
|
||||||
Website: http://www.openmw.org
|
Website: http://www.openmw.org
|
||||||
|
|
||||||
|
@ -97,6 +97,39 @@ Allowed options:
|
||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
0.18.0
|
||||||
|
|
||||||
|
Bug #310: Button of the "preferences menu" are too small
|
||||||
|
Bug #361: Hand-to-hand skill is always 100
|
||||||
|
Bug #365: NPC and creature animation is jerky; Characters float around when they are not supposed to
|
||||||
|
Bug #372: playSound3D uses original coordinates instead of current coordinates.
|
||||||
|
Bug #373: Static OGRE build faulty
|
||||||
|
Bug #375: Alt-tab toggle view
|
||||||
|
Bug #376: Screenshots are disable
|
||||||
|
Bug #378: Exception when drinking self-made potions
|
||||||
|
Bug #380: Cloth visibility problem
|
||||||
|
Bug #384: Weird character on doors tooltip.
|
||||||
|
Bug #398: Some objects do not collide in MW, but do so in OpenMW
|
||||||
|
Feature #22: Implement level-up
|
||||||
|
Feature #36: Hide Marker
|
||||||
|
Feature #88: Hotkey Window
|
||||||
|
Feature #91: Level-Up Dialogue
|
||||||
|
Feature #118: Keyboard and Mouse-Button bindings
|
||||||
|
Feature #119: Spell Buying Window
|
||||||
|
Feature #133: Handle resources across multiple data directories
|
||||||
|
Feature #134: Generate a suitable default-value for --data-local
|
||||||
|
Feature #292: Object Movement/Creation Script Instructions
|
||||||
|
Feature #340: AIPackage data structures
|
||||||
|
Feature #356: Ingredients use
|
||||||
|
Feature #358: Input system rewrite
|
||||||
|
Feature #370: Target handling in actions
|
||||||
|
Feature #379: Door markers on the local map
|
||||||
|
Feature #389: AI framework
|
||||||
|
Feature #395: Using keys to open doors / containers
|
||||||
|
Feature #396: Loading screens
|
||||||
|
Feature #397: Inventory avatar image and race selection head preview
|
||||||
|
Task #339: Move sounds into Action
|
||||||
|
|
||||||
0.17.0
|
0.17.0
|
||||||
|
|
||||||
Bug #225: Valgrind reports about 40MB of leaked memory
|
Bug #225: Valgrind reports about 40MB of leaked memory
|
||||||
|
|
Loading…
Reference in a new issue