Merge branch 'master' of git://github.com/zinnschlag/openmw.git into collisions

Conflicts:
	apps/openmw/mwclass/npc.cpp
pull/21/head
gugus 14 years ago
commit 0fb2107265

@ -12,9 +12,15 @@ if(DPKG_PROGRAM)
set(MORROWIND_DATA_FILES "/usr/share/games/openmw/data/" CACHE PATH "location of Morrowind data files") set(MORROWIND_DATA_FILES "/usr/share/games/openmw/data/" CACHE PATH "location of Morrowind data files")
set(MORROWIND_RESOURCE_FILES "/usr/share/games/openmw/resources/" CACHE PATH "location of Morrowind data files") set(MORROWIND_RESOURCE_FILES "/usr/share/games/openmw/resources/" CACHE PATH "location of Morrowind data files")
else() else()
set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files") if (APPLE)
set(MORROWIND_RESOURCE_FILES "resources" CACHE PATH "location of Morrowind data files") # set path inside bundle
endif() set(MORROWIND_DATA_FILES "Contents/Resources/data" CACHE PATH "location of Morrowind data files")
set(MORROWIND_RESOURCE_FILES "Contents/Resources/resources" CACHE PATH "location of Morrowind data files")
else()
set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files")
set(MORROWIND_RESOURCE_FILES "resources" CACHE PATH "location of Morrowind data files")
endif(APPLE)
endif(DPKG_PROGRAM)
if (WIN32) if (WIN32)
option(USE_DEBUG_CONSOLE "whether a debug console should be enabled for debug builds, if false debug output is redirected to Visual Studio output" ON) option(USE_DEBUG_CONSOLE "whether a debug console should be enabled for debug builds, if false debug output is redirected to Visual Studio output" ON)
@ -23,7 +29,6 @@ endif()
# We probably support older versions than this. # We probably support older versions than this.
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
# #
# Pre-built binaries being used? # Pre-built binaries being used?
# #
@ -239,6 +244,10 @@ if (MSVC10)
add_definitions(-DMYGUI_DONT_REPLACE_NULLPTR) add_definitions(-DMYGUI_DONT_REPLACE_NULLPTR)
endif() endif()
if (APPLE)
set(Boost_USE_STATIC_LIBS ON)
endif (APPLE)
# Dependencies # Dependencies
find_package(OGRE REQUIRED) find_package(OGRE REQUIRED)
@ -282,21 +291,19 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}")
if (WIN32) if (WIN32)
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.win32 configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.win32
"${OpenMW_BINARY_DIR}/plugins.cfg" COPYONLY) "${OpenMW_BINARY_DIR}/plugins.cfg" COPYONLY)
else (WIN32) endif (WIN32)
if (LINUX)
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.linux configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.linux
"${OpenMW_BINARY_DIR}/plugins.cfg") "${OpenMW_BINARY_DIR}/plugins.cfg")
endif (WIN32) endif (LINUX)
if (APPLE)
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac
"${OpenMW_BINARY_DIR}/plugins.cfg")
endif (APPLE)
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
"${OpenMW_BINARY_DIR}/openmw.cfg") "${OpenMW_BINARY_DIR}/openmw.cfg")
if (APPLE)
set(APPLE_BUNDLE_RESOURCES
${CMAKE_SOURCE_DIR}/files/openmw.cfg
${CMAKE_SOURCE_DIR}/files/mac/plugins.cfg
)
endif (APPLE)
# Compiler settings # Compiler settings
if (CMAKE_COMPILER_IS_GNUCC) if (CMAKE_COMPILER_IS_GNUCC)
#add_definitions (-Wall -Werror) #add_definitions (-Wall -Werror)
@ -306,21 +313,17 @@ endif (CMAKE_COMPILER_IS_GNUCC)
# Apple bundling # Apple bundling
if (APPLE) if (APPLE)
set(MISC_FILES set(MISC_FILES
${CMAKE_SOURCE_DIR}/files/openmw.cfg ${OpenMW_BINARY_DIR}/openmw.cfg
${CMAKE_SOURCE_DIR}/files/mac/plugins.cfg ${OpenMW_BINARY_DIR}/plugins.cfg)
${CMAKE_SOURCE_DIR}/files/mac/ogre.cfg)
install(TARGETS openmw
BUNDLE DESTINATION .
RUNTIME DESTINATION ../MacOS
COMPONENT Runtime)
install(FILES ${MISC_FILES} DESTINATION ../MacOS) install(FILES ${MISC_FILES} DESTINATION ../MacOS)
install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ../Resources)
set(CPACK_GENERATOR "Bundle") set(CPACK_GENERATOR "Bundle")
set(CPACK_BUNDLE_PLIST "${CMAKE_SOURCE_DIR}/files/mac/Info.plist") set(CPACK_BUNDLE_PLIST "${CMAKE_SOURCE_DIR}/files/mac/Info.plist")
set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/files/mac/openmw.icns") set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/files/mac/openmw.icns")
set(CPACK_BUNDLE_NAME "OpenMW") set(CPACK_BUNDLE_NAME "OpenMW")
set(CPACK_PACKAGE_VERSION "0.07") set(CPACK_PACKAGE_VERSION "0.10")
set(CPACK_PACKAGE_VERSION_MAJOR "0") set(CPACK_PACKAGE_VERSION_MAJOR "0")
set(CPACK_PACKAGE_VERSION_MINOR "07") set(CPACK_PACKAGE_VERSION_MINOR "10")
set(CPACK_PACKAGE_VERSION_PATCH "") set(CPACK_PACKAGE_VERSION_PATCH "")
include(CPack) include(CPack)

@ -29,22 +29,28 @@ Getting OpenMW Working
---------------------- ----------------------
1. Clone this repository. 1. Clone this repository.
2. Install `bjam` through MacPorts. 2. Note about libs: I prefer not to install them globally (i. e. in /usr/local/), so I installing them in directory in my home directory. If OpenMW sources is in $HOME/path/openmw, I'm using $HOME/path/libs/root as prefix for boost and other libs.
3. Download [boost][] 1.43 and install it with the following command: It's useful to create env var for lib install prefix:
$ export OMW_LIB_PREFIX=$HOME/path/libs/root
$ mkdir build && sudo bjam --build-dir=build \ 3. First of all, set for current terminal some env vars:
--layout=versioned --toolset=darwin architecture=i386 \ $ export CFLAGS="-arch i386"
address-model=32 --link=shared,static install $ export CXXFLAGS="-arch i386"
$ export LDFLAGS="-arch i386"
All libs will build with correct architecture.
If you close your terminal, you should set env vars again before pcoceeding to next steps!
4. Download [boost][] (tested with 1.45) and install it with the following command:
4. Download [Ogre][] 1.7.1 and build and Xcode project with CMake: $ cd /path/to/boost/source
$ ./bootstrap.sh --prefix=$OMW_LIB_PREFIX
$ ./bjam --build-dir=build --layout=versioned \
--toolset=darwin architecture=x86 address-model=32 \
--link-shared,static --prefix=$OMW_LIB_PREFIX install
$ mdkir build && cd build && \
BOOST_INCLUDEDIR=/usr/local/include/boost-1_43 \
BOOST_LIBRARYDIR=/usr/local/lib cmake -G Xcode ..
5. Once the build completes, move `lib/Release/Ogre.framework` into 5. Download [Ogre][] SDK (tested with 1.7.2) and move `lib/Release/Ogre.framework` into
`/Library/Frameworks`. `Library/Frameworks`.
6. Download [OIS][] and use the XCode project provided in 6. Download [OIS][] and use the XCode project provided in
`ois/Mac/XCode-2.2`. Be sure to set your build architecture to `ois/Mac/XCode-2.2`. Be sure to set your build architecture to
@ -52,20 +58,66 @@ Getting OpenMW Working
builds, move `ois/Mac/XCode-2.2/build/Debug/OIS.framework` to builds, move `ois/Mac/XCode-2.2/build/Debug/OIS.framework` to
`/Library/Frameworks`. `/Library/Frameworks`.
7. Generate the Makefile for OpenMW as follows: 7. Download [mpg123][] and build it:
$ cd /path/to/mpg123/source
$ mkdir build && cd build && \ $ ./configure --prefix=$OMW_LIB_PREFIX --disable-debug \
BOOST_INCLUDEDIR=/usr/local/include/boost-1_43 \ --disable-dependency-tracking \
BOOST_LIBRARYDIR=/usr/local/lib CMAKE_OSX_ARCHITECTURES=i386 \ --with-optimization=4 \
cmake .. --with-audio=coreaudio \
--with-default-audio=coreaudio \
8. Move your Morrowind `Data Files` directory into the root `openmw` --with-cpu=sse_alone \
directory with the name `data`. Symlink it into the build directory. $ make install
$ cd build && ln -s ../data data 8. Download [libsndfile][] and build it:
$ cd /path/to/libsndfile/source
$ ./configure --prefix=$OMW_LIB_PREFIX \
--disable-dependency-tracking
$ make install
7. Generate the Makefile for OpenMW as follows and build OpenMW:
$ mkdir /path/to/openmw/build/dir
$ cd /path/to/open/build/dir
$ CMAKE_OSX_ARCHITECTURES=i386 \
BOOST_INCLUDEDIR=$OMW_LIB_PREFIX/include/boost-1_45 \
BOOST_LIBRARYDIR=$OMW_LIB_PREFIX/lib \
cmake -D SNDFILE_INCLUDE_DIR=$OMW_LIB_PREFIX/include \
-D SNDFILE_LIBRARY=$OMW_LIB_PREFIX/lib/libsndfile.a \
-D MPG123_INCLUDE_DIR=$OMW_LIB_PREFIX/include \
-D MPG123_LIBRARY=$OMW_LIB_PREFIX/lib/libmpg123.a \
-G "Unix Makefiles" /path/to/openmw/source
$ make
8. In build directory create directory for game resources:
$ cd /path/to/openmw/build/dir
$ mkdir Contents
$ mkdir Contents/Resources
$ mkdir Contents/Plugins
Copy Ogre plugins from Ogre SDK to Plugins subdir:
$ cp /path/to/ogre/sdk/lib/*.dylib Contents/Plugins
Create symlink to resources subdirectory:
$ ln -s resources Contents/Resources/resources
Create symlinks for *.cfg files:
$ ln -s plugins.cfg Contents/MacOS/plugins.cfg
$ ln -s openmw.cfg Contents/MacOS/openmw.cfg
9. Move your Morrowind `Data Files` directory into the `Contents/Resources`
with the name `data` or create symlink:
$ ln -s /path/to/morrowind/data/files Contents/Resources/data
10. From your build directory run:
$ ./openmw
Enjoy!
11. Optionally you can create .app bundle:
$ make package
But for now you shold manually copy Contents directory from build directory to bundle
(because there is no plugins and resources in generated .app).
[boost]: http://www.boost.org [boost]: http://www.boost.org
[Ogre]: http://www.ogre3d.org [Ogre]: http://www.ogre3d.org
[OIS]: http://wgois.sf.net [OIS]: http://wgois.sf.net
[mpg123]: http://www.mpg123.de
[libsndfile]: http://www.mega-nerd.com/libsndfile
[official website]: http://openmw.com [official website]: http://openmw.com
[Will Thimbleby's Ogre Framework]: http://www.thimbleby.net/ogre/ [Will Thimbleby's Ogre Framework]: http://www.thimbleby.net/ogre/

@ -49,6 +49,7 @@ set(GAMEGUI_HEADER
mwgui/dialogue.hpp mwgui/dialogue.hpp
mwgui/dialogue_history.hpp mwgui/dialogue_history.hpp
mwgui/window_base.hpp mwgui/window_base.hpp
mwgui/stats_window.hpp
) )
set(GAMEGUI set(GAMEGUI
mwgui/window_manager.cpp mwgui/window_manager.cpp
@ -63,6 +64,7 @@ set(GAMEGUI
mwgui/dialogue.cpp mwgui/dialogue.cpp
mwgui/dialogue_history.cpp mwgui/dialogue_history.cpp
mwgui/window_base.cpp mwgui/window_base.cpp
mwgui/stats_window.cpp
) )
source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI}) source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI})
@ -247,6 +249,10 @@ target_link_libraries(openmw
if (APPLE) if (APPLE)
find_library(CARBON_FRAMEWORK Carbon) find_library(CARBON_FRAMEWORK Carbon)
target_link_libraries(openmw ${CARBON_FRAMEWORK}) target_link_libraries(openmw ${CARBON_FRAMEWORK})
install(TARGETS openmw
BUNDLE DESTINATION .
RUNTIME DESTINATION ../MacOS
COMPONENT Runtime)
endif (APPLE) endif (APPLE)
if(DPKG_PROGRAM) if(DPKG_PROGRAM)

@ -41,6 +41,10 @@
#include <OgreRoot.h> #include <OgreRoot.h>
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <OSX/macUtils.h>
#endif
#include <MyGUI_WidgetManager.h> #include <MyGUI_WidgetManager.h>
#include "mwgui/class.hpp" #include "mwgui/class.hpp"
#include "path.hpp" #include "path.hpp"
@ -71,6 +75,11 @@ void OMW::Engine::executeLocalScripts()
bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
{ {
if(mShowFPS)
{
mEnvironment.mWindowManager->wmSetFPS(mOgre.getFPS());
}
if(mUseSound && !(mEnvironment.mSoundManager->isMusicPlaying())) if(mUseSound && !(mEnvironment.mSoundManager->isMusicPlaying()))
{ {
// Play some good 'ol tunes // Play some good 'ol tunes
@ -196,7 +205,8 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
} }
OMW::Engine::Engine() OMW::Engine::Engine()
: mDebug (false) : mShowFPS (false)
, mDebug (false)
, mVerboseScripts (false) , mVerboseScripts (false)
, mNewGame (false) , mNewGame (false)
, mUseSound (true) , mUseSound (true)
@ -360,7 +370,7 @@ void OMW::Engine::go()
MWScript::registerExtensions (mExtensions); MWScript::registerExtensions (mExtensions);
mEnvironment.mWindowManager = new MWGui::WindowManager(mGuiManager->getGui(), mEnvironment, mEnvironment.mWindowManager = new MWGui::WindowManager(mGuiManager->getGui(), mEnvironment,
mExtensions, mNewGame); mExtensions, mShowFPS, mNewGame);
// Create sound system // Create sound system
mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre.getRoot(), mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre.getRoot(),

@ -63,6 +63,7 @@ namespace OMW
OEngine::Physic::PhysicEngine* mPhysicEngine; OEngine::Physic::PhysicEngine* mPhysicEngine;
std::string mCellName; std::string mCellName;
std::string mMaster; std::string mMaster;
bool mShowFPS;
bool mDebug; bool mDebug;
bool mVerboseScripts; bool mVerboseScripts;
bool mNewGame; bool mNewGame;
@ -121,6 +122,9 @@ namespace OMW
/// - Currently OpenMW only supports one master at the same time. /// - Currently OpenMW only supports one master at the same time.
void addMaster (const std::string& master); void addMaster (const std::string& master);
/// Enable fps counter
void showFPS() { mShowFPS = true; }
/// Enable debug mode: /// Enable debug mode:
/// - non-exclusive input /// - non-exclusive input
void enableDebugMode(); void enableDebugMode();

@ -49,6 +49,7 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
"set initial cell") "set initial cell")
("master", bpo::value<std::string>()->default_value ("Morrowind"), ("master", bpo::value<std::string>()->default_value ("Morrowind"),
"master file") "master file")
( "showfps", "show fps counter")
( "debug", "debug mode" ) ( "debug", "debug mode" )
( "nosound", "disable all sound" ) ( "nosound", "disable all sound" )
( "script-verbose", "verbose script output" ) ( "script-verbose", "verbose script output" )
@ -87,6 +88,9 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
engine.setCell (variables["start"].as<std::string>()); engine.setCell (variables["start"].as<std::string>());
engine.addMaster (variables["master"].as<std::string>()); engine.addMaster (variables["master"].as<std::string>());
if (variables.count ("showfps"))
engine.showFPS();
if (variables.count ("debug")) if (variables.count ("debug"))
engine.enableDebugMode(); engine.enableDebugMode();
@ -107,6 +111,11 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
int main(int argc, char**argv) int main(int argc, char**argv)
{ {
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
// set current dir to bundle path
boost::filesystem::path bundlePath = boost::filesystem::path(Ogre::macBundlePath());
boost::filesystem::current_path(bundlePath);
#endif
try try
{ {

@ -75,7 +75,6 @@ namespace MWClass
std::string upperleft[5] = {"", "", "", "", ""}; std::string upperleft[5] = {"", "", "", "", ""};
std::string upperright[5] = {"", "", "", "", ""}; std::string upperright[5] = {"", "", "", "", ""};
std::string neckandup[5] = {"", "", "","",""}; std::string neckandup[5] = {"", "", "","",""};
std::string empty[6] = {"", "", "", "","", ""};
int numbers = 0; int numbers = 0;
int uppernumbers = 0; int uppernumbers = 0;
int neckNumbers = 0; int neckNumbers = 0;
@ -110,7 +109,6 @@ namespace MWClass
//std::cout << "RACE" << bodyRaceID << "\n"; //std::cout << "RACE" << bodyRaceID << "\n";
Ogre::Vector3 pos2 = Ogre::Vector3( 0, .5, 75); Ogre::Vector3 pos2 = Ogre::Vector3( 0, .5, 75);
std::string upperarmpath[2] = {npcName + "chest", npcName + "upper arm"};
if (groin){ if (groin){
cellRender.insertMesh("meshes\\" + groin->model, pos2, axis, kOgrePi, npcName + "groin", addresses, numbers); cellRender.insertMesh("meshes\\" + groin->model, pos2, axis, kOgrePi, npcName + "groin", addresses, numbers);
@ -181,7 +179,7 @@ namespace MWClass
upperleft[uppernumbers] = npcName + "upper arm"; upperleft[uppernumbers] = npcName + "upper arm";
upperright[uppernumbers++] = npcName + "upper arm2"; upperright[uppernumbers++] = npcName + "upper arm2";
cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperleft, uppernumbers); //1 -1 1 cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperleft, uppernumbers); //1 -1 1
cellRender.rotateMesh(Ogre::Vector3(0, 1, 0), kOgrePiOverTwo, upperleft, uppernumbers); cellRender.rotateMesh(Ogre::Vector3(0, .1, 0), kOgrePiOverTwo, upperleft, uppernumbers);
} }
if (forearm) if (forearm)

@ -1,6 +1,4 @@
#include "birth.hpp" #include "birth.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
@ -11,8 +9,8 @@
using namespace MWGui; using namespace MWGui;
using namespace Widgets; using namespace Widgets;
BirthDialog::BirthDialog(MWWorld::Environment& environment) BirthDialog::BirthDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_birth_layout.xml", environment) : WindowBase("openmw_chargen_birth_layout.xml", parWindowManager)
{ {
// Centre dialog // Centre dialog
center(); center();
@ -94,7 +92,7 @@ void BirthDialog::setBirthId(const std::string &birthId)
void BirthDialog::onOkClicked(MyGUI::Widget* _sender) void BirthDialog::onOkClicked(MyGUI::Widget* _sender)
{ {
eventDone(); eventDone(this);
} }
void BirthDialog::onBackClicked(MyGUI::Widget* _sender) void BirthDialog::onBackClicked(MyGUI::Widget* _sender)
@ -121,7 +119,7 @@ void BirthDialog::updateBirths()
{ {
birthList->removeAllItems(); birthList->removeAllItems();
ESMS::ESMStore &store = environment.mWorld->getStore(); ESMS::ESMStore &store = mWindowManager.getStore();
ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator it = store.birthSigns.list.begin(); ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator it = store.birthSigns.list.begin();
ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator end = store.birthSigns.list.end(); ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator end = store.birthSigns.list.end();
@ -151,7 +149,7 @@ void BirthDialog::updateSpells()
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, spellArea->getWidth(), 18); MyGUI::IntCoord coord(0, 0, spellArea->getWidth(), 18);
ESMS::ESMStore &store = environment.mWorld->getStore(); ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::BirthSign *birth = store.birthSigns.find(currentBirthId); const ESM::BirthSign *birth = store.birthSigns.find(currentBirthId);
std::string texturePath = std::string("textures\\") + birth->texture; std::string texturePath = std::string("textures\\") + birth->texture;
@ -191,7 +189,7 @@ void BirthDialog::updateSpells()
if (!categories[category].spells.empty()) if (!categories[category].spells.empty())
{ {
MyGUI::StaticTextPtr label = spellArea->createWidget<MyGUI::StaticText>("SandBrightText", coord, MyGUI::Align::Default, std::string("Label")); MyGUI::StaticTextPtr label = spellArea->createWidget<MyGUI::StaticText>("SandBrightText", coord, MyGUI::Align::Default, std::string("Label"));
label->setCaption(environment.mWindowManager->getGameSettingString(categories[category].label, "")); label->setCaption(mWindowManager.getGameSettingString(categories[category].label, ""));
spellItems.push_back(label); spellItems.push_back(label);
coord.top += lineHeight; coord.top += lineHeight;
@ -200,7 +198,7 @@ void BirthDialog::updateSpells()
{ {
const std::string &spellId = *it; const std::string &spellId = *it;
spellWidget = spellArea->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + boost::lexical_cast<std::string>(i)); spellWidget = spellArea->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + boost::lexical_cast<std::string>(i));
spellWidget->setEnvironment(&environment); spellWidget->setWindowManager(&mWindowManager);
spellWidget->setSpellId(spellId); spellWidget->setSpellId(spellId);
spellItems.push_back(spellWidget); spellItems.push_back(spellWidget);

@ -3,11 +3,6 @@
#include "window_base.hpp" #include "window_base.hpp"
namespace MWWorld
{
class Environment;
}
/* /*
This file contains the dialog for choosing a birth sign. This file contains the dialog for choosing a birth sign.
Layout is defined by resources/mygui/openmw_chargen_race_layout.xml. Layout is defined by resources/mygui/openmw_chargen_race_layout.xml.
@ -17,10 +12,12 @@ namespace MWGui
{ {
using namespace MyGUI; using namespace MyGUI;
class WindowManager;
class BirthDialog : public WindowBase class BirthDialog : public WindowBase
{ {
public: public:
BirthDialog(MWWorld::Environment& environment); BirthDialog(WindowManager& parWindowManager);
enum Gender enum Gender
{ {
@ -42,11 +39,6 @@ namespace MWGui
*/ */
EventHandle_Void eventBack; EventHandle_Void eventBack;
/** Event : Dialog finished, OK button clicked.\n
signature : void method()\n
*/
EventHandle_Void eventDone;
protected: protected:
void onSelectBirth(MyGUI::List* _sender, size_t _index); void onSelectBirth(MyGUI::List* _sender, size_t _index);

@ -1,6 +1,4 @@
#include "class.hpp" #include "class.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
@ -17,14 +15,13 @@ using namespace MWGui;
/* GenerateClassResultDialog */ /* GenerateClassResultDialog */
GenerateClassResultDialog::GenerateClassResultDialog(MWWorld::Environment& environment) GenerateClassResultDialog::GenerateClassResultDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_generate_class_result_layout.xml", environment) : WindowBase("openmw_chargen_generate_class_result_layout.xml", parWindowManager)
{ {
// Centre dialog // Centre dialog
center(); center();
WindowManager *wm = environment.mWindowManager; setText("ReflectT", mWindowManager.getGameSettingString("sMessageQuestionAnswer1", ""));
setText("ReflectT", wm->getGameSettingString("sMessageQuestionAnswer1", ""));
getWidget(classImage, "ClassImage"); getWidget(classImage, "ClassImage");
getWidget(className, "ClassName"); getWidget(className, "ClassName");
@ -53,7 +50,7 @@ void GenerateClassResultDialog::setClassId(const std::string &classId)
{ {
currentClassId = classId; currentClassId = classId;
classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds"); classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds");
ESMS::ESMStore &store = environment.mWorld->getStore(); ESMS::ESMStore &store = mWindowManager.getStore();
className->setCaption(store.classes.find(currentClassId)->name); className->setCaption(store.classes.find(currentClassId)->name);
} }
@ -61,7 +58,7 @@ void GenerateClassResultDialog::setClassId(const std::string &classId)
void GenerateClassResultDialog::onOkClicked(MyGUI::Widget* _sender) void GenerateClassResultDialog::onOkClicked(MyGUI::Widget* _sender)
{ {
eventDone(); eventDone(this);
} }
void GenerateClassResultDialog::onBackClicked(MyGUI::Widget* _sender) void GenerateClassResultDialog::onBackClicked(MyGUI::Widget* _sender)
@ -71,31 +68,30 @@ void GenerateClassResultDialog::onBackClicked(MyGUI::Widget* _sender)
/* PickClassDialog */ /* PickClassDialog */
PickClassDialog::PickClassDialog(MWWorld::Environment& environment) PickClassDialog::PickClassDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_class_layout.xml", environment) : WindowBase("openmw_chargen_class_layout.xml", parWindowManager)
{ {
// Centre dialog // Centre dialog
center(); center();
WindowManager *wm = environment.mWindowManager; setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization"));
setText("SpecializationT", wm->getGameSettingString("sChooseClassMenu1", "Specialization"));
getWidget(specializationName, "SpecializationName"); getWidget(specializationName, "SpecializationName");
setText("FavoriteAttributesT", wm->getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:"));
getWidget(favoriteAttribute[0], "FavoriteAttribute0"); getWidget(favoriteAttribute[0], "FavoriteAttribute0");
getWidget(favoriteAttribute[1], "FavoriteAttribute1"); getWidget(favoriteAttribute[1], "FavoriteAttribute1");
favoriteAttribute[0]->setWindowManager(wm); favoriteAttribute[0]->setWindowManager(&mWindowManager);
favoriteAttribute[1]->setWindowManager(wm); favoriteAttribute[1]->setWindowManager(&mWindowManager);
setText("MajorSkillT", wm->getGameSettingString("sChooseClassMenu3", "Major Skills:")); setText("MajorSkillT", mWindowManager.getGameSettingString("sChooseClassMenu3", "Major Skills:"));
setText("MinorSkillT", wm->getGameSettingString("sChooseClassMenu4", "Minor Skills:")); setText("MinorSkillT", mWindowManager.getGameSettingString("sChooseClassMenu4", "Minor Skills:"));
for(int i = 0; i < 5; i++) for(int i = 0; i < 5; i++)
{ {
char theIndex = '0'+i; char theIndex = '0'+i;
getWidget(majorSkill[i], std::string("MajorSkill").append(1, theIndex)); getWidget(majorSkill[i], std::string("MajorSkill").append(1, theIndex));
getWidget(minorSkill[i], std::string("MinorSkill").append(1, theIndex)); getWidget(minorSkill[i], std::string("MinorSkill").append(1, theIndex));
majorSkill[i]->setWindowManager(wm); majorSkill[i]->setWindowManager(&mWindowManager);
minorSkill[i]->setWindowManager(wm); minorSkill[i]->setWindowManager(&mWindowManager);
} }
getWidget(classList, "ClassList"); getWidget(classList, "ClassList");
@ -173,7 +169,7 @@ void PickClassDialog::setClassId(const std::string &classId)
void PickClassDialog::onOkClicked(MyGUI::Widget* _sender) void PickClassDialog::onOkClicked(MyGUI::Widget* _sender)
{ {
eventDone(); eventDone(this);
} }
void PickClassDialog::onBackClicked(MyGUI::Widget* _sender) void PickClassDialog::onBackClicked(MyGUI::Widget* _sender)
@ -200,7 +196,7 @@ void PickClassDialog::updateClasses()
{ {
classList->removeAllItems(); classList->removeAllItems();
ESMS::ESMStore &store = environment.mWorld->getStore(); ESMS::ESMStore &store = mWindowManager.getStore();
ESMS::RecListT<ESM::Class>::MapType::const_iterator it = store.classes.list.begin(); ESMS::RecListT<ESM::Class>::MapType::const_iterator it = store.classes.list.begin();
ESMS::RecListT<ESM::Class>::MapType::const_iterator end = store.classes.list.end(); ESMS::RecListT<ESM::Class>::MapType::const_iterator end = store.classes.list.end();
@ -224,8 +220,7 @@ void PickClassDialog::updateStats()
{ {
if (currentClassId.empty()) if (currentClassId.empty())
return; return;
WindowManager *wm = environment.mWindowManager; ESMS::ESMStore &store = mWindowManager.getStore();
ESMS::ESMStore &store = environment.mWorld->getStore();
const ESM::Class *klass = store.classes.search(currentClassId); const ESM::Class *klass = store.classes.search(currentClassId);
if (!klass) if (!klass)
return; return;
@ -237,7 +232,7 @@ void PickClassDialog::updateStats()
"sSpecializationMagic", "sSpecializationMagic",
"sSpecializationStealth" "sSpecializationStealth"
}; };
specializationName->setCaption(wm->getGameSettingString(specIds[specialization], specIds[specialization])); specializationName->setCaption(mWindowManager.getGameSettingString(specIds[specialization], specIds[specialization]));
favoriteAttribute[0]->setAttributeId(klass->data.attribute[0]); favoriteAttribute[0]->setAttributeId(klass->data.attribute[0]);
favoriteAttribute[1]->setAttributeId(klass->data.attribute[1]); favoriteAttribute[1]->setAttributeId(klass->data.attribute[1]);
@ -283,8 +278,8 @@ void InfoBoxDialog::layoutVertically(MyGUI::WidgetPtr widget, int margin)
widget->setSize(width, pos); widget->setSize(width, pos);
} }
InfoBoxDialog::InfoBoxDialog(MWWorld::Environment& environment) InfoBoxDialog::InfoBoxDialog(WindowManager& parWindowManager)
: WindowBase("openmw_infobox_layout.xml", environment) : WindowBase("openmw_infobox_layout.xml", parWindowManager)
, currentButton(-1) , currentButton(-1)
{ {
getWidget(textBox, "TextBox"); getWidget(textBox, "TextBox");
@ -358,7 +353,7 @@ void InfoBoxDialog::onButtonClicked(MyGUI::WidgetPtr _sender)
if (*it == _sender) if (*it == _sender)
{ {
currentButton = i; currentButton = i;
eventButtonSelected(_sender, i); eventButtonSelected(i);
return; return;
} }
++i; ++i;
@ -367,23 +362,22 @@ void InfoBoxDialog::onButtonClicked(MyGUI::WidgetPtr _sender)
/* ClassChoiceDialog */ /* ClassChoiceDialog */
ClassChoiceDialog::ClassChoiceDialog(MWWorld::Environment& environment) ClassChoiceDialog::ClassChoiceDialog(WindowManager& parWindowManager)
: InfoBoxDialog(environment) : InfoBoxDialog(parWindowManager)
{ {
WindowManager *mw = environment.mWindowManager;
setText(""); setText("");
ButtonList buttons; ButtonList buttons;
buttons.push_back(mw->getGameSettingString("sClassChoiceMenu1", "")); buttons.push_back(mWindowManager.getGameSettingString("sClassChoiceMenu1", ""));
buttons.push_back(mw->getGameSettingString("sClassChoiceMenu2", "")); buttons.push_back(mWindowManager.getGameSettingString("sClassChoiceMenu2", ""));
buttons.push_back(mw->getGameSettingString("sClassChoiceMenu3", "")); buttons.push_back(mWindowManager.getGameSettingString("sClassChoiceMenu3", ""));
buttons.push_back(mw->getGameSettingString("sBack", "")); buttons.push_back(mWindowManager.getGameSettingString("sBack", ""));
setButtons(buttons); setButtons(buttons);
} }
/* CreateClassDialog */ /* CreateClassDialog */
CreateClassDialog::CreateClassDialog(MWWorld::Environment& environment) CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_create_class_layout.xml", environment) : WindowBase("openmw_chargen_create_class_layout.xml", parWindowManager)
, specDialog(nullptr) , specDialog(nullptr)
, attribDialog(nullptr) , attribDialog(nullptr)
, skillDialog(nullptr) , skillDialog(nullptr)
@ -392,22 +386,21 @@ CreateClassDialog::CreateClassDialog(MWWorld::Environment& environment)
// Centre dialog // Centre dialog
center(); center();
WindowManager *wm = environment.mWindowManager; setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization"));
setText("SpecializationT", wm->getGameSettingString("sChooseClassMenu1", "Specialization"));
getWidget(specializationName, "SpecializationName"); getWidget(specializationName, "SpecializationName");
specializationName->setCaption(wm->getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], ""));
specializationName->eventMouseButtonClick = MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); specializationName->eventMouseButtonClick = MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked);
setText("FavoriteAttributesT", wm->getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:"));
getWidget(favoriteAttribute0, "FavoriteAttribute0"); getWidget(favoriteAttribute0, "FavoriteAttribute0");
getWidget(favoriteAttribute1, "FavoriteAttribute1"); getWidget(favoriteAttribute1, "FavoriteAttribute1");
favoriteAttribute0->setWindowManager(wm); favoriteAttribute0->setWindowManager(&mWindowManager);
favoriteAttribute1->setWindowManager(wm); favoriteAttribute1->setWindowManager(&mWindowManager);
favoriteAttribute0->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); favoriteAttribute0->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked);
favoriteAttribute1->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); favoriteAttribute1->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked);
setText("MajorSkillT", wm->getGameSettingString("sSkillClassMajor", "")); setText("MajorSkillT", mWindowManager.getGameSettingString("sSkillClassMajor", ""));
setText("MinorSkillT", wm->getGameSettingString("sSkillClassMinor", "")); setText("MinorSkillT", mWindowManager.getGameSettingString("sSkillClassMinor", ""));
for(int i = 0; i < 5; i++) for(int i = 0; i < 5; i++)
{ {
char theIndex = '0'+i; char theIndex = '0'+i;
@ -420,11 +413,11 @@ CreateClassDialog::CreateClassDialog(MWWorld::Environment& environment)
std::vector<Widgets::MWSkillPtr>::const_iterator end = skills.end(); std::vector<Widgets::MWSkillPtr>::const_iterator end = skills.end();
for (std::vector<Widgets::MWSkillPtr>::const_iterator it = skills.begin(); it != end; ++it) for (std::vector<Widgets::MWSkillPtr>::const_iterator it = skills.begin(); it != end; ++it)
{ {
(*it)->setWindowManager(wm); (*it)->setWindowManager(&mWindowManager);
(*it)->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onSkillClicked); (*it)->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onSkillClicked);
} }
setText("LabelT", wm->getGameSettingString("sName", "")); setText("LabelT", mWindowManager.getGameSettingString("sName", ""));
getWidget(editName, "EditName"); getWidget(editName, "EditName");
// Make sure the edit box has focus // Make sure the edit box has focus
@ -566,7 +559,7 @@ void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender)
{ {
if (specDialog) if (specDialog)
delete specDialog; delete specDialog;
specDialog = new SelectSpecializationDialog(environment, environment.mWindowManager->getGui()->getViewSize()); specDialog = new SelectSpecializationDialog(mWindowManager);
specDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); specDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
specDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected); specDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected);
specDialog->setVisible(true); specDialog->setVisible(true);
@ -575,7 +568,7 @@ void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender)
void CreateClassDialog::onSpecializationSelected() void CreateClassDialog::onSpecializationSelected()
{ {
specializationId = specDialog->getSpecializationId(); specializationId = specDialog->getSpecializationId();
specializationName->setCaption(environment.mWindowManager->getGameSettingString(ESM::Class::gmstSpecializationIds[specializationId], "")); specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[specializationId], ""));
specDialog->setVisible(false); specDialog->setVisible(false);
} }
@ -583,7 +576,7 @@ void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
{ {
if (attribDialog) if (attribDialog)
delete attribDialog; delete attribDialog;
attribDialog = new SelectAttributeDialog(environment, environment.mWindowManager->getGui()->getViewSize()); attribDialog = new SelectAttributeDialog(mWindowManager);
attribDialog->setAffectedWidget(_sender); attribDialog->setAffectedWidget(_sender);
attribDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); attribDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
attribDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected); attribDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected);
@ -612,7 +605,7 @@ void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
{ {
if (skillDialog) if (skillDialog)
delete skillDialog; delete skillDialog;
skillDialog = new SelectSkillDialog(environment, environment.mWindowManager->getGui()->getViewSize()); skillDialog = new SelectSkillDialog(mWindowManager);
skillDialog->setAffectedWidget(_sender); skillDialog->setAffectedWidget(_sender);
skillDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); skillDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
skillDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected); skillDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected);
@ -643,21 +636,21 @@ void CreateClassDialog::onSkillSelected()
void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender) void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender)
{ {
descDialog = new DescriptionDialog(environment, environment.mWindowManager->getGui()->getViewSize()); descDialog = new DescriptionDialog(mWindowManager);
descDialog->setTextInput(description); descDialog->setTextInput(description);
descDialog->eventDone = MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionEntered); descDialog->eventDone = MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionEntered);
descDialog->setVisible(true); descDialog->setVisible(true);
} }
void CreateClassDialog::onDescriptionEntered() void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow)
{ {
description = descDialog->getTextInput(); description = descDialog->getTextInput();
environment.mWindowManager->removeDialog(descDialog); mWindowManager.removeDialog(descDialog);
} }
void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender) void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender)
{ {
eventDone(); eventDone(this);
} }
void CreateClassDialog::onBackClicked(MyGUI::Widget* _sender) void CreateClassDialog::onBackClicked(MyGUI::Widget* _sender)
@ -667,31 +660,29 @@ void CreateClassDialog::onBackClicked(MyGUI::Widget* _sender)
/* SelectSpecializationDialog */ /* SelectSpecializationDialog */
SelectSpecializationDialog::SelectSpecializationDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize) SelectSpecializationDialog::SelectSpecializationDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_select_specialization_layout.xml", environment) : WindowBase("openmw_chargen_select_specialization_layout.xml", parWindowManager)
{ {
// Centre dialog // Centre dialog
center(); center();
WindowManager *wm = environment.mWindowManager; setText("LabelT", mWindowManager.getGameSettingString("sSpecializationMenu1", ""));
setText("LabelT", wm->getGameSettingString("sSpecializationMenu1", ""));
getWidget(specialization0, "Specialization0"); getWidget(specialization0, "Specialization0");
getWidget(specialization1, "Specialization1"); getWidget(specialization1, "Specialization1");
getWidget(specialization2, "Specialization2"); getWidget(specialization2, "Specialization2");
specialization0->setCaption(wm->getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); specialization0->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], ""));
specialization0->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); specialization0->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked);
specialization1->setCaption(wm->getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], "")); specialization1->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], ""));
specialization1->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); specialization1->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked);
specialization2->setCaption(wm->getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], "")); specialization2->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], ""));
specialization2->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); specialization2->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked);
specializationId = ESM::Class::Combat; specializationId = ESM::Class::Combat;
// TODO: These buttons should be managed by a Dialog class // TODO: These buttons should be managed by a Dialog class
MyGUI::ButtonPtr cancelButton; MyGUI::ButtonPtr cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(wm->getGameSettingString("sCancel", "")); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked);
} }
@ -718,15 +709,13 @@ void SelectSpecializationDialog::onCancelClicked(MyGUI::Widget* _sender)
/* SelectAttributeDialog */ /* SelectAttributeDialog */
SelectAttributeDialog::SelectAttributeDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize) SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_select_attribute_layout.xml", environment) : WindowBase("openmw_chargen_select_attribute_layout.xml", parWindowManager)
{ {
// Centre dialog // Centre dialog
center(); center();
WindowManager *wm = environment.mWindowManager; setText("LabelT", mWindowManager.getGameSettingString("sAttributesMenu1", ""));
setText("LabelT", wm->getGameSettingString("sAttributesMenu1", ""));
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
@ -734,7 +723,7 @@ SelectAttributeDialog::SelectAttributeDialog(MWWorld::Environment& environment,
char theIndex = '0'+i; char theIndex = '0'+i;
getWidget(attribute, std::string("Attribute").append(1, theIndex)); getWidget(attribute, std::string("Attribute").append(1, theIndex));
attribute->setWindowManager(wm); attribute->setWindowManager(&parWindowManager);
attribute->setAttributeId(ESM::Attribute::attributeIds[i]); attribute->setAttributeId(ESM::Attribute::attributeIds[i]);
attribute->eventClicked = MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked); attribute->eventClicked = MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked);
} }
@ -742,7 +731,7 @@ SelectAttributeDialog::SelectAttributeDialog(MWWorld::Environment& environment,
// TODO: These buttons should be managed by a Dialog class // TODO: These buttons should be managed by a Dialog class
MyGUI::ButtonPtr cancelButton; MyGUI::ButtonPtr cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(wm->getGameSettingString("sCancel", "")); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked);
} }
@ -763,18 +752,16 @@ void SelectAttributeDialog::onCancelClicked(MyGUI::Widget* _sender)
/* SelectSkillDialog */ /* SelectSkillDialog */
SelectSkillDialog::SelectSkillDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize) SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_select_skill_layout.xml", environment) : WindowBase("openmw_chargen_select_skill_layout.xml", parWindowManager)
{ {
// Centre dialog // Centre dialog
center(); center();
WindowManager *wm = environment.mWindowManager; setText("LabelT", mWindowManager.getGameSettingString("sSkillsMenu1", ""));
setText("CombatLabelT", mWindowManager.getGameSettingString("sSpecializationCombat", ""));
setText("LabelT", wm->getGameSettingString("sSkillsMenu1", "")); setText("MagicLabelT", mWindowManager.getGameSettingString("sSpecializationMagic", ""));
setText("CombatLabelT", wm->getGameSettingString("sSpecializationCombat", "")); setText("StealthLabelT", mWindowManager.getGameSettingString("sSpecializationStealth", ""));
setText("MagicLabelT", wm->getGameSettingString("sSpecializationMagic", ""));
setText("StealthLabelT", wm->getGameSettingString("sSpecializationStealth", ""));
for(int i = 0; i < 9; i++) for(int i = 0; i < 9; i++)
{ {
@ -824,7 +811,7 @@ SelectSkillDialog::SelectSkillDialog(MWWorld::Environment& environment, MyGUI::I
{ {
for (int i = 0; i < 9; ++i) for (int i = 0; i < 9; ++i)
{ {
skills[spec][i].widget->setWindowManager(wm); skills[spec][i].widget->setWindowManager(&mWindowManager);
skills[spec][i].widget->setSkillId(skills[spec][i].skillId); skills[spec][i].widget->setSkillId(skills[spec][i].skillId);
skills[spec][i].widget->eventClicked = MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked); skills[spec][i].widget->eventClicked = MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked);
} }
@ -833,7 +820,7 @@ SelectSkillDialog::SelectSkillDialog(MWWorld::Environment& environment, MyGUI::I
// TODO: These buttons should be managed by a Dialog class // TODO: These buttons should be managed by a Dialog class
MyGUI::ButtonPtr cancelButton; MyGUI::ButtonPtr cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(wm->getGameSettingString("sCancel", "")); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked);
} }
@ -852,8 +839,8 @@ void SelectSkillDialog::onCancelClicked(MyGUI::Widget* _sender)
/* DescriptionDialog */ /* DescriptionDialog */
DescriptionDialog::DescriptionDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize) DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_class_description_layout.xml", environment) : WindowBase("openmw_chargen_class_description_layout.xml", parWindowManager)
{ {
// Centre dialog // Centre dialog
center(); center();
@ -864,7 +851,7 @@ DescriptionDialog::DescriptionDialog(MWWorld::Environment& environment, MyGUI::I
MyGUI::ButtonPtr okButton; MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked); okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked);
okButton->setCaption(environment.mWindowManager->getGameSettingString("sInputMenu1", "")); okButton->setCaption(mWindowManager.getGameSettingString("sInputMenu1", ""));
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit);
@ -874,5 +861,5 @@ DescriptionDialog::DescriptionDialog(MWWorld::Environment& environment, MyGUI::I
void DescriptionDialog::onOkClicked(MyGUI::Widget* _sender) void DescriptionDialog::onOkClicked(MyGUI::Widget* _sender)
{ {
eventDone(); eventDone(this);
} }

@ -5,11 +5,6 @@
#include "widgets.hpp" #include "widgets.hpp"
#include "window_base.hpp" #include "window_base.hpp"
namespace MWWorld
{
class Environment;
}
/* /*
This file contains the dialogs for choosing a class. This file contains the dialogs for choosing a class.
Layout is defined by resources/mygui/openmw_chargen_class_layout.xml. Layout is defined by resources/mygui/openmw_chargen_class_layout.xml.
@ -19,10 +14,12 @@ namespace MWGui
{ {
using namespace MyGUI; using namespace MyGUI;
class WindowManager;
class InfoBoxDialog : public WindowBase class InfoBoxDialog : public WindowBase
{ {
public: public:
InfoBoxDialog(MWWorld::Environment& environment); InfoBoxDialog(WindowManager& parWindowManager);
typedef std::vector<std::string> ButtonList; typedef std::vector<std::string> ButtonList;
@ -34,12 +31,12 @@ namespace MWGui
int getChosenButton() const; int getChosenButton() const;
// Events // Events
typedef delegates::CDelegate2<MyGUI::WidgetPtr, int> EventHandle_WidgetInt; typedef delegates::CDelegate1<int> EventHandle_Int;
/** Event : Button was clicked.\n /** Event : Button was clicked.\n
signature : void method(MyGUI::WidgetPtr widget, int index)\n signature : void method(MyGUI::WidgetPtr widget, int index)\n
*/ */
EventHandle_WidgetInt eventButtonSelected; EventHandle_Int eventButtonSelected;
protected: protected:
void onButtonClicked(MyGUI::WidgetPtr _sender); void onButtonClicked(MyGUI::WidgetPtr _sender);
@ -67,13 +64,13 @@ namespace MWGui
Class_Create = 2, Class_Create = 2,
Class_Back = 3 Class_Back = 3
}; };
ClassChoiceDialog(MWWorld::Environment& environment); ClassChoiceDialog(WindowManager& parWindowManager);
}; };
class GenerateClassResultDialog : public WindowBase class GenerateClassResultDialog : public WindowBase
{ {
public: public:
GenerateClassResultDialog(MWWorld::Environment& environment); GenerateClassResultDialog(WindowManager& parWindowManager);
std::string getClassId() const; std::string getClassId() const;
void setClassId(const std::string &classId); void setClassId(const std::string &classId);
@ -88,11 +85,6 @@ namespace MWGui
*/ */
EventHandle_Void eventBack; EventHandle_Void eventBack;
/** Event : Dialog finished, OK button clicked.\n
signature : void method()\n
*/
EventHandle_Void eventDone;
protected: protected:
void onOkClicked(MyGUI::Widget* _sender); void onOkClicked(MyGUI::Widget* _sender);
void onBackClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender);
@ -107,7 +99,7 @@ namespace MWGui
class PickClassDialog : public WindowBase class PickClassDialog : public WindowBase
{ {
public: public:
PickClassDialog(MWWorld::Environment& environment); PickClassDialog(WindowManager& parWindowManager);
const std::string &getClassId() const { return currentClassId; } const std::string &getClassId() const { return currentClassId; }
void setClassId(const std::string &classId); void setClassId(const std::string &classId);
@ -123,11 +115,6 @@ namespace MWGui
*/ */
EventHandle_Void eventBack; EventHandle_Void eventBack;
/** Event : Dialog finished, OK button clicked.\n
signature : void method()\n
*/
EventHandle_Void eventDone;
protected: protected:
void onSelectClass(MyGUI::List* _sender, size_t _index); void onSelectClass(MyGUI::List* _sender, size_t _index);
@ -151,7 +138,7 @@ namespace MWGui
class SelectSpecializationDialog : public WindowBase class SelectSpecializationDialog : public WindowBase
{ {
public: public:
SelectSpecializationDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize); SelectSpecializationDialog(WindowManager& parWindowManager);
ESM::Class::Specialization getSpecializationId() const { return specializationId; } ESM::Class::Specialization getSpecializationId() const { return specializationId; }
@ -181,7 +168,7 @@ namespace MWGui
class SelectAttributeDialog : public WindowBase class SelectAttributeDialog : public WindowBase
{ {
public: public:
SelectAttributeDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize); SelectAttributeDialog(WindowManager& parWindowManager);
ESM::Attribute::AttributeID getAttributeId() const { return attributeId; } ESM::Attribute::AttributeID getAttributeId() const { return attributeId; }
Widgets::MWAttributePtr getAffectedWidget() const { return affectedWidget; } Widgets::MWAttributePtr getAffectedWidget() const { return affectedWidget; }
@ -213,7 +200,7 @@ namespace MWGui
class SelectSkillDialog : public WindowBase class SelectSkillDialog : public WindowBase
{ {
public: public:
SelectSkillDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize); SelectSkillDialog(WindowManager& parWindowManager);
ESM::Skill::SkillEnum getSkillId() const { return skillId; } ESM::Skill::SkillEnum getSkillId() const { return skillId; }
Widgets::MWSkillPtr getAffectedWidget() const { return affectedWidget; } Widgets::MWSkillPtr getAffectedWidget() const { return affectedWidget; }
@ -248,19 +235,11 @@ namespace MWGui
class DescriptionDialog : public WindowBase class DescriptionDialog : public WindowBase
{ {
public: public:
DescriptionDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize); DescriptionDialog(WindowManager& parWindowManager);
std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; } std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; }
void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); } void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); }
// Events
typedef delegates::CDelegate0 EventHandle_Void;
/** Event : Dialog finished, OK button clicked.\n
signature : void method()\n
*/
EventHandle_Void eventDone;
protected: protected:
void onOkClicked(MyGUI::Widget* _sender); void onOkClicked(MyGUI::Widget* _sender);
@ -271,7 +250,7 @@ namespace MWGui
class CreateClassDialog : public WindowBase class CreateClassDialog : public WindowBase
{ {
public: public:
CreateClassDialog(MWWorld::Environment& environment); CreateClassDialog(WindowManager& parWindowManager);
virtual ~CreateClassDialog(); virtual ~CreateClassDialog();
std::string getName() const; std::string getName() const;
@ -292,11 +271,6 @@ namespace MWGui
*/ */
EventHandle_Void eventBack; EventHandle_Void eventBack;
/** Event : Dialog finished, OK button clicked.\n
signature : void method()\n
*/
EventHandle_Void eventDone;
protected: protected:
void onOkClicked(MyGUI::Widget* _sender); void onOkClicked(MyGUI::Widget* _sender);
void onBackClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender);
@ -308,7 +282,7 @@ namespace MWGui
void onSkillClicked(Widgets::MWSkillPtr _sender); void onSkillClicked(Widgets::MWSkillPtr _sender);
void onSkillSelected(); void onSkillSelected();
void onDescriptionClicked(MyGUI::Widget* _sender); void onDescriptionClicked(MyGUI::Widget* _sender);
void onDescriptionEntered(); void onDescriptionEntered(WindowBase* parWindow);
void onDialogCancel(); void onDialogCancel();
private: private:

@ -1,7 +1,5 @@
#include "dialogue.hpp" #include "dialogue.hpp"
#include "dialogue_history.hpp" #include "dialogue_history.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
@ -16,8 +14,8 @@
using namespace MWGui; using namespace MWGui;
using namespace Widgets; using namespace Widgets;
DialogueWindow::DialogueWindow(MWWorld::Environment& environment) DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
: WindowBase("openmw_dialogue_window_layout.xml", environment) : WindowBase("openmw_dialogue_window_layout.xml", parWindowManager)
{ {
// Centre dialog // Centre dialog
center(); center();

@ -4,9 +4,9 @@
#include "window_base.hpp" #include "window_base.hpp"
#include <boost/array.hpp> #include <boost/array.hpp>
namespace MWWorld namespace MWGui
{ {
class Environment; class WindowManager;
} }
/* /*
@ -23,7 +23,7 @@ namespace MWGui
class DialogueWindow: public WindowBase class DialogueWindow: public WindowBase
{ {
public: public:
DialogueWindow(MWWorld::Environment& environment); DialogueWindow(WindowManager& parWindowManager);
void open(); void open();

@ -1,6 +1,4 @@
#include "dialogue_history.hpp" #include "dialogue_history.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"

@ -1,416 +1,126 @@
#include "layouts.hpp" #include "layouts.hpp"
#include "../mwworld/class.hpp"
#include "../mwmechanics/mechanicsmanager.hpp" #include "../mwmechanics/mechanicsmanager.hpp"
#include "../mwgui/window_manager.hpp" #include "window_manager.hpp"
#include <cmath> #include <cmath>
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <boost/lexical_cast.hpp>
#undef min #undef min
#undef max #undef max
using namespace MWGui; using namespace MWGui;
const int StatsWindow::lineHeight = 18;
StatsWindow::StatsWindow (MWWorld::Environment& environment) HUD::HUD(int width, int height, bool fpsSwitch)
: WindowBase("openmw_stats_window_layout.xml", environment) : Layout("openmw_hud_layout.xml")
, lastPos(0)
, reputation(0)
, bounty(0)
{ {
setCoord(0,0,498, 342); setCoord(0,0, width, height);
const char *names[][2] = // Energy bars
{ getWidget(health, "Health");
{ "Attrib1", "sAttributeStrength" }, getWidget(magicka, "Magicka");
{ "Attrib2", "sAttributeIntelligence" }, getWidget(stamina, "Stamina");
{ "Attrib3", "sAttributeWillpower" },
{ "Attrib4", "sAttributeAgility" },
{ "Attrib5", "sAttributeSpeed" },
{ "Attrib6", "sAttributeEndurance" },
{ "Attrib7", "sAttributePersonality" },
{ "Attrib8", "sAttributeLuck" },
{ "Health_str", "sHealth" },
{ "Magicka_str", "sMagic" },
{ "Fatigue_str", "sFatigue" },
{ "Level_str", "sLevel" },
{ "Race_str", "sRace" },
{ "Class_str", "sClass" },
{ 0, 0 }
};
const ESMS::ESMStore &store = environment.mWorld->getStore(); // Item and spell images and status bars
for (int i=0; names[i][0]; ++i) getWidget(weapImage, "WeapImage");
{ getWidget(weapStatus, "WeapStatus");
setText (names[i][0], store.gameSettings.find (names[i][1])->str); getWidget(spellImage, "SpellImage");
} getWidget(spellStatus, "SpellStatus");
getWidget(skillAreaWidget, "Skills"); getWidget(effectBox, "EffectBox");
getWidget(skillClientWidget, "SkillClient"); getWidget(effect1, "Effect1");
getWidget(skillScrollerWidget, "SkillScroller");
skillScrollerWidget->eventScrollChangePosition = MyGUI::newDelegate(this, &StatsWindow::onScrollChangePosition); getWidget(minimap, "MiniMap");
updateScroller(); getWidget(compass, "Compass");
for (int i = 0; i < ESM::Skill::Length; ++i) getWidget(crosshair, "Crosshair");
{
skillValues.insert(std::make_pair(i, MWMechanics::Stat<float>()));
skillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::StaticText*> (0)));
}
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget); getWidget(fpsbox, "FPSBox");
t->eventWindowChangeCoord = MyGUI::newDelegate(this, &StatsWindow::onWindowResize); getWidget(fpscounter, "FPSCounter");
}
void StatsWindow::onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos) fpsbox->setVisible(fpsSwitch);
{
int diff = lastPos - pos;
// Adjust position of all widget according to difference
if (diff == 0)
return;
lastPos = pos;
std::vector<MyGUI::WidgetPtr>::const_iterator end = skillWidgets.end(); compass->setImageTexture("textures\\compass.dds");
for (std::vector<MyGUI::WidgetPtr>::const_iterator it = skillWidgets.begin(); it != end; ++it) crosshair->setImageTexture("textures\\target.dds");
{
(*it)->setCoord((*it)->getCoord() + MyGUI::IntPoint(0, diff));
}
}
void StatsWindow::onWindowResize(MyGUI::WidgetPtr window) // These are just demo values, you should replace these with
{ // real calls from outside the class later.
updateScroller(); setWeapIcon("icons\\w\\tx_knife_iron.dds");
setWeapStatus(90, 100);
setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds");
setSpellStatus(65, 100);
setEffect("icons\\s\\tx_s_chameleon.dds");
} }
void StatsWindow::setBar(const std::string& name, const std::string& tname, int val, int max) void HUD::setFPS(float fps)
{ {
MyGUI::ProgressPtr pt; fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps));
getWidget(pt, name);
pt->setProgressRange(max);
pt->setProgressPosition(val);
std::stringstream out;
out << val << "/" << max;
setText(tname, out.str().c_str());
} }
void StatsWindow::setPlayerName(const std::string& playerName)
void HUD::setStats(int h, int hmax, int m, int mmax, int s, int smax)
{ {
mMainWidget->setCaption(playerName); health->setProgressRange(hmax);
health->setProgressPosition(h);
magicka->setProgressRange(mmax);
magicka->setProgressPosition(m);
stamina->setProgressRange(smax);
stamina->setProgressPosition(s);
} }
void StatsWindow::setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value) void HUD::setWeapIcon(const char *str)
{ {
widget->setCaption(value); weapImage->setImageTexture(str);
if (style == CS_Super)
widget->setTextColour(MyGUI::Colour(0, 1, 0));
else if (style == CS_Sub)
widget->setTextColour(MyGUI::Colour(1, 0, 0));
else
widget->setTextColour(MyGUI::Colour(1, 1, 1));
} }
void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>& value) void HUD::setSpellIcon(const char *str)
{ {
static const char *ids[] = spellImage->setImageTexture(str);
{
"AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5",
"AttribVal6", "AttribVal7", "AttribVal8",
0
};
for (int i=0; ids[i]; ++i)
if (ids[i]==id)
{
std::ostringstream valueString;
valueString << value.getModified();
setText (id, valueString.str());
if (value.getModified()>value.getBase())
setTextColor (id, 0, 1, 0);
else if (value.getModified()<value.getBase())
setTextColor (id, 1, 0, 0);
else
setTextColor (id, 1, 1, 1);
break;
}
} }
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value) void HUD::setWeapStatus(int s, int smax)
{ {
static const char *ids[] = weapStatus->setProgressRange(smax);
{ weapStatus->setProgressPosition(s);
"HBar", "MBar", "FBar",
0
};
for (int i=0; ids[i]; ++i)
if (ids[i]==id)
{
std::string id (ids[i]);
setBar (id, id + "T", value.getCurrent(), value.getModified());
}
} }
void StatsWindow::setValue (const std::string& id, const std::string& value) void HUD::setSpellStatus(int s, int smax)
{ {
if (id=="name") spellStatus->setProgressRange(smax);
setPlayerName (value); spellStatus->setProgressPosition(s);
else if (id=="race")
setText ("RaceText", value);
else if (id=="class")
setText ("ClassText", value);
} }
void StatsWindow::setValue (const std::string& id, int value) void HUD::setEffect(const char *img)
{ {
if (id=="level") effect1->setImageTexture(img);
{
std::ostringstream text;
text << value;
setText("LevelText", text.str());
}
} }
void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<float>& value) void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& value)
{ {
static struct {const char *id; ESM::Skill::SkillEnum skillId; } skillMap[] = static const char *ids[] =
{ {
{"SkillBlock", ESM::Skill::Block}, "HBar", "MBar", "FBar", 0
{"SkillArmorer", ESM::Skill::Armorer},
{"SkillMediumArmor", ESM::Skill::MediumArmor},
{"SkillHeavyArmor", ESM::Skill::HeavyArmor},
{"SkillBluntWeapon", ESM::Skill::BluntWeapon},
{"SkillLongBlade", ESM::Skill::LongBlade},
{"SkillAxe", ESM::Skill::Axe},
{"SkillSpear", ESM::Skill::Spear},
{"SkillAthletics", ESM::Skill::Athletics},
{"SkillEnchant", ESM::Skill::Armorer},
{"SkillDestruction", ESM::Skill::Destruction},
{"SkillAlteration", ESM::Skill::Alteration},
{"SkillIllusion", ESM::Skill::Illusion},
{"SkillConjuration", ESM::Skill::Conjuration},
{"SkillMysticism", ESM::Skill::Mysticism},
{"SkillRestoration", ESM::Skill::Restoration},
{"SkillAlchemy", ESM::Skill::Alchemy},
{"SkillUnarmored", ESM::Skill::Unarmored},
{"SkillSecurity", ESM::Skill::Security},
{"SkillSneak", ESM::Skill::Sneak},
{"SkillAcrobatics", ESM::Skill::Acrobatics},
{"SkillLightArmor", ESM::Skill::LightArmor},
{"SkillShortBlade", ESM::Skill::ShortBlade},
{"SkillMarksman", ESM::Skill::Marksman},
{"SkillMercantile", ESM::Skill::Mercantile},
{"SkillSpeechcraft", ESM::Skill::Speechcraft},
{"SkillHandToHand", ESM::Skill::HandToHand},
}; };
for (size_t i = 0; i < sizeof(skillMap)/sizeof(skillMap[0]); ++i)
{ for (int i=0; ids[i]; ++i)
if (skillMap[i].id == id) if (ids[i]==id)
{ {
int skillId = skillMap[i].skillId; switch (i)
skillValues[skillId] = value;
MyGUI::StaticTextPtr widget = skillWidgetMap[skillId];
if (widget)
{ {
float modified = value.getModified(), base = value.getBase(); case 0:
std::string text = boost::lexical_cast<std::string>(std::floor(modified)); health->setProgressRange (value.getModified());
ColorStyle style = CS_Normal; health->setProgressPosition (value.getCurrent());
if (modified > base) break;
style = CS_Super; case 1:
else if (modified < base) magicka->setProgressRange (value.getModified());
style = CS_Sub; magicka->setProgressPosition (value.getCurrent());
break;
setStyledText(widget, style, text); case 2:
stamina->setProgressRange (value.getModified());
stamina->setProgressPosition (value.getCurrent());
break;
} }
break;
} }
}
}
void StatsWindow::configureSkills (const std::vector<int>& major, const std::vector<int>& minor)
{
majorSkills = major;
minorSkills = minor;
// Update misc skills with the remaining skills not in major or minor
std::set<int> skillSet;
std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin()));
std::copy(minor.begin(), minor.end(), std::inserter(skillSet, skillSet.begin()));
boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator end = ESM::Skill::skillIds.end();
miscSkills.clear();
for (boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator it = ESM::Skill::skillIds.begin(); it != end; ++it)
{
int skill = *it;
if (skillSet.find(skill) == skillSet.end())
miscSkills.push_back(skill);
}
}
void StatsWindow::setFactions (const std::vector<Faction>& factions)
{
this->factions = factions;
}
void StatsWindow::setBirthSign (const std::string& signId)
{
birthSignId = signId;
}
void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticImagePtr separator = skillClientWidget->createWidget<MyGUI::StaticImage>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
skillWidgets.push_back(separator);
coord1.top += separator->getHeight();
coord2.top += separator->getHeight();
}
void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticTextPtr groupWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default);
groupWidget->setCaption(label);
skillWidgets.push_back(groupWidget);
coord1.top += lineHeight;
coord2.top += lineHeight;
}
MyGUI::StaticTextPtr StatsWindow::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticTextPtr skillNameWidget, skillValueWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandText", coord1, MyGUI::Align::Default);
skillNameWidget->setCaption(text);
skillValueWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandTextRight", coord2, MyGUI::Align::Default);
setStyledText(skillValueWidget, style, value);
skillWidgets.push_back(skillNameWidget);
skillWidgets.push_back(skillValueWidget);
coord1.top += lineHeight;
coord2.top += lineHeight;
return skillValueWidget;
}
void StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticTextPtr skillNameWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
skillNameWidget->setCaption(text);
skillWidgets.push_back(skillNameWidget);
coord1.top += lineHeight;
coord2.top += lineHeight;
}
void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
WindowManager *wm = environment.mWindowManager;
// Add a line separator if there are items above
if (!skillWidgets.empty())
{
addSeparator(coord1, coord2);
}
addGroup(wm->getGameSettingString(titleId, titleDefault), coord1, coord2);
SkillList::const_iterator end = skills.end();
for (SkillList::const_iterator it = skills.begin(); it != end; ++it)
{
int skillId = *it;
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
continue;
assert(skillId >= 0 && skillId < ESM::Skill::Length);
const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId];
const MWMechanics::Stat<float> &stat = skillValues.find(skillId)->second;
float base = stat.getBase();
float modified = stat.getModified();
ColorStyle style = CS_Normal;
if (modified > base)
style = CS_Super;
else if (modified < base)
style = CS_Sub;
MyGUI::StaticTextPtr widget = addValueItem(wm->getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), style, coord1, coord2);
skillWidgetMap[skillId] = widget;
}
}
void StatsWindow::updateSkillArea()
{
for (std::vector<MyGUI::WidgetPtr>::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
}
skillWidgets.clear();
const int valueSize = 40;
MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18);
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
if (!majorSkills.empty())
addSkills(majorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2);
if (!minorSkills.empty())
addSkills(minorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2);
if (!miscSkills.empty())
addSkills(miscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
WindowManager *wm = environment.mWindowManager;
ESMS::ESMStore &store = environment.mWorld->getStore();
if (!factions.empty())
{
// Add a line separator if there are items above
if (!skillWidgets.empty())
addSeparator(coord1, coord2);
addGroup(wm->getGameSettingString("sFaction", "Faction"), coord1, coord2);
FactionList::const_iterator end = factions.end();
for (FactionList::const_iterator it = factions.begin(); it != end; ++it)
{
const ESM::Faction *faction = store.factions.find(it->first);
addItem(faction->name, coord1, coord2);
// TODO: Faction rank should be placed in tooltip
}
}
if (!birthSignId.empty())
{
// Add a line separator if there are items above
if (!skillWidgets.empty())
addSeparator(coord1, coord2);
addGroup(wm->getGameSettingString("sSign", "Sign"), coord1, coord2);
const ESM::BirthSign *sign = store.birthSigns.find(birthSignId);
addItem(sign->name, coord1, coord2);
}
// Add a line separator if there are items above
if (!skillWidgets.empty())
addSeparator(coord1, coord2);
addValueItem(wm->getGameSettingString("sReputation", "Reputation"), boost::lexical_cast<std::string>(static_cast<int>(reputation)), CS_Normal, coord1, coord2);
addValueItem(wm->getGameSettingString("sBounty", "Bounty"), boost::lexical_cast<std::string>(static_cast<int>(bounty)), CS_Normal, coord1, coord2);
clientHeight = coord1.top;
updateScroller();
}
void StatsWindow::updateScroller()
{
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
} }

@ -3,9 +3,8 @@
#include <components/esm_store/store.hpp> #include <components/esm_store/store.hpp>
#include <openengine/gui/layout.hpp>
#include <boost/array.hpp> #include <boost/array.hpp>
#include <boost/lexical_cast.hpp>
#include <sstream> #include <sstream>
#include <set> #include <set>
@ -13,12 +12,10 @@
#include <utility> #include <utility>
#include "../mwmechanics/stat.hpp" #include "../mwmechanics/stat.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "window_base.hpp" #include "window_base.hpp"
/* /*
This file contains classes corresponding to all the window layouts This file contains classes corresponding to window layouts
defined in resources/mygui/ *.xml. defined in resources/mygui/ *.xml.
Each class inherites GUI::Layout and loads the XML file, and Each class inherites GUI::Layout and loads the XML file, and
@ -35,117 +32,27 @@ namespace MWGui
class HUD : public OEngine::GUI::Layout class HUD : public OEngine::GUI::Layout
{ {
public: public:
HUD(int width, int height) HUD(int width, int height, bool fpsSwitch);
: Layout("openmw_hud_layout.xml") void setStats(int h, int hmax, int m, int mmax, int s, int smax);
{ void setWeapIcon(const char *str);
setCoord(0,0, width, height); void setSpellIcon(const char *str);
void setWeapStatus(int s, int smax);
// Energy bars void setSpellStatus(int s, int smax);
getWidget(health, "Health"); void setEffect(const char *img);
getWidget(magicka, "Magicka"); void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
getWidget(stamina, "Stamina"); void setFPS(float fps);
// Item and spell images and status bars
getWidget(weapImage, "WeapImage");
getWidget(weapStatus, "WeapStatus");
getWidget(spellImage, "SpellImage");
getWidget(spellStatus, "SpellStatus");
getWidget(effectBox, "EffectBox");
getWidget(effect1, "Effect1");
getWidget(minimap, "MiniMap");
getWidget(compass, "Compass");
getWidget(crosshair, "Crosshair");
compass->setImageTexture("textures\\compass.dds");
crosshair->setImageTexture("textures\\target.dds");
// These are just demo values, you should replace these with
// real calls from outside the class later.
setWeapIcon("icons\\w\\tx_knife_iron.dds");
setWeapStatus(90, 100);
setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds");
setSpellStatus(65, 100);
setEffect("icons\\s\\tx_s_chameleon.dds");
}
void setStats(int h, int hmax, int m, int mmax, int s, int smax)
{
health->setProgressRange(hmax);
health->setProgressPosition(h);
magicka->setProgressRange(mmax);
magicka->setProgressPosition(m);
stamina->setProgressRange(smax);
stamina->setProgressPosition(s);
}
void setWeapIcon(const char *str)
{ weapImage->setImageTexture(str); }
void setSpellIcon(const char *str)
{ spellImage->setImageTexture(str); }
void setWeapStatus(int s, int smax)
{
weapStatus->setProgressRange(smax);
weapStatus->setProgressPosition(s);
}
void setSpellStatus(int s, int smax)
{
spellStatus->setProgressRange(smax);
spellStatus->setProgressPosition(s);
}
void setEffect(const char *img)
{ effect1->setImageTexture(img); }
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
{
static const char *ids[] =
{
"HBar", "MBar", "FBar",
0
};
for (int i=0; ids[i]; ++i)
if (ids[i]==id)
{
switch (i)
{
case 0:
health->setProgressRange (value.getModified());
health->setProgressPosition (value.getCurrent());
break;
case 1:
magicka->setProgressRange (value.getModified());
magicka->setProgressPosition (value.getCurrent());
break;
case 2:
stamina->setProgressRange (value.getModified());
stamina->setProgressPosition (value.getCurrent());
break;
}
}
}
MyGUI::ProgressPtr health, magicka, stamina; MyGUI::ProgressPtr health, magicka, stamina;
MyGUI::StaticImagePtr weapImage, spellImage; MyGUI::StaticImagePtr weapImage, spellImage;
MyGUI::ProgressPtr weapStatus, spellStatus; MyGUI::ProgressPtr weapStatus, spellStatus;
MyGUI::WidgetPtr effectBox; MyGUI::WidgetPtr effectBox;
MyGUI::StaticImagePtr effect1; MyGUI::StaticImagePtr effect1;
MyGUI::StaticImagePtr minimap; MyGUI::StaticImagePtr minimap;
MyGUI::StaticImagePtr compass; MyGUI::StaticImagePtr compass;
MyGUI::StaticImagePtr crosshair; MyGUI::StaticImagePtr crosshair;
MyGUI::WidgetPtr fpsbox;
MyGUI::StaticTextPtr fpscounter;
}; };
class MapWindow : public OEngine::GUI::Layout class MapWindow : public OEngine::GUI::Layout
@ -178,68 +85,6 @@ namespace MWGui
} }
}; };
class StatsWindow : public WindowBase
{
public:
typedef std::pair<std::string, int> Faction;
typedef std::vector<Faction> FactionList;
typedef std::vector<int> SkillList;
StatsWindow (MWWorld::Environment& environment);
void setBar(const std::string& name, const std::string& tname, int val, int max);
void setPlayerName(const std::string& playerName);
/// 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::DynamicStat<int>& 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, const MWMechanics::Stat<float>& value);
void configureSkills (const SkillList& major, const SkillList& minor);
void setFactions (const std::vector<Faction>& factions);
void setBirthSign (const std::string &signId);
void setReputation (int reputation) { this->reputation = reputation; }
void setBounty (int bounty) { this->bounty = bounty; }
void updateSkillArea();
private:
enum ColorStyle
{
CS_Sub,
CS_Normal,
CS_Super
};
void setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value);
void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
MyGUI::StaticTextPtr addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void updateScroller();
void onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos);
void onWindowResize(MyGUI::WidgetPtr window);
static const int lineHeight;
MyGUI::WidgetPtr skillAreaWidget, skillClientWidget;
MyGUI::VScrollPtr skillScrollerWidget;
int lastPos, clientHeight;
SkillList majorSkills, minorSkills, miscSkills;
std::map<int, MWMechanics::Stat<float> > skillValues;
std::map<int, MyGUI::StaticTextPtr> skillWidgetMap;
std::map<std::string, MyGUI::WidgetPtr> factionWidgetMap;
FactionList factions; ///< Stores a list of factions and the current rank
std::string birthSignId;
int reputation, bounty;
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information
};
#if 0 #if 0
class InventoryWindow : public OEngine::GUI::Layout class InventoryWindow : public OEngine::GUI::Layout
{ {

@ -1,6 +1,4 @@
#include "race.hpp" #include "race.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
@ -15,8 +13,8 @@
using namespace MWGui; using namespace MWGui;
using namespace Widgets; using namespace Widgets;
RaceDialog::RaceDialog(MWWorld::Environment& environment) RaceDialog::RaceDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_race_layout.xml", environment) : WindowBase("openmw_chargen_race_layout.xml", parWindowManager)
, genderIndex(0) , genderIndex(0)
, faceIndex(0) , faceIndex(0)
, hairIndex(0) , hairIndex(0)
@ -29,8 +27,7 @@ RaceDialog::RaceDialog(MWWorld::Environment& environment)
// These are just demo values, you should replace these with // These are just demo values, you should replace these with
// real calls from outside the class later. // real calls from outside the class later.
WindowManager *wm = environment.mWindowManager; setText("AppearanceT", mWindowManager.getGameSettingString("sRaceMenu1", "Appearance"));
setText("AppearanceT", wm->getGameSettingString("sRaceMenu1", "Appearance"));
getWidget(appearanceBox, "AppearanceBox"); getWidget(appearanceBox, "AppearanceBox");
getWidget(headRotate, "HeadRotate"); getWidget(headRotate, "HeadRotate");
@ -42,34 +39,34 @@ RaceDialog::RaceDialog(MWWorld::Environment& environment)
// Set up next/previous buttons // Set up next/previous buttons
MyGUI::ButtonPtr prevButton, nextButton; MyGUI::ButtonPtr prevButton, nextButton;
setText("GenderChoiceT", wm->getGameSettingString("sRaceMenu2", "Change Sex")); setText("GenderChoiceT", mWindowManager.getGameSettingString("sRaceMenu2", "Change Sex"));
getWidget(prevButton, "PrevGenderButton"); getWidget(prevButton, "PrevGenderButton");
getWidget(nextButton, "NextGenderButton"); getWidget(nextButton, "NextGenderButton");
prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousGender); prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousGender);
nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextGender); nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextGender);
setText("FaceChoiceT", wm->getGameSettingString("sRaceMenu3", "Change Face")); setText("FaceChoiceT", mWindowManager.getGameSettingString("sRaceMenu3", "Change Face"));
getWidget(prevButton, "PrevFaceButton"); getWidget(prevButton, "PrevFaceButton");
getWidget(nextButton, "NextFaceButton"); getWidget(nextButton, "NextFaceButton");
prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace); prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace);
nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace); nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace);
setText("HairChoiceT", wm->getGameSettingString("sRaceMenu3", "Change Hair")); setText("HairChoiceT", mWindowManager.getGameSettingString("sRaceMenu3", "Change Hair"));
getWidget(prevButton, "PrevHairButton"); getWidget(prevButton, "PrevHairButton");
getWidget(nextButton, "NextHairButton"); getWidget(nextButton, "NextHairButton");
prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair); prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair);
nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair); nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair);
setText("RaceT", wm->getGameSettingString("sRaceMenu4", "Race")); setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu4", "Race"));
getWidget(raceList, "RaceList"); getWidget(raceList, "RaceList");
raceList->setScrollVisible(true); raceList->setScrollVisible(true);
raceList->eventListSelectAccept = MyGUI::newDelegate(this, &RaceDialog::onSelectRace); raceList->eventListSelectAccept = MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
raceList->eventListMouseItemActivate = MyGUI::newDelegate(this, &RaceDialog::onSelectRace); raceList->eventListMouseItemActivate = MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
raceList->eventListChangePosition = MyGUI::newDelegate(this, &RaceDialog::onSelectRace); raceList->eventListChangePosition = MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
setText("SkillsT", wm->getGameSettingString("sBonusSkillTitle", "Skill Bonus")); setText("SkillsT", mWindowManager.getGameSettingString("sBonusSkillTitle", "Skill Bonus"));
getWidget(skillList, "SkillList"); getWidget(skillList, "SkillList");
setText("SpellPowerT", wm->getGameSettingString("sRaceMenu7", "Specials")); setText("SpellPowerT", mWindowManager.getGameSettingString("sRaceMenu7", "Specials"));
getWidget(spellPowerList, "SpellPowerList"); getWidget(spellPowerList, "SpellPowerList");
// TODO: These buttons should be managed by a Dialog class // TODO: These buttons should be managed by a Dialog class
@ -152,7 +149,7 @@ int wrap(int index, int max)
void RaceDialog::onOkClicked(MyGUI::Widget* _sender) void RaceDialog::onOkClicked(MyGUI::Widget* _sender)
{ {
eventDone(); eventDone(this);
} }
void RaceDialog::onBackClicked(MyGUI::Widget* _sender) void RaceDialog::onBackClicked(MyGUI::Widget* _sender)
@ -215,7 +212,7 @@ void RaceDialog::updateRaces()
{ {
raceList->removeAllItems(); raceList->removeAllItems();
ESMS::ESMStore &store = environment.mWorld->getStore(); ESMS::ESMStore &store = mWindowManager.getStore();
ESMS::RecListT<ESM::Race>::MapType::const_iterator it = store.races.list.begin(); ESMS::RecListT<ESM::Race>::MapType::const_iterator it = store.races.list.begin();
ESMS::RecListT<ESM::Race>::MapType::const_iterator end = store.races.list.end(); ESMS::RecListT<ESM::Race>::MapType::const_iterator end = store.races.list.end();
@ -249,8 +246,7 @@ void RaceDialog::updateSkills()
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord1(0, 0, skillList->getWidth(), 18); MyGUI::IntCoord coord1(0, 0, skillList->getWidth(), 18);
WindowManager *wm = environment.mWindowManager; ESMS::ESMStore &store = mWindowManager.getStore();
ESMS::ESMStore &store = environment.mWorld->getStore();
const ESM::Race *race = store.races.find(currentRaceId); const ESM::Race *race = store.races.find(currentRaceId);
int count = sizeof(race->data.bonus)/sizeof(race->data.bonus[0]); // TODO: Find a portable macro for this ARRAYSIZE? int count = sizeof(race->data.bonus)/sizeof(race->data.bonus[0]); // TODO: Find a portable macro for this ARRAYSIZE?
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
@ -261,7 +257,7 @@ void RaceDialog::updateSkills()
skillWidget = skillList->createWidget<MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default, skillWidget = skillList->createWidget<MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default,
std::string("Skill") + boost::lexical_cast<std::string>(i)); std::string("Skill") + boost::lexical_cast<std::string>(i));
skillWidget->setWindowManager(wm); skillWidget->setWindowManager(&mWindowManager);
skillWidget->setSkillNumber(skillId); skillWidget->setSkillNumber(skillId);
skillWidget->setSkillValue(MWSkill::SkillValue(race->data.bonus[i].bonus)); skillWidget->setSkillValue(MWSkill::SkillValue(race->data.bonus[i].bonus));
@ -286,7 +282,7 @@ void RaceDialog::updateSpellPowers()
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, spellPowerList->getWidth(), 18); MyGUI::IntCoord coord(0, 0, spellPowerList->getWidth(), 18);
ESMS::ESMStore &store = environment.mWorld->getStore(); ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::Race *race = store.races.find(currentRaceId); const ESM::Race *race = store.races.find(currentRaceId);
std::vector<std::string>::const_iterator it = race->powers.list.begin(); std::vector<std::string>::const_iterator it = race->powers.list.begin();
@ -295,7 +291,7 @@ void RaceDialog::updateSpellPowers()
{ {
const std::string &spellpower = *it; const std::string &spellpower = *it;
spellPowerWidget = spellPowerList->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i)); spellPowerWidget = spellPowerList->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i));
spellPowerWidget->setEnvironment(&environment); spellPowerWidget->setWindowManager(&mWindowManager);
spellPowerWidget->setSpellId(spellpower); spellPowerWidget->setSpellId(spellpower);
spellPowerItems.push_back(spellPowerWidget); spellPowerItems.push_back(spellPowerWidget);

@ -7,9 +7,9 @@
#include <boost/array.hpp> #include <boost/array.hpp>
namespace MWWorld namespace MWGui
{ {
class Environment; class WindowManager;
} }
/* /*
@ -24,7 +24,7 @@ namespace MWGui
class RaceDialog : public WindowBase class RaceDialog : public WindowBase
{ {
public: public:
RaceDialog(MWWorld::Environment& environment); RaceDialog(WindowManager& parWindowManager);
enum Gender enum Gender
{ {
@ -53,11 +53,6 @@ namespace MWGui
*/ */
EventHandle_Void eventBack; EventHandle_Void eventBack;
/** Event : Dialog finished, OK button clicked.\n
signature : void method()\n
*/
EventHandle_Void eventDone;
protected: protected:
void onHeadRotate(MyGUI::VScroll* _sender, size_t _position); void onHeadRotate(MyGUI::VScroll* _sender, size_t _position);

@ -1,6 +1,4 @@
#include "review.hpp" #include "review.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
@ -18,48 +16,46 @@ using namespace Widgets;
const int ReviewDialog::lineHeight = 18; const int ReviewDialog::lineHeight = 18;
ReviewDialog::ReviewDialog(MWWorld::Environment& environment) ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_review_layout.xml", environment) : WindowBase("openmw_chargen_review_layout.xml", parWindowManager)
, lastPos(0) , lastPos(0)
{ {
// Centre dialog // Centre dialog
center(); center();
WindowManager *wm = environment.mWindowManager;
// Setup static stats // Setup static stats
ButtonPtr button; ButtonPtr button;
getWidget(nameWidget, "NameText"); getWidget(nameWidget, "NameText");
getWidget(button, "NameButton"); getWidget(button, "NameButton");
button->setCaption(wm->getGameSettingString("sName", "")); button->setCaption(mWindowManager.getGameSettingString("sName", ""));
button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);; button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);;
getWidget(raceWidget, "RaceText"); getWidget(raceWidget, "RaceText");
getWidget(button, "RaceButton"); getWidget(button, "RaceButton");
button->setCaption(wm->getGameSettingString("sRace", "")); button->setCaption(mWindowManager.getGameSettingString("sRace", ""));
button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);; button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);;
getWidget(classWidget, "ClassText"); getWidget(classWidget, "ClassText");
getWidget(button, "ClassButton"); getWidget(button, "ClassButton");
button->setCaption(wm->getGameSettingString("sClass", "")); button->setCaption(mWindowManager.getGameSettingString("sClass", ""));
button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);; button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);;
getWidget(birthSignWidget, "SignText"); getWidget(birthSignWidget, "SignText");
getWidget(button, "SignButton"); getWidget(button, "SignButton");
button->setCaption(wm->getGameSettingString("sBirthSign", "")); button->setCaption(mWindowManager.getGameSettingString("sBirthSign", ""));
button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);; button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);;
// Setup dynamic stats // Setup dynamic stats
getWidget(health, "Health"); getWidget(health, "Health");
health->setTitle(wm->getGameSettingString("sHealth", "")); health->setTitle(mWindowManager.getGameSettingString("sHealth", ""));
health->setValue(45, 45); health->setValue(45, 45);
getWidget(magicka, "Magicka"); getWidget(magicka, "Magicka");
magicka->setTitle(wm->getGameSettingString("sMagic", "")); magicka->setTitle(mWindowManager.getGameSettingString("sMagic", ""));
magicka->setValue(50, 50); magicka->setValue(50, 50);
getWidget(fatigue, "Fatigue"); getWidget(fatigue, "Fatigue");
fatigue->setTitle(wm->getGameSettingString("sFatigue", "")); fatigue->setTitle(mWindowManager.getGameSettingString("sFatigue", ""));
fatigue->setValue(160, 160); fatigue->setValue(160, 160);
// Setup attributes // Setup attributes
@ -69,7 +65,7 @@ ReviewDialog::ReviewDialog(MWWorld::Environment& environment)
{ {
getWidget(attribute, std::string("Attribute") + boost::lexical_cast<std::string>(idx)); getWidget(attribute, std::string("Attribute") + boost::lexical_cast<std::string>(idx));
attributeWidgets.insert(std::make_pair(static_cast<int>(ESM::Attribute::attributeIds[idx]), attribute)); attributeWidgets.insert(std::make_pair(static_cast<int>(ESM::Attribute::attributeIds[idx]), attribute));
attribute->setWindowManager(wm); attribute->setWindowManager(&mWindowManager);
attribute->setAttributeId(ESM::Attribute::attributeIds[idx]); attribute->setAttributeId(ESM::Attribute::attributeIds[idx]);
attribute->setAttributeValue(MWAttribute::AttributeValue(0, 0)); attribute->setAttributeValue(MWAttribute::AttributeValue(0, 0));
} }
@ -121,7 +117,7 @@ void ReviewDialog::onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos
} }
} }
void ReviewDialog::onWindowResize(MyGUI::WidgetPtr window) void ReviewDialog::onWindowResize(MyGUI::Window* window)
{ {
updateScroller(); updateScroller();
} }
@ -134,7 +130,7 @@ void ReviewDialog::setPlayerName(const std::string &name)
void ReviewDialog::setRace(const std::string &raceId_) void ReviewDialog::setRace(const std::string &raceId_)
{ {
raceId = raceId_; raceId = raceId_;
const ESM::Race *race = environment.mWorld->getStore().races.search(raceId); const ESM::Race *race = mWindowManager.getStore().races.search(raceId);
if (race) if (race)
raceWidget->setCaption(race->name); raceWidget->setCaption(race->name);
} }
@ -148,7 +144,7 @@ void ReviewDialog::setClass(const ESM::Class& class_)
void ReviewDialog::setBirthSign(const std::string& signId) void ReviewDialog::setBirthSign(const std::string& signId)
{ {
birthSignId = signId; birthSignId = signId;
const ESM::BirthSign *sign = environment.mWorld->getStore().birthSigns.search(birthSignId); const ESM::BirthSign *sign = mWindowManager.getStore().birthSigns.search(birthSignId);
if (sign) if (sign)
birthSignWidget->setCaption(sign->name); birthSignWidget->setCaption(sign->name);
} }
@ -278,15 +274,13 @@ void ReviewDialog::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGU
void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{ {
WindowManager *wm = environment.mWindowManager;
// Add a line separator if there are items above // Add a line separator if there are items above
if (!skillWidgets.empty()) if (!skillWidgets.empty())
{ {
addSeparator(coord1, coord2); addSeparator(coord1, coord2);
} }
addGroup(wm->getGameSettingString(titleId, titleDefault), coord1, coord2); addGroup(mWindowManager.getGameSettingString(titleId, titleDefault), coord1, coord2);
SkillList::const_iterator end = skills.end(); SkillList::const_iterator end = skills.end();
for (SkillList::const_iterator it = skills.begin(); it != end; ++it) for (SkillList::const_iterator it = skills.begin(); it != end; ++it)
@ -305,7 +299,7 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId
style = CS_Super; style = CS_Super;
else if (modified < base) else if (modified < base)
style = CS_Sub; style = CS_Sub;
MyGUI::StaticTextPtr widget = addValueItem(wm->getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), style, coord1, coord2); MyGUI::StaticTextPtr widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), style, coord1, coord2);
skillWidgetMap[skillId] = widget; skillWidgetMap[skillId] = widget;
} }
} }
@ -345,7 +339,7 @@ void ReviewDialog::updateScroller()
void ReviewDialog::onOkClicked(MyGUI::Widget* _sender) void ReviewDialog::onOkClicked(MyGUI::Widget* _sender)
{ {
eventDone(); eventDone(this);
} }
void ReviewDialog::onBackClicked(MyGUI::Widget* _sender) void ReviewDialog::onBackClicked(MyGUI::Widget* _sender)
@ -355,20 +349,20 @@ void ReviewDialog::onBackClicked(MyGUI::Widget* _sender)
void ReviewDialog::onNameClicked(MyGUI::Widget* _sender) void ReviewDialog::onNameClicked(MyGUI::Widget* _sender)
{ {
eventNameActivated(); eventActivateDialog(NAME_DIALOG);
} }
void ReviewDialog::onRaceClicked(MyGUI::Widget* _sender) void ReviewDialog::onRaceClicked(MyGUI::Widget* _sender)
{ {
eventRaceActivated(); eventActivateDialog(RACE_DIALOG);
} }
void ReviewDialog::onClassClicked(MyGUI::Widget* _sender) void ReviewDialog::onClassClicked(MyGUI::Widget* _sender)
{ {
eventClassActivated(); eventActivateDialog(CLASS_DIALOG);
} }
void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender) void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender)
{ {
eventBirthSignActivated(); eventActivateDialog(BIRTHSIGN_DIALOG);
} }

@ -5,9 +5,9 @@
#include "../mwmechanics/stat.hpp" #include "../mwmechanics/stat.hpp"
#include "widgets.hpp" #include "widgets.hpp"
namespace MWWorld namespace MWGui
{ {
class Environment; class WindowManager;
} }
/* /*
@ -22,9 +22,15 @@ namespace MWGui
class ReviewDialog : public WindowBase class ReviewDialog : public WindowBase
{ {
public: public:
enum Dialogs {
NAME_DIALOG,
RACE_DIALOG,
CLASS_DIALOG,
BIRTHSIGN_DIALOG
};
typedef std::vector<int> SkillList; typedef std::vector<int> SkillList;
ReviewDialog(MWWorld::Environment& environment); ReviewDialog(WindowManager& parWindowManager);
void setPlayerName(const std::string &name); void setPlayerName(const std::string &name);
void setRace(const std::string &raceId); void setRace(const std::string &raceId);
@ -44,36 +50,14 @@ namespace MWGui
// Events // Events
typedef delegates::CDelegate0 EventHandle_Void; typedef delegates::CDelegate0 EventHandle_Void;
typedef delegates::CDelegate1<int> EventHandle_Int;
/** Event : Back button clicked.\n /** Event : Back button clicked.\n
signature : void method()\n signature : void method()\n
*/ */
EventHandle_Void eventBack; EventHandle_Void eventBack;
/** Event : Dialog finished, OK button clicked.\n EventHandle_Int eventActivateDialog;
signature : void method()\n
*/
EventHandle_Void eventDone;
/** Event : Activate name dialog.\n
signature : void method()\n
*/
EventHandle_Void eventNameActivated;
/** Event : Activate race dialog.\n
signature : void method()\n
*/
EventHandle_Void eventRaceActivated;
/** Event : Activate class dialog.\n
signature : void method()\n
*/
EventHandle_Void eventClassActivated;
/** Event : Activate birth sign dialog.\n
signature : void method()\n
*/
EventHandle_Void eventBirthSignActivated;
protected: protected:
void onOkClicked(MyGUI::Widget* _sender); void onOkClicked(MyGUI::Widget* _sender);
@ -101,7 +85,7 @@ namespace MWGui
void updateSkillArea(); void updateSkillArea();
void onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos); void onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos);
void onWindowResize(MyGUI::WidgetPtr window); void onWindowResize(MyGUI::Window* window);
static const int lineHeight; static const int lineHeight;

@ -0,0 +1,370 @@
#include "stats_window.hpp"
#include "../mwmechanics/mechanicsmanager.hpp"
#include "window_manager.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#include <boost/lexical_cast.hpp>
using namespace MWGui;
const int StatsWindow::lineHeight = 18;
StatsWindow::StatsWindow (WindowManager& parWindowManager)
: WindowBase("openmw_stats_window_layout.xml", parWindowManager)
, lastPos(0)
, reputation(0)
, bounty(0)
{
setCoord(0,0,498, 342);
const char *names[][2] =
{
{ "Attrib1", "sAttributeStrength" },
{ "Attrib2", "sAttributeIntelligence" },
{ "Attrib3", "sAttributeWillpower" },
{ "Attrib4", "sAttributeAgility" },
{ "Attrib5", "sAttributeSpeed" },
{ "Attrib6", "sAttributeEndurance" },
{ "Attrib7", "sAttributePersonality" },
{ "Attrib8", "sAttributeLuck" },
{ "Health_str", "sHealth" },
{ "Magicka_str", "sMagic" },
{ "Fatigue_str", "sFatigue" },
{ "Level_str", "sLevel" },
{ "Race_str", "sRace" },
{ "Class_str", "sClass" },
{ 0, 0 }
};
const ESMS::ESMStore &store = mWindowManager.getStore();
for (int i=0; names[i][0]; ++i)
{
setText (names[i][0], store.gameSettings.find (names[i][1])->str);
}
getWidget(skillAreaWidget, "Skills");
getWidget(skillClientWidget, "SkillClient");
getWidget(skillScrollerWidget, "SkillScroller");
skillScrollerWidget->eventScrollChangePosition = MyGUI::newDelegate(this, &StatsWindow::onScrollChangePosition);
updateScroller();
for (int i = 0; i < ESM::Skill::Length; ++i)
{
skillValues.insert(std::pair<int, MWMechanics::Stat<float> >(i, MWMechanics::Stat<float>()));
skillWidgetMap.insert(std::pair<int, MyGUI::StaticTextPtr>(i, nullptr));
}
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget);
t->eventWindowChangeCoord = MyGUI::newDelegate(this, &StatsWindow::onWindowResize);
}
void StatsWindow::onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos)
{
int diff = lastPos - pos;
// Adjust position of all widget according to difference
if (diff == 0)
return;
lastPos = pos;
std::vector<MyGUI::WidgetPtr>::const_iterator end = skillWidgets.end();
for (std::vector<MyGUI::WidgetPtr>::const_iterator it = skillWidgets.begin(); it != end; ++it)
{
(*it)->setCoord((*it)->getCoord() + MyGUI::IntPoint(0, diff));
}
}
void StatsWindow::onWindowResize(MyGUI::Window* window)
{
updateScroller();
}
void StatsWindow::setBar(const std::string& name, const std::string& tname, int val, int max)
{
MyGUI::ProgressPtr pt;
getWidget(pt, name);
pt->setProgressRange(max);
pt->setProgressPosition(val);
std::stringstream out;
out << val << "/" << max;
setText(tname, out.str().c_str());
}
void StatsWindow::setPlayerName(const std::string& playerName)
{
mMainWidget->setCaption(playerName);
}
void StatsWindow::setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value)
{
widget->setCaption(value);
if (style == CS_Super)
widget->setTextColour(MyGUI::Colour(0, 1, 0));
else if (style == CS_Sub)
widget->setTextColour(MyGUI::Colour(1, 0, 0));
else
widget->setTextColour(MyGUI::Colour(1, 1, 1));
}
void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
{
static const char *ids[] =
{
"AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5",
"AttribVal6", "AttribVal7", "AttribVal8",
0
};
for (int i=0; ids[i]; ++i)
if (ids[i]==id)
{
std::ostringstream valueString;
valueString << value.getModified();
setText (id, valueString.str());
if (value.getModified()>value.getBase())
setTextColor (id, 0, 1, 0);
else if (value.getModified()<value.getBase())
setTextColor (id, 1, 0, 0);
else
setTextColor (id, 1, 1, 1);
break;
}
}
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
{
static const char *ids[] =
{
"HBar", "MBar", "FBar",
0
};
for (int i=0; ids[i]; ++i)
if (ids[i]==id)
{
std::string id (ids[i]);
setBar (id, id + "T", value.getCurrent(), value.getModified());
}
}
void StatsWindow::setValue (const std::string& id, const std::string& value)
{
if (id=="name")
setPlayerName (value);
else if (id=="race")
setText ("RaceText", value);
else if (id=="class")
setText ("ClassText", value);
}
void StatsWindow::setValue (const std::string& id, int value)
{
if (id=="level")
{
std::ostringstream text;
text << value;
setText("LevelText", text.str());
}
}
void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
{
skillValues[parSkill] = value;
MyGUI::StaticTextPtr widget = skillWidgetMap[(int)parSkill];
if (widget)
{
float modified = value.getModified(), base = value.getBase();
std::string text = boost::lexical_cast<std::string>(std::floor(modified));
ColorStyle style = CS_Normal;
if (modified > base)
style = CS_Super;
else if (modified < base)
style = CS_Sub;
setStyledText(widget, style, text);
}
}
void StatsWindow::configureSkills (const std::vector<int>& major, const std::vector<int>& minor)
{
majorSkills = major;
minorSkills = minor;
// Update misc skills with the remaining skills not in major or minor
std::set<int> skillSet;
std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin()));
std::copy(minor.begin(), minor.end(), std::inserter(skillSet, skillSet.begin()));
boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator end = ESM::Skill::skillIds.end();
miscSkills.clear();
for (boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator it = ESM::Skill::skillIds.begin(); it != end; ++it)
{
int skill = *it;
if (skillSet.find(skill) == skillSet.end())
miscSkills.push_back(skill);
}
}
void StatsWindow::setFactions (const std::vector<Faction>& factions)
{
this->factions = factions;
}
void StatsWindow::setBirthSign (const std::string& signId)
{
birthSignId = signId;
}
void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticImagePtr separator = skillClientWidget->createWidget<MyGUI::StaticImage>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
skillWidgets.push_back(separator);
coord1.top += separator->getHeight();
coord2.top += separator->getHeight();
}
void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticTextPtr groupWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default);
groupWidget->setCaption(label);
skillWidgets.push_back(groupWidget);
coord1.top += lineHeight;
coord2.top += lineHeight;
}
MyGUI::StaticTextPtr StatsWindow::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticTextPtr skillNameWidget, skillValueWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandText", coord1, MyGUI::Align::Default);
skillNameWidget->setCaption(text);
skillValueWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandTextRight", coord2, MyGUI::Align::Default);
setStyledText(skillValueWidget, style, value);
skillWidgets.push_back(skillNameWidget);
skillWidgets.push_back(skillValueWidget);
coord1.top += lineHeight;
coord2.top += lineHeight;
return skillValueWidget;
}
void StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticTextPtr skillNameWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
skillNameWidget->setCaption(text);
skillWidgets.push_back(skillNameWidget);
coord1.top += lineHeight;
coord2.top += lineHeight;
}
void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
// Add a line separator if there are items above
if (!skillWidgets.empty())
{
addSeparator(coord1, coord2);
}
addGroup(mWindowManager.getGameSettingString(titleId, titleDefault), coord1, coord2);
SkillList::const_iterator end = skills.end();
for (SkillList::const_iterator it = skills.begin(); it != end; ++it)
{
int skillId = *it;
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
continue;
assert(skillId >= 0 && skillId < ESM::Skill::Length);
const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId];
const MWMechanics::Stat<float> &stat = skillValues.find(skillId)->second;
float base = stat.getBase();
float modified = stat.getModified();
ColorStyle style = CS_Normal;
if (modified > base)
style = CS_Super;
else if (modified < base)
style = CS_Sub;
MyGUI::StaticTextPtr widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), style, coord1, coord2);
skillWidgetMap[skillId] = widget;
}
}
void StatsWindow::updateSkillArea()
{
for (std::vector<MyGUI::WidgetPtr>::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
}
skillWidgets.clear();
const int valueSize = 40;
MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18);
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
if (!majorSkills.empty())
addSkills(majorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2);
if (!minorSkills.empty())
addSkills(minorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2);
if (!miscSkills.empty())
addSkills(miscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
ESMS::ESMStore &store = mWindowManager.getStore();
if (!factions.empty())
{
// Add a line separator if there are items above
if (!skillWidgets.empty())
addSeparator(coord1, coord2);
addGroup(mWindowManager.getGameSettingString("sFaction", "Faction"), coord1, coord2);
FactionList::const_iterator end = factions.end();
for (FactionList::const_iterator it = factions.begin(); it != end; ++it)
{
const ESM::Faction *faction = store.factions.find(it->first);
addItem(faction->name, coord1, coord2);
// TODO: Faction rank should be placed in tooltip
}
}
if (!birthSignId.empty())
{
// Add a line separator if there are items above
if (!skillWidgets.empty())
addSeparator(coord1, coord2);
addGroup(mWindowManager.getGameSettingString("sSign", "Sign"), coord1, coord2);
const ESM::BirthSign *sign = store.birthSigns.find(birthSignId);
addItem(sign->name, coord1, coord2);
}
// Add a line separator if there are items above
if (!skillWidgets.empty())
addSeparator(coord1, coord2);
addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"), boost::lexical_cast<std::string>(static_cast<int>(reputation)), CS_Normal, coord1, coord2);
addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"), boost::lexical_cast<std::string>(static_cast<int>(bounty)), CS_Normal, coord1, coord2);
clientHeight = coord1.top;
updateScroller();
}
void StatsWindow::updateScroller()
{
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
}

@ -0,0 +1,80 @@
#ifndef MWGUI_STATS_WINDOW_H
#define MWGUI_STATS_WINDOW_H
#include <components/esm_store/store.hpp>
#include <sstream>
#include <set>
#include <string>
#include <utility>
#include "../mwmechanics/stat.hpp"
#include "window_base.hpp"
namespace MWGui
{
class WindowManager;
class StatsWindow : public WindowBase
{
public:
typedef std::pair<std::string, int> Faction;
typedef std::vector<Faction> FactionList;
typedef std::vector<int> SkillList;
StatsWindow(WindowManager& parWindowManager);
void setBar(const std::string& name, const std::string& tname, int val, int max);
void setPlayerName(const std::string& playerName);
/// 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::DynamicStat<int>& value);
void setValue (const std::string& id, const std::string& value);
void setValue (const std::string& id, int value);
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
void configureSkills (const SkillList& major, const SkillList& minor);
void setFactions (const std::vector<Faction>& factions);
void setBirthSign (const std::string &signId);
void setReputation (int reputation) { this->reputation = reputation; }
void setBounty (int bounty) { this->bounty = bounty; }
void updateSkillArea();
private:
enum ColorStyle
{
CS_Sub,
CS_Normal,
CS_Super
};
void setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value);
void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
MyGUI::StaticTextPtr addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void updateScroller();
void onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos);
void onWindowResize(MyGUI::Window* window);
static const int lineHeight;
MyGUI::WidgetPtr skillAreaWidget, skillClientWidget;
MyGUI::VScrollPtr skillScrollerWidget;
int lastPos, clientHeight;
SkillList majorSkills, minorSkills, miscSkills;
std::map<int, MWMechanics::Stat<float> > skillValues;
std::map<int, MyGUI::StaticTextPtr> skillWidgetMap;
std::map<std::string, MyGUI::WidgetPtr> factionWidgetMap;
FactionList factions; ///< Stores a list of factions and the current rank
std::string birthSignId;
int reputation, bounty;
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information
};
}
#endif

@ -1,12 +1,10 @@
#include "text_input.hpp" #include "text_input.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
using namespace MWGui; using namespace MWGui;
TextInputDialog::TextInputDialog(MWWorld::Environment& environment) TextInputDialog::TextInputDialog(WindowManager& parWindowManager)
: WindowBase("openmw_text_input_layout.xml", environment) : WindowBase("openmw_text_input_layout.xml", parWindowManager)
{ {
// Centre dialog // Centre dialog
center(); center();
@ -55,10 +53,10 @@ void TextInputDialog::open()
void TextInputDialog::onOkClicked(MyGUI::Widget* _sender) void TextInputDialog::onOkClicked(MyGUI::Widget* _sender)
{ {
eventDone(); eventDone(this);
} }
void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender) void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
{ {
eventDone(); eventDone(this);
} }

@ -3,9 +3,9 @@
#include "window_base.hpp" #include "window_base.hpp"
namespace MWWorld namespace MWGui
{ {
class Environment; class WindowManager;
} }
/* /*
@ -18,7 +18,7 @@ namespace MWGui
class TextInputDialog : public WindowBase class TextInputDialog : public WindowBase
{ {
public: public:
TextInputDialog(MWWorld::Environment& environment); TextInputDialog(WindowManager& parWindowManager);
std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; } std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; }
void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); } void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); }
@ -27,14 +27,6 @@ namespace MWGui
void setTextLabel(const std::string &label); void setTextLabel(const std::string &label);
void open(); void open();
// Events
typedef delegates::CDelegate0 EventHandle_Void;
/** Event : Dialog finished, OK button clicked.\n
signature : void method()\n
*/
EventHandle_Void eventDone;
protected: protected:
void onOkClicked(MyGUI::Widget* _sender); void onOkClicked(MyGUI::Widget* _sender);
void onTextAccepted(MyGUI::Edit* _sender); void onTextAccepted(MyGUI::Edit* _sender);

@ -1,7 +1,5 @@
#include "widgets.hpp" #include "widgets.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -267,7 +265,7 @@ void MWAttribute::shutdownWidgetSkin()
/* MWSpell */ /* MWSpell */
MWSpell::MWSpell() MWSpell::MWSpell()
: env(nullptr) : mWindowManager(nullptr)
, spellNameWidget(nullptr) , spellNameWidget(nullptr)
{ {
} }
@ -280,7 +278,7 @@ void MWSpell::setSpellId(const std::string &spellId)
void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord) void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord)
{ {
ESMS::ESMStore &store = env->mWorld->getStore(); ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::Spell *spell = store.spells.search(id); const ESM::Spell *spell = store.spells.search(id);
MYGUI_ASSERT(spell, "spell with id '" << id << "' not found"); MYGUI_ASSERT(spell, "spell with id '" << id << "' not found");
@ -289,7 +287,7 @@ void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI:
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->effects.list.begin(); it != end; ++it) for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->effects.list.begin(); it != end; ++it)
{ {
effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default); effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default);
effect->setEnvironment(env); effect->setWindowManager(mWindowManager);
effect->setSpellEffect(*it); effect->setSpellEffect(*it);
effects.push_back(effect); effects.push_back(effect);
coord.top += effect->getHeight(); coord.top += effect->getHeight();
@ -298,9 +296,9 @@ void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI:
void MWSpell::updateWidgets() void MWSpell::updateWidgets()
{ {
if (spellNameWidget && env) if (spellNameWidget && mWindowManager)
{ {
ESMS::ESMStore &store = env->mWorld->getStore(); ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::Spell *spell = store.spells.search(id); const ESM::Spell *spell = store.spells.search(id);
if (spell) if (spell)
spellNameWidget->setCaption(spell->name); spellNameWidget->setCaption(spell->name);
@ -348,7 +346,7 @@ void MWSpell::shutdownWidgetSkin()
/* MWSpellEffect */ /* MWSpellEffect */
MWSpellEffect::MWSpellEffect() MWSpellEffect::MWSpellEffect()
: env(nullptr) : mWindowManager(nullptr)
, imageWidget(nullptr) , imageWidget(nullptr)
, textWidget(nullptr) , textWidget(nullptr)
{ {
@ -362,11 +360,10 @@ void MWSpellEffect::setSpellEffect(SpellEffectValue value)
void MWSpellEffect::updateWidgets() void MWSpellEffect::updateWidgets()
{ {
if (!env) if (!mWindowManager)
return; return;
ESMS::ESMStore &store = env->mWorld->getStore(); ESMS::ESMStore &store = mWindowManager->getStore();
WindowManager *wm = env->mWindowManager;
const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID); const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID);
if (textWidget) if (textWidget)
{ {
@ -376,7 +373,7 @@ void MWSpellEffect::updateWidgets()
std::string spellLine = ""; std::string spellLine = "";
if (effect.skill >= 0 && effect.skill < ESM::Skill::Length) if (effect.skill >= 0 && effect.skill < ESM::Skill::Length)
{ {
spellLine += " " + wm->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], ""); spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], "");
} }
if (effect.attribute >= 0 && effect.attribute < 8) if (effect.attribute >= 0 && effect.attribute < 8)
{ {
@ -390,7 +387,7 @@ void MWSpellEffect::updateWidgets()
"sAttributePersonality", "sAttributePersonality",
"sAttributeLuck" "sAttributeLuck"
}; };
spellLine += " " + wm->getGameSettingString(attributes[effect.attribute], ""); spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], "");
} }
if (effect.magnMin >= 0 || effect.magnMax >= 0) if (effect.magnMin >= 0 || effect.magnMax >= 0)
{ {

@ -7,11 +7,6 @@
#include "../mwmechanics/stat.hpp" #include "../mwmechanics/stat.hpp"
namespace MWWorld
{
class Environment;
}
/* /*
This file contains various custom widgets used in OpenMW. This file contains various custom widgets used in OpenMW.
*/ */
@ -129,11 +124,10 @@ namespace MWGui
typedef MWMechanics::Stat<int> SpellValue; typedef MWMechanics::Stat<int> SpellValue;
void setEnvironment(MWWorld::Environment *env_) { env = env_; } void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; }
void setSpellId(const std::string &id); void setSpellId(const std::string &id);
void createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord); void createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord);
MWWorld::Environment *getEnvironment() const { return env; }
const std::string &getSpellId() const { return id; } const std::string &getSpellId() const { return id; }
/*internal:*/ /*internal:*/
@ -150,7 +144,7 @@ namespace MWGui
void updateWidgets(); void updateWidgets();
MWWorld::Environment *env; WindowManager* mWindowManager;
std::string id; std::string id;
MyGUI::StaticTextPtr spellNameWidget; MyGUI::StaticTextPtr spellNameWidget;
}; };
@ -164,10 +158,9 @@ namespace MWGui
typedef ESM::ENAMstruct SpellEffectValue; typedef ESM::ENAMstruct SpellEffectValue;
void setEnvironment(MWWorld::Environment *env_) { env = env_; } void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; }
void setSpellEffect(SpellEffectValue value); void setSpellEffect(SpellEffectValue value);
MWWorld::Environment *getEnvironment() const { return env; }
const SpellEffectValue &getSpellEffect() const { return effect; } const SpellEffectValue &getSpellEffect() const { return effect; }
/*internal:*/ /*internal:*/
@ -184,7 +177,7 @@ namespace MWGui
void updateWidgets(); void updateWidgets();
MWWorld::Environment *env; WindowManager* mWindowManager;
SpellEffectValue effect; SpellEffectValue effect;
MyGUI::StaticImagePtr imageWidget; MyGUI::StaticImagePtr imageWidget;
MyGUI::StaticTextPtr textWidget; MyGUI::StaticTextPtr textWidget;

@ -1,12 +1,11 @@
#include "window_base.hpp" #include "window_base.hpp"
#include "../mwworld/environment.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
using namespace MWGui; using namespace MWGui;
WindowBase::WindowBase(const std::string& parLayout, MWWorld::Environment& parEnvironment) WindowBase::WindowBase(const std::string& parLayout, WindowManager& parWindowManager)
: Layout(parLayout) : Layout(parLayout)
, environment(parEnvironment) , mWindowManager(parWindowManager)
{ {
} }
@ -17,7 +16,7 @@ void WindowBase::open()
void WindowBase::center() void WindowBase::center()
{ {
// Centre dialog // Centre dialog
MyGUI::IntSize gameWindowSize = environment.mWindowManager->getGui()->getViewSize(); MyGUI::IntSize gameWindowSize = mWindowManager.getGui()->getViewSize();
MyGUI::IntCoord coord = mMainWidget->getCoord(); MyGUI::IntCoord coord = mMainWidget->getCoord();
coord.left = (gameWindowSize.width - coord.width)/2; coord.left = (gameWindowSize.width - coord.width)/2;
coord.top = (gameWindowSize.height - coord.height)/2; coord.top = (gameWindowSize.height - coord.height)/2;

@ -3,23 +3,28 @@
#include <openengine/gui/layout.hpp> #include <openengine/gui/layout.hpp>
namespace MWWorld
{
class Environment;
}
namespace MWGui namespace MWGui
{ {
class WindowManager;
class WindowBase: public OEngine::GUI::Layout class WindowBase: public OEngine::GUI::Layout
{ {
public: public:
WindowBase(const std::string& parLayout, MWWorld::Environment& parEnvironment); WindowBase(const std::string& parLayout, WindowManager& parWindowManager);
// Events
typedef MyGUI::delegates::CDelegate1<WindowBase*> EventHandle_WindowBase;
virtual void open(); virtual void open();
void center(); void center();
/** Event : Dialog finished, OK button clicked.\n
signature : void method()\n
*/
EventHandle_WindowBase eventDone;
protected: protected:
MWWorld::Environment& environment; WindowManager& mWindowManager;
}; };
} }

@ -7,6 +7,7 @@
#include "review.hpp" #include "review.hpp"
#include "dialogue.hpp" #include "dialogue.hpp"
#include "dialogue_history.hpp" #include "dialogue_history.hpp"
#include "stats_window.hpp"
#include "../mwmechanics/mechanicsmanager.hpp" #include "../mwmechanics/mechanicsmanager.hpp"
#include "../mwinput/inputmanager.hpp" #include "../mwinput/inputmanager.hpp"
@ -20,7 +21,7 @@
using namespace MWGui; using namespace MWGui;
WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment, WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment,
const Compiler::Extensions& extensions, bool newGame) const Compiler::Extensions& extensions, bool fpsSwitch, bool newGame)
: environment(environment) : environment(environment)
, nameDialog(nullptr) , nameDialog(nullptr)
, raceDialog(nullptr) , raceDialog(nullptr)
@ -32,11 +33,6 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment
, createClassDialog(nullptr) , createClassDialog(nullptr)
, birthSignDialog(nullptr) , birthSignDialog(nullptr)
, reviewDialog(nullptr) , reviewDialog(nullptr)
, nameChosen(false)
, raceChosen(false)
, classChosen(false)
, birthSignChosen(false)
, reviewNext(false)
, gui(_gui) , gui(_gui)
, mode(GM_Game) , mode(GM_Game)
, nextMode(GM_Game) , nextMode(GM_Game)
@ -44,65 +40,68 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment
, shown(GW_ALL) , shown(GW_ALL)
, allowed(newGame ? GW_None : GW_ALL) , allowed(newGame ? GW_None : GW_ALL)
{ {
showFPSCounter = fpsSwitch;
creationStage = NotStarted;
//Register own widgets with MyGUI //Register own widgets with MyGUI
MyGUI::FactoryManager::getInstance().registerFactory<DialogeHistory>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<DialogeHistory>("Widget");
// Get size info from the Gui object // Get size info from the Gui object
assert(gui); assert(gui);
int w = gui->getViewSize().width; int w = gui->getViewSize().width;
int h = gui->getViewSize().height; int h = gui->getViewSize().height;
hud = new HUD(w,h); hud = new HUD(w,h, showFPSCounter);
menu = new MainMenu(w,h); menu = new MainMenu(w,h);
map = new MapWindow(); map = new MapWindow();
stats = new StatsWindow (environment); stats = new StatsWindow(*this);
#if 0 #if 0
inventory = new InventoryWindow (); inventory = new InventoryWindow ();
#endif #endif
console = new Console(w,h, environment, extensions); console = new Console(w,h, environment, extensions);
// The HUD is always on // The HUD is always on
hud->setVisible(true); hud->setVisible(true);
// Setup player stats // Setup player stats
for (int i = 0; i < ESM::Attribute::Length; ++i) for (int i = 0; i < ESM::Attribute::Length; ++i)
{ {
playerAttributes.insert(std::make_pair(ESM::Attribute::attributeIds[i], MWMechanics::Stat<int>())); playerAttributes.insert(std::make_pair(ESM::Attribute::attributeIds[i], MWMechanics::Stat<int>()));
} }
for (int i = 0; i < ESM::Skill::Length; ++i) for (int i = 0; i < ESM::Skill::Length; ++i)
{ {
playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>())); playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>()));
} }
// Set up visibility // Set up visibility
updateVisible(); updateVisible();
} }
WindowManager::~WindowManager() WindowManager::~WindowManager()
{ {
delete console; delete console;
delete hud; delete hud;
delete map; delete map;
delete menu; delete menu;
delete stats; delete stats;
#if 0 #if 0
delete inventory; delete inventory;
#endif #endif
delete nameDialog; delete nameDialog;
delete raceDialog; delete raceDialog;
delete dialogueWindow; delete dialogueWindow;
delete classChoiceDialog; delete classChoiceDialog;
delete generateClassQuestionDialog; delete generateClassQuestionDialog;
delete generateClassResultDialog; delete generateClassResultDialog;
delete pickClassDialog; delete pickClassDialog;
delete createClassDialog; delete createClassDialog;
delete birthSignDialog; delete birthSignDialog;
delete reviewDialog; delete reviewDialog;
cleanupGarbage(); cleanupGarbage();
} }
void WindowManager::cleanupGarbage() void WindowManager::cleanupGarbage()
@ -127,6 +126,10 @@ void WindowManager::update()
environment.mInputManager->setGuiMode(nextMode); environment.mInputManager->setGuiMode(nextMode);
nextMode = GM_Game; nextMode = GM_Game;
} }
if (showFPSCounter)
{
hud->setFPS(mFPS);
}
} }
void WindowManager::setNextMode(GuiMode newMode) void WindowManager::setNextMode(GuiMode newMode)
@ -142,198 +145,193 @@ void WindowManager::setGuiMode(GuiMode newMode)
void WindowManager::updateVisible() void WindowManager::updateVisible()
{ {
// Start out by hiding everything except the HUD // Start out by hiding everything except the HUD
map->setVisible(false); map->setVisible(false);
menu->setVisible(false); menu->setVisible(false);
stats->setVisible(false); stats->setVisible(false);
#if 0 #if 0
inventory->setVisible(false); inventory->setVisible(false);
#endif #endif
console->disable(); console->disable();
// Mouse is visible whenever we're not in game mode // Mouse is visible whenever we're not in game mode
gui->setVisiblePointer(isGuiMode()); gui->setVisiblePointer(isGuiMode());
// If in game mode, don't show anything. // If in game mode, don't show anything.
if(mode == GM_Game) if(mode == GM_Game)
{ {
return; return;
} }
if(mode == GM_MainMenu) if(mode == GM_MainMenu)
{ {
// Enable the main menu // Enable the main menu
menu->setVisible(true); menu->setVisible(true);
return; return;
} }
if(mode == GM_Console) if(mode == GM_Console)
{ {
console->enable(); console->enable();
return; return;
} }
if (mode == GM_Name) if (mode == GM_Name)
{ {
if (nameDialog) if (nameDialog)
removeDialog(nameDialog); removeDialog(nameDialog);
nameDialog = new TextInputDialog(environment); nameDialog = new TextInputDialog(*this);
std::string sName = getGameSettingString("sName", "Name"); std::string sName = getGameSettingString("sName", "Name");
nameDialog->setTextLabel(sName); nameDialog->setTextLabel(sName);
nameDialog->setTextInput(playerName); nameDialog->setTextInput(playerName);
nameDialog->setNextButtonShow(nameChosen || reviewNext); nameDialog->setNextButtonShow(creationStage >= NameChosen);
nameDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onNameDialogDone); nameDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onNameDialogDone);
nameDialog->open(); nameDialog->open();
return; return;
} }
if (mode == GM_Race) if (mode == GM_Race)
{ {
if (raceDialog) if (raceDialog)
removeDialog(raceDialog); removeDialog(raceDialog);
raceDialog = new RaceDialog(environment); raceDialog = new RaceDialog(*this);
raceDialog->setNextButtonShow(raceChosen || reviewNext); raceDialog->setNextButtonShow(creationStage >= RaceChosen);
raceDialog->setRaceId(playerRaceId); raceDialog->setRaceId(playerRaceId);
raceDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onRaceDialogDone); raceDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onRaceDialogDone);
raceDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onRaceDialogBack); raceDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onRaceDialogBack);
raceDialog->open(); raceDialog->open();
return; return;
} }
if (mode == GM_Class) if (mode == GM_Class)
{ {
if (classChoiceDialog) if (classChoiceDialog)
removeDialog(classChoiceDialog); removeDialog(classChoiceDialog);
classChoiceDialog = new ClassChoiceDialog(environment); classChoiceDialog = new ClassChoiceDialog(*this);
classChoiceDialog->eventButtonSelected = MyGUI::newDelegate(this, &WindowManager::onClassChoice); classChoiceDialog->eventButtonSelected = MyGUI::newDelegate(this, &WindowManager::onClassChoice);
classChoiceDialog->open(); classChoiceDialog->open();
return; return;
} }
if (mode == GM_ClassGenerate) if (mode == GM_ClassGenerate)
{ {
generateClassStep = 0; generateClassStep = 0;
generateClass = ""; generateClass = "";
generateClassSpecializations[0] = 0; generateClassSpecializations[0] = 0;
generateClassSpecializations[1] = 0; generateClassSpecializations[1] = 0;
generateClassSpecializations[2] = 0; generateClassSpecializations[2] = 0;
showClassQuestionDialog(); showClassQuestionDialog();
return; return;
} }
if (mode == GM_ClassPick) if (mode == GM_ClassPick)
{ {
if (pickClassDialog) if (pickClassDialog)
removeDialog(pickClassDialog); removeDialog(pickClassDialog);
pickClassDialog = new PickClassDialog(environment); pickClassDialog = new PickClassDialog(*this);
pickClassDialog->setNextButtonShow(classChosen || reviewNext); pickClassDialog->setNextButtonShow(creationStage >= ClassChosen);
pickClassDialog->setClassId(playerClass.name); pickClassDialog->setClassId(playerClass.name);
pickClassDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onPickClassDialogDone); pickClassDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onPickClassDialogDone);
pickClassDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onPickClassDialogBack); pickClassDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onPickClassDialogBack);
pickClassDialog->open(); pickClassDialog->open();
return; return;
} }
if (mode == GM_ClassCreate) if (mode == GM_ClassCreate)
{ {
if (createClassDialog) if (createClassDialog)
removeDialog(createClassDialog); removeDialog(createClassDialog);
createClassDialog = new CreateClassDialog(environment); createClassDialog = new CreateClassDialog(*this);
createClassDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onCreateClassDialogDone); createClassDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onCreateClassDialogDone);
createClassDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onCreateClassDialogBack); createClassDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onCreateClassDialogBack);
createClassDialog->open(); createClassDialog->open();
return; return;
} }
if (mode == GM_Birth) if (mode == GM_Birth)
{ {
if (birthSignDialog) if (birthSignDialog)
removeDialog(birthSignDialog); removeDialog(birthSignDialog);
birthSignDialog = new BirthDialog(environment); birthSignDialog = new BirthDialog(*this);
birthSignDialog->setNextButtonShow(birthSignChosen || reviewNext); birthSignDialog->setNextButtonShow(creationStage >= BirthSignChosen);
birthSignDialog->setBirthId(playerBirthSignId); birthSignDialog->setBirthId(playerBirthSignId);
birthSignDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogDone); birthSignDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogDone);
birthSignDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogBack); birthSignDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogBack);
birthSignDialog->open(); birthSignDialog->open();
return; return;
} }
if (mode == GM_Review) if (mode == GM_Review)
{ {
reviewNext = false; if (reviewDialog)
if (reviewDialog) removeDialog(reviewDialog);
removeDialog(reviewDialog); reviewDialog = new ReviewDialog(*this);
reviewDialog = new ReviewDialog(environment); reviewDialog->setPlayerName(playerName);
reviewDialog->setPlayerName(playerName); reviewDialog->setRace(playerRaceId);
reviewDialog->setRace(playerRaceId); reviewDialog->setClass(playerClass);
reviewDialog->setClass(playerClass); reviewDialog->setBirthSign(playerBirthSignId);
reviewDialog->setBirthSign(playerBirthSignId);
reviewDialog->setHealth(playerHealth);
reviewDialog->setHealth(playerHealth); reviewDialog->setMagicka(playerMagicka);
reviewDialog->setMagicka(playerMagicka); reviewDialog->setFatigue(playerFatigue);
reviewDialog->setFatigue(playerFatigue);
{
{ std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator end = playerAttributes.end();
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator end = playerAttributes.end(); for (std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator it = playerAttributes.begin(); it != end; ++it)
for (std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator it = playerAttributes.begin(); it != end; ++it) {
{ reviewDialog->setAttribute(it->first, it->second);
reviewDialog->setAttribute(it->first, it->second); }
} }
}
{
{ std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator end = playerSkillValues.end();
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator end = playerSkillValues.end(); for (std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator it = playerSkillValues.begin(); it != end; ++it)
for (std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator it = playerSkillValues.begin(); it != end; ++it) {
{ reviewDialog->setSkillValue(it->first, it->second);
reviewDialog->setSkillValue(it->first, it->second); }
} reviewDialog->configureSkills(playerMajorSkills, playerMinorSkills);
reviewDialog->configureSkills(playerMajorSkills, playerMinorSkills); }
}
reviewDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onReviewDialogDone);
reviewDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onReviewDialogDone); reviewDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onReviewDialogBack);
reviewDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onReviewDialogBack); reviewDialog->eventActivateDialog = MyGUI::newDelegate(this, &WindowManager::onReviewActivateDialog);
reviewDialog->open();
reviewDialog->eventNameActivated = MyGUI::newDelegate(this, &WindowManager::onNameDialogActivate); return;
reviewDialog->eventRaceActivated = MyGUI::newDelegate(this, &WindowManager::onRaceDialogActivate); }
reviewDialog->eventClassActivated = MyGUI::newDelegate(this, &WindowManager::onClassDialogActivate);
reviewDialog->eventBirthSignActivated = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogActivate); if(mode == GM_Inventory)
{
reviewDialog->open(); // Ah, inventory mode. First, compute the effective set of
return; // windows to show. This is controlled both by what windows the
} // user has opened/closed (the 'shown' variable) and by what
// windows we are allowed to show (the 'allowed' var.)
if(mode == GM_Inventory) int eff = shown & allowed;
{
// Ah, inventory mode. First, compute the effective set of // Show the windows we want
// windows to show. This is controlled both by what windows the map -> setVisible( (eff & GW_Map) != 0 );
// user has opened/closed (the 'shown' variable) and by what stats -> setVisible( (eff & GW_Stats) != 0 );
// windows we are allowed to show (the 'allowed' var.)
int eff = shown & allowed;
// Show the windows we want
map -> setVisible( (eff & GW_Map) != 0 );
stats -> setVisible( (eff & GW_Stats) != 0 );
#if 0 #if 0
// inventory -> setVisible( eff & GW_Inventory ); // inventory -> setVisible( eff & GW_Inventory );
#endif #endif
return; return;
} }
if (mode == GM_Dialogue) if (mode == GM_Dialogue)
{ {
if (dialogueWindow) if (!dialogueWindow)
removeDialog(dialogueWindow); {
dialogueWindow = new DialogueWindow(environment); dialogueWindow = new DialogueWindow(*this);
dialogueWindow->eventBye = MyGUI::newDelegate(this, &WindowManager::onDialogueWindowBye); dialogueWindow->eventBye = MyGUI::newDelegate(this, &WindowManager::onDialogueWindowBye);
dialogueWindow->open(); }
return; dialogueWindow->open();
} return;
}
// Unsupported mode, switch back to game // Unsupported mode, switch back to game
// Note: The call will eventually end up this method again but // Note: The call will eventually end up this method again but
// will stop at the check if(mode == GM_Game) above. // will stop at the check if(mode == GM_Game) above.
setGuiMode(GM_Game); setGuiMode(GM_Game);
} }
void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value) void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
@ -365,49 +363,11 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int
} }
} }
void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<float>& value)
{
stats->setValue (id, value);
static struct {const char *id; ESM::Skill::SkillEnum skillId; } skillMap[] = void WindowManager::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
{ {
{"SkillBlock", ESM::Skill::Block}, stats->setValue(parSkill, value);
{"SkillArmorer", ESM::Skill::Armorer}, playerSkillValues[parSkill] = value;
{"SkillMediumArmor", ESM::Skill::MediumArmor},
{"SkillHeavyArmor", ESM::Skill::HeavyArmor},
{"SkillBluntWeapon", ESM::Skill::BluntWeapon},
{"SkillLongBlade", ESM::Skill::LongBlade},
{"SkillAxe", ESM::Skill::Axe},
{"SkillSpear", ESM::Skill::Spear},
{"SkillAthletics", ESM::Skill::Athletics},
{"SkillEnchant", ESM::Skill::Armorer},
{"SkillDestruction", ESM::Skill::Destruction},
{"SkillAlteration", ESM::Skill::Alteration},
{"SkillIllusion", ESM::Skill::Illusion},
{"SkillConjuration", ESM::Skill::Conjuration},
{"SkillMysticism", ESM::Skill::Mysticism},
{"SkillRestoration", ESM::Skill::Restoration},
{"SkillAlchemy", ESM::Skill::Alchemy},
{"SkillUnarmored", ESM::Skill::Unarmored},
{"SkillSecurity", ESM::Skill::Security},
{"SkillSneak", ESM::Skill::Sneak},
{"SkillAcrobatics", ESM::Skill::Acrobatics},
{"SkillLightArmor", ESM::Skill::LightArmor},
{"SkillShortBlade", ESM::Skill::ShortBlade},
{"SkillMarksman", ESM::Skill::Marksman},
{"SkillMercantile", ESM::Skill::Mercantile},
{"SkillSpeechcraft", ESM::Skill::Speechcraft},
{"SkillHandToHand", ESM::Skill::HandToHand},
};
for (size_t i = 0; i < sizeof(skillMap)/sizeof(skillMap[0]); ++i)
{
if (skillMap[i].id == id)
{
ESM::Skill::SkillEnum skillId = skillMap[i].skillId;
playerSkillValues[skillId] = value;
break;
}
}
} }
void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value) void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
@ -504,7 +464,7 @@ const std::string &WindowManager::getGameSettingString(const std::string &id, co
return default_; return default_;
} }
void WindowManager::onNameDialogDone() void WindowManager::onNameDialogDone(WindowBase* parWindow)
{ {
if (nameDialog) if (nameDialog)
{ {
@ -513,18 +473,19 @@ void WindowManager::onNameDialogDone()
removeDialog(nameDialog); removeDialog(nameDialog);
} }
bool goNext = nameChosen; // Go to next dialog if name was previously chosen // Go to next dialog if name was previously chosen
nameChosen = true; if (creationStage == ReviewNext)
if (reviewNext)
setGuiMode(GM_Review); setGuiMode(GM_Review);
else if (goNext) else if (creationStage >= NameChosen)
setGuiMode(GM_Race); setGuiMode(GM_Race);
else else
{
creationStage = NameChosen;
setGuiMode(GM_Game); setGuiMode(GM_Game);
}
} }
void WindowManager::onRaceDialogDone() void WindowManager::onRaceDialogDone(WindowBase* parWindow)
{ {
if (raceDialog) if (raceDialog)
{ {
@ -534,15 +495,16 @@ void WindowManager::onRaceDialogDone()
removeDialog(raceDialog); removeDialog(raceDialog);
} }
bool goNext = raceChosen; // Go to next dialog if race was previously chosen // Go to next dialog if race was previously chosen
raceChosen = true; if (creationStage == ReviewNext)
if (reviewNext)
setGuiMode(GM_Review); setGuiMode(GM_Review);
else if (goNext) else if(creationStage >= RaceChosen)
setGuiMode(GM_Class); setGuiMode(GM_Class);
else else
{
creationStage = RaceChosen;
setGuiMode(GM_Game); setGuiMode(GM_Game);
}
} }
void WindowManager::onDialogueWindowBye() void WindowManager::onDialogueWindowBye()
@ -568,29 +530,29 @@ void WindowManager::onRaceDialogBack()
setGuiMode(GM_Name); setGuiMode(GM_Name);
} }
void WindowManager::onClassChoice(MyGUI::WidgetPtr, int _index) void WindowManager::onClassChoice(int _index)
{ {
if (classChoiceDialog) if (classChoiceDialog)
{ {
removeDialog(classChoiceDialog); removeDialog(classChoiceDialog);
} }
if (_index == ClassChoiceDialog::Class_Generate) switch(_index)
{
setGuiMode(GM_ClassGenerate);
}
else if (_index == ClassChoiceDialog::Class_Pick)
{ {
setGuiMode(GM_ClassPick); case ClassChoiceDialog::Class_Generate:
} setGuiMode(GM_ClassGenerate);
else if (_index == ClassChoiceDialog::Class_Create) break;
{ case ClassChoiceDialog::Class_Pick:
setGuiMode(GM_ClassCreate); setGuiMode(GM_ClassPick);
} break;
else if (_index == ClassChoiceDialog::Class_Back) case ClassChoiceDialog::Class_Create:
{ setGuiMode(GM_ClassCreate);
setGuiMode(GM_Race); break;
} case ClassChoiceDialog::Class_Back:
setGuiMode(GM_Race);
break;
};
} }
namespace MWGui namespace MWGui
@ -678,18 +640,6 @@ namespace MWGui
} }; } };
} }
namespace MWGui
{
struct ClassPoint
{
const char *id;
// Specialization points to match, in order: Stealth, Combat, Magic
// Note: Order is taken from http://www.uesp.net/wiki/Morrowind:Class_Quiz
int points[3];
};
}
void WindowManager::showClassQuestionDialog() void WindowManager::showClassQuestionDialog()
{ {
if (generateClassStep == generateClassSteps.size()) if (generateClassStep == generateClassSteps.size())
@ -753,7 +703,7 @@ void WindowManager::showClassQuestionDialog()
if (generateClassResultDialog) if (generateClassResultDialog)
removeDialog(generateClassResultDialog); removeDialog(generateClassResultDialog);
generateClassResultDialog = new GenerateClassResultDialog(environment); generateClassResultDialog = new GenerateClassResultDialog(*this);
generateClassResultDialog->setClassId(generateClass); generateClassResultDialog->setClassId(generateClass);
generateClassResultDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onGenerateClassBack); generateClassResultDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onGenerateClassBack);
generateClassResultDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onGenerateClassDone); generateClassResultDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onGenerateClassDone);
@ -769,7 +719,7 @@ void WindowManager::showClassQuestionDialog()
if (generateClassQuestionDialog) if (generateClassQuestionDialog)
removeDialog(generateClassQuestionDialog); removeDialog(generateClassQuestionDialog);
generateClassQuestionDialog = new InfoBoxDialog(environment); generateClassQuestionDialog = new InfoBoxDialog(*this);
InfoBoxDialog::ButtonList buttons; InfoBoxDialog::ButtonList buttons;
generateClassQuestionDialog->setText(generateClassSteps[generateClassStep].text); generateClassQuestionDialog->setText(generateClassSteps[generateClassStep].text);
@ -781,7 +731,7 @@ void WindowManager::showClassQuestionDialog()
generateClassQuestionDialog->open(); generateClassQuestionDialog->open();
} }
void WindowManager::onClassQuestionChosen(MyGUI::Widget* _sender, int _index) void WindowManager::onClassQuestionChosen(int _index)
{ {
if (generateClassQuestionDialog) if (generateClassQuestionDialog)
removeDialog(generateClassQuestionDialog); removeDialog(generateClassQuestionDialog);
@ -804,7 +754,8 @@ void WindowManager::onClassQuestionChosen(MyGUI::Widget* _sender, int _index)
void WindowManager::onGenerateClassBack() void WindowManager::onGenerateClassBack()
{ {
classChosen = true; if(creationStage < ClassChosen)
creationStage = ClassChosen;
if (generateClassResultDialog) if (generateClassResultDialog)
removeDialog(generateClassResultDialog); removeDialog(generateClassResultDialog);
@ -813,25 +764,26 @@ void WindowManager::onGenerateClassBack()
setGuiMode(GM_Class); setGuiMode(GM_Class);
} }
void WindowManager::onGenerateClassDone() void WindowManager::onGenerateClassDone(WindowBase* parWindow)
{ {
bool goNext = classChosen; // Go to next dialog if class was previously chosen
classChosen = true;
if (generateClassResultDialog) if (generateClassResultDialog)
removeDialog(generateClassResultDialog); removeDialog(generateClassResultDialog);
environment.mMechanicsManager->setPlayerClass(generateClass); environment.mMechanicsManager->setPlayerClass(generateClass);
if (reviewNext) // Go to next dialog if class was previously chosen
if (creationStage == ReviewNext)
setGuiMode(GM_Review); setGuiMode(GM_Review);
else if (goNext) else if (creationStage >= ClassChosen)
setGuiMode(GM_Birth); setGuiMode(GM_Birth);
else else
{
creationStage = ClassChosen;
setGuiMode(GM_Game); setGuiMode(GM_Game);
}
} }
void WindowManager::onPickClassDialogDone() void WindowManager::onPickClassDialogDone(WindowBase* parWindow)
{ {
if (pickClassDialog) if (pickClassDialog)
{ {
@ -844,15 +796,16 @@ void WindowManager::onPickClassDialogDone()
removeDialog(pickClassDialog); removeDialog(pickClassDialog);
} }
bool goNext = classChosen; // Go to next dialog if class was previously chosen // Go to next dialog if class was previously chosen
classChosen = true; if (creationStage == ReviewNext)
if (reviewNext)
setGuiMode(GM_Review); setGuiMode(GM_Review);
else if (goNext) else if (creationStage >= ClassChosen)
setGuiMode(GM_Birth); setGuiMode(GM_Birth);
else else
{
creationStage = ClassChosen;
setGuiMode(GM_Game); setGuiMode(GM_Game);
}
} }
void WindowManager::onPickClassDialogBack() void WindowManager::onPickClassDialogBack()
@ -868,7 +821,7 @@ void WindowManager::onPickClassDialogBack()
setGuiMode(GM_Class); setGuiMode(GM_Class);
} }
void WindowManager::onCreateClassDialogDone() void WindowManager::onCreateClassDialogDone(WindowBase* parWindow)
{ {
if (createClassDialog) if (createClassDialog)
{ {
@ -898,15 +851,16 @@ void WindowManager::onCreateClassDialogDone()
removeDialog(createClassDialog); removeDialog(createClassDialog);
} }
bool goNext = classChosen; // Go to next dialog if class was previously chosen // Go to next dialog if class was previously chosen
classChosen = true; if (creationStage == ReviewNext)
if (reviewNext)
setGuiMode(GM_Review); setGuiMode(GM_Review);
else if (goNext) else if (creationStage >= ClassChosen)
setGuiMode(GM_Birth); setGuiMode(GM_Birth);
else else
{
creationStage = ClassChosen;
setGuiMode(GM_Game); setGuiMode(GM_Game);
}
} }
void WindowManager::onCreateClassDialogBack() void WindowManager::onCreateClassDialogBack()
@ -917,7 +871,7 @@ void WindowManager::onCreateClassDialogBack()
setGuiMode(GM_Class); setGuiMode(GM_Class);
} }
void WindowManager::onBirthSignDialogDone() void WindowManager::onBirthSignDialogDone(WindowBase* parWindow)
{ {
if (birthSignDialog) if (birthSignDialog)
{ {
@ -927,13 +881,14 @@ void WindowManager::onBirthSignDialogDone()
removeDialog(birthSignDialog); removeDialog(birthSignDialog);
} }
bool goNext = birthSignChosen; // Go to next dialog if birth sign was previously chosen // Go to next dialog if birth sign was previously chosen
birthSignChosen = true; if (creationStage >= BirthSignChosen)
if (reviewNext || goNext)
setGuiMode(GM_Review); setGuiMode(GM_Review);
else else
{
creationStage = BirthSignChosen;
setGuiMode(GM_Game); setGuiMode(GM_Game);
}
} }
void WindowManager::onBirthSignDialogBack() void WindowManager::onBirthSignDialogBack()
@ -947,7 +902,7 @@ void WindowManager::onBirthSignDialogBack()
setGuiMode(GM_Class); setGuiMode(GM_Class);
} }
void WindowManager::onReviewDialogDone() void WindowManager::onReviewDialogDone(WindowBase* parWindow)
{ {
if (reviewDialog) if (reviewDialog)
removeDialog(reviewDialog); removeDialog(reviewDialog);
@ -963,38 +918,29 @@ void WindowManager::onReviewDialogBack()
setGuiMode(GM_Birth); setGuiMode(GM_Birth);
} }
void WindowManager::onNameDialogActivate() void WindowManager::onReviewActivateDialog(int parDialog)
{
if (reviewDialog)
removeDialog(reviewDialog);
reviewNext = true;
setGuiMode(GM_Name);
}
void WindowManager::onRaceDialogActivate()
{ {
if (reviewDialog) if (reviewDialog)
removeDialog(reviewDialog); removeDialog(reviewDialog);
creationStage = ReviewNext;
reviewNext = true; switch(parDialog)
setGuiMode(GM_Race); {
} case ReviewDialog::NAME_DIALOG:
setGuiMode(GM_Name);
void WindowManager::onClassDialogActivate() break;
{ case ReviewDialog::RACE_DIALOG:
if (reviewDialog) setGuiMode(GM_Race);
removeDialog(reviewDialog); break;
case ReviewDialog::CLASS_DIALOG:
reviewNext = true; setGuiMode(GM_Class);
setGuiMode(GM_Class); break;
case ReviewDialog::BIRTHSIGN_DIALOG:
setGuiMode(GM_Birth);
};
} }
void WindowManager::onBirthSignDialogActivate() ESMS::ESMStore& WindowManager::getStore()
{ {
if (reviewDialog) return environment.mWorld->getStore();
removeDialog(reviewDialog);
reviewNext = true;
setGuiMode(GM_Birth);
} }

@ -44,6 +44,7 @@ namespace OEngine
namespace MWGui namespace MWGui
{ {
class WindowBase;
class HUD; class HUD;
class MapWindow; class MapWindow;
class MainMenu; class MainMenu;
@ -62,6 +63,14 @@ namespace MWGui
class BirthDialog; class BirthDialog;
class ReviewDialog; class ReviewDialog;
struct ClassPoint
{
const char *id;
// Specialization points to match, in order: Stealth, Combat, Magic
// Note: Order is taken from http://www.uesp.net/wiki/Morrowind:Class_Quiz
unsigned int points[3];
};
class WindowManager class WindowManager
{ {
public: public:
@ -92,14 +101,6 @@ namespace MWGui
BirthDialog *birthSignDialog; BirthDialog *birthSignDialog;
ReviewDialog *reviewDialog; ReviewDialog *reviewDialog;
// Which dialogs have been shown, controls back/next/ok buttons
bool nameChosen;
bool raceChosen;
bool classChosen;
bool birthSignChosen;
bool reviewNext;
///< If true then any click on Next will cause the summary to be shown
// Keeps track of current step in Generate Class dialogs // Keeps track of current step in Generate Class dialogs
unsigned generateClassStep; unsigned generateClassStep;
// A counter for each specialization which is increased when an answer is chosen, in order: Stealth, Combat, Magic // A counter for each specialization which is increased when an answer is chosen, in order: Stealth, Combat, Magic
@ -153,10 +154,13 @@ namespace MWGui
void setGuiMode(GuiMode newMode); void setGuiMode(GuiMode newMode);
bool showFPSCounter;
float mFPS;
public: public:
/// The constructor needs the main Gui object /// The constructor needs the main Gui object
WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment, WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment,
const Compiler::Extensions& extensions, bool newGame); const Compiler::Extensions& extensions, bool fpsSwitch, bool newGame);
virtual ~WindowManager(); virtual ~WindowManager();
/** /**
@ -197,10 +201,12 @@ namespace MWGui
MyGUI::Gui* getGui() const { return gui; } MyGUI::Gui* getGui() const { return gui; }
void wmSetFPS(float fps) { mFPS = fps; }
void setValue (const std::string& id, const MWMechanics::Stat<int>& value); void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
///< Set value for the given ID. ///< Set value for the given ID.
void setValue (const std::string& id, const MWMechanics::Stat<float>& value); void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
///< Set value for the given ID. ///< Set value for the given ID.
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value); void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
@ -251,45 +257,57 @@ namespace MWGui
*/ */
const std::string &getGameSettingString(const std::string &id, const std::string &default_); const std::string &getGameSettingString(const std::string &id, const std::string &default_);
ESMS::ESMStore& getStore();
private: private:
void onDialogueWindowBye(); void onDialogueWindowBye();
// Character generation: Name dialog // Character generation: Name dialog
void onNameDialogDone(); void onNameDialogDone(WindowBase* parWindow);
// Character generation: Race dialog // Character generation: Race dialog
void onRaceDialogDone(); void onRaceDialogDone(WindowBase* parWindow);
void onRaceDialogBack(); void onRaceDialogBack();
// Character generation: Choose class process // Character generation: Choose class process
void onClassChoice(MyGUI::Widget* _sender, int _index); void onClassChoice(int _index);
// Character generation: Generate Class // Character generation: Generate Class
void showClassQuestionDialog(); void showClassQuestionDialog();
void onClassQuestionChosen(MyGUI::Widget* _sender, int _index); void onClassQuestionChosen(int _index);
void onGenerateClassBack(); void onGenerateClassBack();
void onGenerateClassDone(); void onGenerateClassDone(WindowBase* parWindow);
// Character generation: Pick Class dialog // Character generation: Pick Class dialog
void onPickClassDialogDone(); void onPickClassDialogDone(WindowBase* parWindow);
void onPickClassDialogBack(); void onPickClassDialogBack();
// Character generation: Create Class dialog // Character generation: Create Class dialog
void onCreateClassDialogDone(); void onCreateClassDialogDone(WindowBase* parWindow);
void onCreateClassDialogBack(); void onCreateClassDialogBack();
// Character generation: Birth sign dialog // Character generation: Birth sign dialog
void onBirthSignDialogDone(); void onBirthSignDialogDone(WindowBase* parWindow);
void onBirthSignDialogBack(); void onBirthSignDialogBack();
// Character generation: Review dialog // Character generation: Review dialog
void onReviewDialogDone(); void onReviewDialogDone(WindowBase* parWindow);
void onReviewDialogBack(); void onReviewDialogBack();
void onNameDialogActivate(); void onReviewActivateDialog(int parDialog);
void onRaceDialogActivate();
void onClassDialogActivate(); enum CreationStageEnum
void onBirthSignDialogActivate(); {
NotStarted,
NameChosen,
RaceChosen,
ClassChosen,
BirthSignChosen,
ReviewNext
};
// Which state the character creating is in, controls back/next/ok buttons
CreationStageEnum creationStage;
}; };
template<typename T> template<typename T>

@ -282,17 +282,6 @@ namespace MWMechanics
"HBar", "MBar", "FBar" "HBar", "MBar", "FBar"
}; };
static const char *skillNames[27] =
{
"SkillBlock", "SkillArmorer", "SkillMediumArmor", "SkillHeavyArmor",
"SkillBluntWeapon", "SkillLongBlade", "SkillAxe", "SkillSpear",
"SkillAthletics", "SkillEnchant", "SkillDestruction", "SkillAlteration",
"SkillIllusion", "SkillConjuration", "SkillMysticism", "SkillRestoration",
"SkillAlchemy", "SkillUnarmored", "SkillSecurity", "SkillSneak",
"SkillAcrobatics", "SkillLightArmor", "SkillShortBlade", "SkillMarksman",
"SkillMercantile", "SkillSpeechcraft", "SkillHandToHand",
};
for (int i=0; i<8; ++i) for (int i=0; i<8; ++i)
{ {
if (stats.mAttributes[i]!=mWatchedCreature.mAttributes[i]) if (stats.mAttributes[i]!=mWatchedCreature.mAttributes[i])
@ -315,16 +304,14 @@ namespace MWMechanics
bool update = false; bool update = false;
for (int i=0; i<27; ++i) //Loop over ESM::Skill::SkillEnum
for(int i = 0; i < 27; ++i)
{ {
if (npcStats.mSkill[i]!=mWatchedNpc.mSkill[i]) if(npcStats.mSkill[i] != mWatchedNpc.mSkill[i])
{ {
update = true; update = true;
mWatchedNpc.mSkill[i] = npcStats.mSkill[i]; mWatchedNpc.mSkill[i] = npcStats.mSkill[i];
mEnvironment.mWindowManager->setValue((ESM::Skill::SkillEnum)i, npcStats.mSkill[i]);
mEnvironment.mWindowManager->setValue (skillNames[i], npcStats.mSkill[i]);
} }
} }

@ -13,7 +13,7 @@ std::string OMW::Path::getPath(PathTypeEnum parType, const std::string parApp, c
if(parType == GLOBAL_CFG_PATH) if(parType == GLOBAL_CFG_PATH)
{ {
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
theBasePath = macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX? theBasePath = Ogre::macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX?
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
theBasePath = "/etc/"+parApp+"/"; theBasePath = "/etc/"+parApp+"/";
#else #else
@ -24,7 +24,7 @@ std::string OMW::Path::getPath(PathTypeEnum parType, const std::string parApp, c
else else
{ {
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
theBasePath = macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX? theBasePath = Ogre::macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX?
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
const char* theDir; const char* theDir;
if ((theDir = getenv("OPENMW_HOME")) != NULL) if ((theDir = getenv("OPENMW_HOME")) != NULL)

@ -4,6 +4,10 @@
#include <OgrePlatform.h> #include <OgrePlatform.h>
#include <string> #include <string>
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <OSX/macUtils.h>
#endif
namespace OMW namespace OMW
{ {
class Path class Path

@ -1,2 +0,0 @@
old
*.d

@ -490,10 +490,6 @@ public:
// Adjust number of record bytes left // Adjust number of record bytes left
mCtx.leftRec -= mCtx.leftSub + 4; mCtx.leftRec -= mCtx.leftSub + 4;
// Check that sizes added up
if(mCtx.leftRec < 0)
fail("Not enough bytes left in record for this subrecord.");
} }
/** Get sub header and check the size /** Get sub header and check the size

@ -259,11 +259,11 @@ namespace ESMS
int getSize() { return count; } int getSize() { return count; }
// List of interior cells. Indexed by cell name. // List of interior cells. Indexed by cell name.
typedef std::map<std::string,Cell*, ciLessBoost> IntCells; typedef std::map<std::string,ESM::Cell*, ciLessBoost> IntCells;
IntCells intCells; IntCells intCells;
// List of exterior cells. Indexed as extCells[gridX][gridY]. // List of exterior cells. Indexed as extCells[gridX][gridY].
typedef std::map<int, Cell*> ExtCellsCol; typedef std::map<int, ESM::Cell*> ExtCellsCol;
typedef std::map<int, ExtCellsCol> ExtCells; typedef std::map<int, ExtCellsCol> ExtCells;
ExtCells extCells; ExtCells extCells;
@ -283,7 +283,7 @@ namespace ESMS
} }
const Cell* findInt(const std::string &id) const const ESM::Cell* findInt(const std::string &id) const
{ {
IntCells::const_iterator it = intCells.find(id); IntCells::const_iterator it = intCells.find(id);
@ -293,7 +293,7 @@ namespace ESMS
return it->second; return it->second;
} }
const Cell *searchExt (int x, int y) const const ESM::Cell *searchExt (int x, int y) const
{ {
ExtCells::const_iterator it = extCells.find (x); ExtCells::const_iterator it = extCells.find (x);
@ -308,7 +308,7 @@ namespace ESMS
return it2->second; return it2->second;
} }
const Cell *searchExtByName (const std::string& id) const const ESM::Cell *searchExtByName (const std::string& id) const
{ {
for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter) for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter)
{ {
@ -323,7 +323,7 @@ namespace ESMS
return 0; return 0;
} }
const Cell *searchExtByRegion (const std::string& id) const const ESM::Cell *searchExtByRegion (const std::string& id) const
{ {
std::string id2 = toLower (id); std::string id2 = toLower (id);
@ -345,13 +345,13 @@ namespace ESMS
count++; count++;
// All cells have a name record, even nameless exterior cells. // All cells have a name record, even nameless exterior cells.
Cell *cell = new Cell; ESM::Cell *cell = new ESM::Cell;
cell->name = id; cell->name = id;
// The cell itself takes care of all the hairy details // The cell itself takes care of all the hairy details
cell->load(esm); cell->load(esm);
if(cell->data.flags & Cell::Interior) if(cell->data.flags & ESM::Cell::Interior)
{ {
// Store interior cell by name // Store interior cell by name
intCells[id] = cell; intCells[id] = cell;

@ -2,32 +2,11 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <string> #include <string>
#include <OgrePrerequisites.h>
bool isFile(const char *name) bool isFile(const char *name)
{ {
boost::filesystem::path cfg_file_path(name); boost::filesystem::path cfg_file_path(name);
return boost::filesystem::exists(cfg_file_path); return boost::filesystem::exists(cfg_file_path);
} }
#ifdef __MACOSX__
#include <CoreFoundation/CoreFoundation.h>
std::string macBundlePath()
{
char path[1024];
CFBundleRef mainBundle = CFBundleGetMainBundle();
assert(mainBundle);
CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
assert(mainBundleURL);
CFStringRef cfStringRef = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
assert(cfStringRef);
CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);
CFRelease(mainBundleURL);
CFRelease(cfStringRef);
return std::string(path);
}
#endif

@ -28,7 +28,6 @@
#include <stdio.h> #include <stdio.h>
#include <libs/mangle/vfs/servers/ogre_vfs.hpp> #include <libs/mangle/vfs/servers/ogre_vfs.hpp>
#include "../../apps/openmw/mwclass/npc.hpp"
#include "../nif/nif_file.hpp" #include "../nif/nif_file.hpp"
#include "../nif/node.hpp" #include "../nif/node.hpp"
#include "../nif/data.hpp" #include "../nif/data.hpp"
@ -476,8 +475,6 @@ static void vectorMul(const Matrix &A, float *C)
void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bounds) void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bounds)
{ {
//if( MWClass::Npc.isChest)
//cout << "t:" << shape << "\n";
assert(shape != NULL); assert(shape != NULL);
// Interpret flags // Interpret flags
@ -643,8 +640,13 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
for (std::vector<NiSkinData::BoneInfo>::iterator it = boneList.begin(); for (std::vector<NiSkinData::BoneInfo>::iterator it = boneList.begin();
it != boneList.end(); it++) it != boneList.end(); it++)
{ {
if(mSkel.isNull())
{
std::cout << "No skeleton for :" << shape->skin->bones[boneIndex].name.toString() << std::endl;
break;
}
//get the bone from bones array of skindata //get the bone from bones array of skindata
bonePtr = skel->getBone(shape->skin->bones[boneIndex].name.toString()); bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name.toString());
// final_vector = old_vector + old_rotation*new_vector*old_scale // final_vector = old_vector + old_rotation*new_vector*old_scale
vecPos = bonePtr->_getDerivedPosition() + vecPos = bonePtr->_getDerivedPosition() +
@ -767,7 +769,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
//FIXME: "Bip01" isn't every time the root bone //FIXME: "Bip01" isn't every time the root bone
if (node->name == "Bip01" || node->name == "Root Bone") //root node, create a skeleton if (node->name == "Bip01" || node->name == "Root Bone") //root node, create a skeleton
{ {
skel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true); mSkel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true);
/*if (node->extra->recType == RC_NiTextKeyExtraData ) /*if (node->extra->recType == RC_NiTextKeyExtraData )
{ {
@ -776,16 +778,16 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
}*/ }*/
} }
if (!skel.isNull()) //if there is a skeleton if (!mSkel.isNull()) //if there is a skeleton
{ {
std::string name = node->name.toString(); std::string name = node->name.toString();
//if (isBeast && isChest) //if (isBeast && isChest)
// std::cout << "NAME: " << name << "\n"; // std::cout << "NAME: " << name << "\n";
// Quick-n-dirty workaround for the fact that several // Quick-n-dirty workaround for the fact that several
// bones may have the same name. // bones may have the same name.
if(!skel->hasBone(name)) if(!mSkel->hasBone(name))
{ {
bone = skel->createBone(name); bone = mSkel->createBone(name);
if (parentBone) if (parentBone)
parentBone->addChild(bone); parentBone->addChild(bone);
@ -1011,13 +1013,12 @@ void NIFLoader::loadResource(Resource *resource)
//if(split== "Skins.NIF") //if(split== "Skins.NIF")
// std::cout << "\nSPECIAL PROPS\n"; // std::cout << "\nSPECIAL PROPS\n";
resourceName = ""; resourceName = "";
MeshManager *m = MeshManager::getSingletonPtr();
// Check if the resource already exists // Check if the resource already exists
//MeshPtr ptr = m->load(name, "custom"); //MeshPtr ptr = m->load(name, "custom");
//cout << "THISNAME: " << ptr->getName() << "\n"; //cout << "THISNAME: " << ptr->getName() << "\n";
//cout << "RESOURCE:"<< resource->getName(); //cout << "RESOURCE:"<< resource->getName();
mesh = 0; mesh = 0;
skel.setNull(); mSkel.setNull();
// Set up the VFS if it hasn't been done already // Set up the VFS if it hasn't been done already
if (!vfs) vfs = new OgreVFS(resourceGroup); if (!vfs) vfs = new OgreVFS(resourceGroup);

@ -135,7 +135,7 @@ class NIFLoader : Ogre::ManualResourceLoader
// pointer to the ogre mesh which is currently build // pointer to the ogre mesh which is currently build
Ogre::Mesh *mesh; Ogre::Mesh *mesh;
Ogre::SkeletonPtr skel; Ogre::SkeletonPtr mSkel;
}; };
#endif #endif

@ -321,7 +321,7 @@ namespace Caelum
getGregorianDateTimeFromJulianDay(julianDay, year, month, day, hour, minute, second); getGregorianDateTimeFromJulianDay(julianDay, year, month, day, hour, minute, second);
} }
#if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) && (OGRE_COMPILER == OGRE_COMPILER_MSVC) #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) && (OGRE_COMPILER == OGRE_COMPILER_MSVC) && (OGRE_ARCH_TYPE != OGRE_ARCHITECTURE_64)
int Astronomy::enterHighPrecissionFloatingPointMode () int Astronomy::enterHighPrecissionFloatingPointMode ()
{ {
int oldMode = ::_controlfp (0, 0); int oldMode = ::_controlfp (0, 0);

@ -25,7 +25,10 @@ if (MYGUI_USE_FREETYPE)
) )
endif() endif()
target_link_libraries(${PROJECT_NAME} ${CMAKE_DL_LIBS} uuid) # We don't need this lib in OS X. uuid functions is in libc here.
if (NOT APPLE)
target_link_libraries(${PROJECT_NAME} ${CMAKE_DL_LIBS} uuid)
endif(NOT APPLE)
if (MINGW) if (MINGW)
target_link_libraries(${PROJECT_NAME} libwinmm.a) target_link_libraries(${PROJECT_NAME} libwinmm.a)

@ -62,7 +62,11 @@ namespace MyGUI
if (dwProcessID != ::GetCurrentProcessId()) if (dwProcessID != ::GetCurrentProcessId())
return TRUE; return TRUE;
#ifdef _M_X64
if (::GetWindowLongPtr(hWnd, GWLP_HINSTANCE) == lParam)
#else
if (::GetWindowLong(hWnd, GWL_HINSTANCE) == lParam) if (::GetWindowLong(hWnd, GWL_HINSTANCE) == lParam)
#endif
{ {
// Нашли. hWnd - то что надо // Нашли. hWnd - то что надо
g_hWnd = hWnd; g_hWnd = hWnd;

@ -48,5 +48,13 @@
<Widget type="StaticImage" skin="StaticImage" position="0 0 32 <Widget type="StaticImage" skin="StaticImage" position="0 0 32
32" align="Center Center" name="Crosshair"/> 32" align="Center Center" name="Crosshair"/>
<!-- FPSCounter box -->
<Widget type="Widget" skin="HUD_Box" position="12 12 28 21" align="Left Top"
name="FPSBox">
<Widget type="StaticText" skin="NumFPS" position="3 3 21 17" name="FPSCounter"/>
</Widget>
</Widget> </Widget>
</MyGUI> </MyGUI>

@ -9,6 +9,14 @@
<BasisSkin type="SimpleText" offset = "0 0 16 16" align = "ALIGN_STRETCH"/> <BasisSkin type="SimpleText" offset = "0 0 16 16" align = "ALIGN_STRETCH"/>
</Skin> </Skin>
<Skin name = "NumFPS" size = "16 16">
<Property key="FontName" value = "MyGUI_CoreFont.18" />
<Property key="FontHeight" value = "18" />
<Property key="AlignText" value = "ALIGN_HCENTER ALIGN_BOTTOM" />
<Property key="Colour" value = "1 1 1" />
<BasisSkin type="SimpleText" offset = "0 0 16 16" align = "ALIGN_STRETCH"/>
</Skin>
<Skin name = "SandText" size = "16 16"> <Skin name = "SandText" size = "16 16">
<Property key="FontName" value = "MyGUI_CoreFont.18" /> <Property key="FontName" value = "MyGUI_CoreFont.18" />
<Property key="FontHeight" value = "18" /> <Property key="FontHeight" value = "18" />

@ -19,7 +19,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0.07</string> <string>0.10</string>
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>
<true/> <true/>
<key>LSRequiresCarbon</key> <key>LSRequiresCarbon</key>

@ -0,0 +1,12 @@
# Defines plugins to load
# Define plugin folder
PluginFolder=${OGRE_PLUGIN_DIR}
# Define plugins
Plugin=RenderSystem_GL.dylib
Plugin=Plugin_ParticleFX.dylib
Plugin=Plugin_OctreeSceneManager.dylib
# Plugin=Plugin_CgProgramManager
Loading…
Cancel
Save