Merge branch 'master' into potions

Conflicts:
	apps/openmw/mwclass/npc.cpp
	apps/openmw/mwclass/npc.hpp
This commit is contained in:
Marc Zinnschlag 2012-07-17 10:32:18 +02:00
commit 2c70a93553
184 changed files with 4738 additions and 7054 deletions

1
.gitignore vendored
View file

@ -13,3 +13,4 @@ cmake_install.cmake
Makefile Makefile
makefile makefile
data data
*.kdev4

View file

@ -20,6 +20,14 @@ set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
# Debug suffix for plugins
set(DEBUG_SUFFIX "")
if (DEFINED CMAKE_BUILD_TYPE)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(DEBUG_SUFFIX "_d")
endif()
endif()
# doxygen main page # doxygen main page
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp") configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
@ -93,9 +101,8 @@ ENDIF()
set(LIBDIR ${CMAKE_SOURCE_DIR}/libs) set(LIBDIR ${CMAKE_SOURCE_DIR}/libs)
set(MANGLE_VFS ${LIBDIR}/mangle/vfs/servers/ogre_vfs.cpp)
set(MANGLE_INPUT ${LIBDIR}/mangle/input/servers/ois_driver.cpp) set(MANGLE_INPUT ${LIBDIR}/mangle/input/servers/ois_driver.cpp)
set(MANGLE_ALL ${MANGLE_VFS} ${MANGLE_INPUT}) set(MANGLE_ALL ${MANGLE_INPUT})
source_group(libs\\mangle FILES ${MANGLE_ALL}) source_group(libs\\mangle FILES ${MANGLE_ALL})
set(OENGINE_OGRE set(OENGINE_OGRE

View file

@ -39,7 +39,7 @@ add_openmw_dir (mwscript
locals scriptmanager compilercontext interpretercontext cellextensions miscextensions locals scriptmanager compilercontext interpretercontext cellextensions miscextensions
guiextensions soundextensions skyextensions statsextensions containerextensions guiextensions soundextensions skyextensions statsextensions containerextensions
aiextensions controlextensions extensions globalscripts ref dialogueextensions aiextensions controlextensions extensions globalscripts ref dialogueextensions
animationextensions animationextensions transformationextensions
) )
add_openmw_dir (mwsound add_openmw_dir (mwsound
@ -79,7 +79,6 @@ ENDIF(WIN32)
ENDIF(OGRE_STATIC) ENDIF(OGRE_STATIC)
add_executable(openmw add_executable(openmw
${OPENMW_LIBS} ${OPENMW_LIBS_HEADER} ${OPENMW_LIBS} ${OPENMW_LIBS_HEADER}
${COMPONENT_FILES}
${OPENMW_FILES} ${OPENMW_FILES}
${GAME} ${GAME_HEADER} ${GAME} ${GAME_HEADER}
${APPLE_BUNDLE_RESOURCES} ${APPLE_BUNDLE_RESOURCES}

View file

@ -1,25 +1,13 @@
#include "engine.hpp" #include "engine.hpp"
#include "components/esm/loadcell.hpp" #include "components/esm/loadcell.hpp"
#include <cassert>
#include <iostream>
#include <utility>
#include <OgreRoot.h> #include <OgreRoot.h>
#include <OgreRenderWindow.h> #include <OgreRenderWindow.h>
#include <MyGUI_WidgetManager.h> #include <MyGUI_WidgetManager.h>
#include <openengine/ogre/renderer.hpp>
#include <openengine/gui/manager.hpp>
#include <components/esm/records.hpp>
#include <components/bsa/bsa_archive.hpp> #include <components/bsa/bsa_archive.hpp>
#include <components/esm/esm_reader.hpp>
#include <components/files/fixedpath.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include <components/settings/settings.hpp>
#include <components/nifoverrides/nifoverrides.hpp> #include <components/nifoverrides/nifoverrides.hpp>
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bullet_nif_loader.hpp>
@ -31,16 +19,12 @@
#include "mwgui/cursorreplace.hpp" #include "mwgui/cursorreplace.hpp"
#include "mwscript/scriptmanager.hpp" #include "mwscript/scriptmanager.hpp"
#include "mwscript/compilercontext.hpp"
#include "mwscript/interpretercontext.hpp"
#include "mwscript/extensions.hpp" #include "mwscript/extensions.hpp"
#include "mwscript/globalscripts.hpp"
#include "mwsound/soundmanager.hpp" #include "mwsound/soundmanager.hpp"
#include "mwworld/class.hpp" #include "mwworld/class.hpp"
#include "mwworld/player.hpp" #include "mwworld/player.hpp"
#include "mwworld/cellstore.hpp"
#include "mwworld/worldimp.hpp" #include "mwworld/worldimp.hpp"
#include "mwclass/classes.hpp" #include "mwclass/classes.hpp"
@ -50,9 +34,6 @@
#include "mwmechanics/mechanicsmanager.hpp" #include "mwmechanics/mechanicsmanager.hpp"
#include "mwbase/environment.hpp"
#include "mwbase/world.hpp"
void OMW::Engine::executeLocalScripts() void OMW::Engine::executeLocalScripts()
{ {

View file

@ -1,10 +1,6 @@
#ifndef ENGINE_H #ifndef ENGINE_H
#define ENGINE_H #define ENGINE_H
#include <string>
#include <boost/filesystem.hpp>
#include <OgreFrameListener.h> #include <OgreFrameListener.h>
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>

View file

@ -1,13 +1,5 @@
#include <iostream> #include <iostream>
#include <string>
#include <fstream>
#include <boost/program_options.hpp>
#include <components/files/fileops.hpp>
#include <components/files/fixedpath.hpp>
#include <components/files/collections.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include "engine.hpp" #include "engine.hpp"
@ -16,15 +8,10 @@
#include <boost/iostreams/concepts.hpp> #include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/stream_buffer.hpp> #include <boost/iostreams/stream_buffer.hpp>
# if !defined(_DEBUG)
# include <iostream>
# include <fstream>
# endif
// For OutputDebugString // For OutputDebugString
#include <Windows.h> #include <Windows.h>
// makes __argc and __argv available on windows // makes __argc and __argv available on windows
#include <stdlib.h> #include <cstdlib>
#endif #endif
@ -52,8 +39,6 @@ inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string
} /* namespace boost */ } /* namespace boost */
#endif /* (BOOST_VERSION <= 104600) */ #endif /* (BOOST_VERSION <= 104600) */
using namespace std;
struct FallbackMap { struct FallbackMap {
std::map<std::string,std::string> mMap; std::map<std::string,std::string> mMap;
}; };

View file

@ -1,8 +1,6 @@
#ifndef GAME_MWBASE_WORLD_H #ifndef GAME_MWBASE_WORLD_H
#define GAME_MWBASE_WORLD_H #define GAME_MWBASE_WORLD_H
#include <string>
#include <map>
#include <vector> #include <vector>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -178,6 +176,10 @@ namespace MWBase
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z) = 0;
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
const = 0; const = 0;
///< Convert cell numbers to position. ///< Convert cell numbers to position.

View file

@ -1,7 +1,6 @@
#ifndef GAME_MWCLASS_CREATURE_H #ifndef GAME_MWCLASS_CREATURE_H
#define GAME_MWCLASS_CREATURE_H #define GAME_MWCLASS_CREATURE_H
#include "../mwworld/class.hpp"
#include "../mwrender/renderinginterface.hpp" #include "../mwrender/renderinginterface.hpp"
#include "../mwrender/actors.hpp" #include "../mwrender/actors.hpp"

View file

@ -9,7 +9,7 @@ namespace MWClass
{ {
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;

View file

@ -125,10 +125,14 @@ namespace MWClass
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
assert (ref->base != NULL); assert (ref->base != NULL);
std::string headID = ref->base->head; std::string headID = ref->base->head;
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
@ -136,7 +140,8 @@ namespace MWClass
std::string smodel = "meshes\\base_anim.nif"; std::string smodel = "meshes\\base_anim.nif";
if(beast) if(beast)
smodel = "meshes\\base_animkna.nif"; smodel = "meshes\\base_animkna.nif";
physics.insertActorPhysics(ptr, smodel); physics.insertActorPhysics(ptr, smodel);
MWBase::Environment::get().getMechanicsManager()->addActor (ptr); MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
} }
@ -365,4 +370,10 @@ namespace MWClass
stats.useSkill (skill, *class_, usageType); stats.useSkill (skill, *class_, usageType);
} }
void Npc::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const
{
y = 0;
x = 0;
}
} }

View file

@ -48,7 +48,7 @@ namespace MWClass
virtual std::string getScript (const MWWorld::Ptr& ptr) const; virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr ///< Return name of the script attached to ptr
virtual void setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const; virtual void setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const;
///< Force or unforce a stance. ///< Force or unforce a stance.
virtual void setStance (const MWWorld::Ptr& ptr, Stance stance, bool set) const; virtual void setStance (const MWWorld::Ptr& ptr, Stance stance, bool set) const;
@ -85,6 +85,8 @@ namespace MWClass
virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const; virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const;
///< Inform actor \a ptr that a skill use has succeeded. ///< Inform actor \a ptr that a skill use has succeeded.
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
static void registerSelf(); static void registerSelf();
}; };
} }

View file

@ -9,7 +9,7 @@ namespace MWClass
{ {
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;

View file

@ -9,7 +9,7 @@ namespace MWClass
{ {
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;

View file

@ -591,7 +591,7 @@ namespace MWDialogue
mIsInChoice = false; mIsInChoice = false;
mCompilerContext.setExtensions (&extensions); mCompilerContext.setExtensions (&extensions);
mDialogueMap.clear(); mDialogueMap.clear();
actorKnownTopics.clear(); mActorKnownTopics.clear();
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list; ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{ {
@ -601,24 +601,24 @@ namespace MWDialogue
void DialogueManager::addTopic(std::string topic) void DialogueManager::addTopic(std::string topic)
{ {
knownTopics[toLower(topic)] = true; mKnownTopics[toLower(topic)] = true;
} }
void DialogueManager::parseText(std::string text) void DialogueManager::parseText(std::string text)
{ {
std::list<std::string>::iterator it; std::list<std::string>::iterator it;
for(it = actorKnownTopics.begin();it != actorKnownTopics.end();++it) for(it = mActorKnownTopics.begin();it != mActorKnownTopics.end();++it)
{ {
size_t pos = find_str_ci(text,*it,0); size_t pos = find_str_ci(text,*it,0);
if(pos !=std::string::npos) if(pos !=std::string::npos)
{ {
if(pos==0) if(pos==0)
{ {
knownTopics[*it] = true; mKnownTopics[*it] = true;
} }
else if(text.substr(pos -1,1) == " ") else if(text.substr(pos -1,1) == " ")
{ {
knownTopics[*it] = true; mKnownTopics[*it] = true;
} }
} }
} }
@ -632,7 +632,7 @@ namespace MWDialogue
mActor = actor; mActor = actor;
actorKnownTopics.clear(); mActorKnownTopics.clear();
//initialise the GUI //initialise the GUI
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue); MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue);
@ -742,7 +742,7 @@ namespace MWDialogue
std::list<std::string> keywordList; std::list<std::string> keywordList;
int choice = mChoice; int choice = mChoice;
mChoice = -1; mChoice = -1;
actorKnownTopics.clear(); mActorKnownTopics.clear();
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list; ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
@ -755,9 +755,9 @@ namespace MWDialogue
{ {
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
{ {
actorKnownTopics.push_back(toLower(it->first)); mActorKnownTopics.push_back(toLower(it->first));
//does the player know the topic? //does the player know the topic?
if(knownTopics.find(toLower(it->first)) != knownTopics.end()) if(mKnownTopics.find(toLower(it->first)) != mKnownTopics.end())
{ {
keywordList.push_back(it->first); keywordList.push_back(it->first);
break; break;

View file

@ -26,8 +26,8 @@ namespace MWDialogue
void updateTopics(); void updateTopics();
std::map<std::string,ESM::Dialogue> mDialogueMap; std::map<std::string,ESM::Dialogue> mDialogueMap;
std::map<std::string,bool> knownTopics;// Those are the topics the player knows. std::map<std::string,bool> mKnownTopics;// Those are the topics the player knows.
std::list<std::string> actorKnownTopics; std::list<std::string> mActorKnownTopics;
MWScript::CompilerContext mCompilerContext; MWScript::CompilerContext mCompilerContext;
std::ostream mErrorStream; std::ostream mErrorStream;

View file

@ -15,15 +15,15 @@ BirthDialog::BirthDialog(WindowManager& parWindowManager)
// Centre dialog // Centre dialog
center(); center();
getWidget(spellArea, "SpellArea"); getWidget(mSpellArea, "SpellArea");
getWidget(birthImage, "BirthsignImage"); getWidget(mBirthImage, "BirthsignImage");
getWidget(birthList, "BirthsignList"); getWidget(mBirthList, "BirthsignList");
birthList->setScrollVisible(true); mBirthList->setScrollVisible(true);
birthList->eventListSelectAccept += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); mBirthList->eventListSelectAccept += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
birthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); mBirthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
birthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); mBirthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
MyGUI::ButtonPtr backButton; MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
@ -68,14 +68,14 @@ void BirthDialog::open()
void BirthDialog::setBirthId(const std::string &birthId) void BirthDialog::setBirthId(const std::string &birthId)
{ {
currentBirthId = birthId; mCurrentBirthId = birthId;
birthList->setIndexSelected(MyGUI::ITEM_NONE); mBirthList->setIndexSelected(MyGUI::ITEM_NONE);
size_t count = birthList->getItemCount(); size_t count = mBirthList->getItemCount();
for (size_t i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
if (boost::iequals(*birthList->getItemDataAt<std::string>(i), birthId)) if (boost::iequals(*mBirthList->getItemDataAt<std::string>(i), birthId))
{ {
birthList->setIndexSelected(i); mBirthList->setIndexSelected(i);
break; break;
} }
} }
@ -100,11 +100,11 @@ void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index)
if (_index == MyGUI::ITEM_NONE) if (_index == MyGUI::ITEM_NONE)
return; return;
const std::string *birthId = birthList->getItemDataAt<std::string>(_index); const std::string *birthId = mBirthList->getItemDataAt<std::string>(_index);
if (boost::iequals(currentBirthId, *birthId)) if (boost::iequals(mCurrentBirthId, *birthId))
return; return;
currentBirthId = *birthId; mCurrentBirthId = *birthId;
updateSpells(); updateSpells();
} }
@ -112,7 +112,7 @@ void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index)
void BirthDialog::updateBirths() void BirthDialog::updateBirths()
{ {
birthList->removeAllItems(); mBirthList->removeAllItems();
const ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
@ -122,34 +122,34 @@ void BirthDialog::updateBirths()
for (; it != end; ++it) for (; it != end; ++it)
{ {
const ESM::BirthSign &birth = it->second; const ESM::BirthSign &birth = it->second;
birthList->addItem(birth.name, it->first); mBirthList->addItem(birth.name, it->first);
if (boost::iequals(it->first, currentBirthId)) if (boost::iequals(it->first, mCurrentBirthId))
birthList->setIndexSelected(index); mBirthList->setIndexSelected(index);
++index; ++index;
} }
} }
void BirthDialog::updateSpells() void BirthDialog::updateSpells()
{ {
for (std::vector<MyGUI::WidgetPtr>::iterator it = spellItems.begin(); it != spellItems.end(); ++it) for (std::vector<MyGUI::WidgetPtr>::iterator it = mSpellItems.begin(); it != mSpellItems.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }
spellItems.clear(); mSpellItems.clear();
if (currentBirthId.empty()) if (mCurrentBirthId.empty())
return; return;
MWSpellPtr spellWidget; MWSpellPtr spellWidget;
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, spellArea->getWidth(), 18); MyGUI::IntCoord coord(0, 0, mSpellArea->getWidth(), 18);
const ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::BirthSign *birth = store.birthSigns.find(currentBirthId); const ESM::BirthSign *birth = store.birthSigns.find(mCurrentBirthId);
std::string texturePath = std::string("textures\\") + birth->texture; std::string texturePath = std::string("textures\\") + birth->texture;
fixTexturePath(texturePath); fixTexturePath(texturePath);
birthImage->setImageTexture(texturePath); mBirthImage->setImageTexture(texturePath);
std::vector<std::string> abilities, powers, spells; std::vector<std::string> abilities, powers, spells;
@ -183,25 +183,25 @@ void BirthDialog::updateSpells()
{ {
if (!categories[category].spells.empty()) if (!categories[category].spells.empty())
{ {
MyGUI::TextBox* label = spellArea->createWidget<MyGUI::TextBox>("SandBrightText", coord, MyGUI::Align::Default, std::string("Label")); MyGUI::TextBox* label = mSpellArea->createWidget<MyGUI::TextBox>("SandBrightText", coord, MyGUI::Align::Default, std::string("Label"));
label->setCaption(mWindowManager.getGameSettingString(categories[category].label, "")); label->setCaption(mWindowManager.getGameSettingString(categories[category].label, ""));
spellItems.push_back(label); mSpellItems.push_back(label);
coord.top += lineHeight; coord.top += lineHeight;
std::vector<std::string>::const_iterator end = categories[category].spells.end(); std::vector<std::string>::const_iterator end = categories[category].spells.end();
for (std::vector<std::string>::const_iterator it = categories[category].spells.begin(); it != end; ++it) for (std::vector<std::string>::const_iterator it = categories[category].spells.begin(); it != end; ++it)
{ {
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 = mSpellArea->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + boost::lexical_cast<std::string>(i));
spellWidget->setWindowManager(&mWindowManager); spellWidget->setWindowManager(&mWindowManager);
spellWidget->setSpellId(spellId); spellWidget->setSpellId(spellId);
spellItems.push_back(spellWidget); mSpellItems.push_back(spellWidget);
coord.top += lineHeight; coord.top += lineHeight;
MyGUI::IntCoord spellCoord = coord; MyGUI::IntCoord spellCoord = coord;
spellCoord.height = 24; // TODO: This should be fetched from the skin somehow, or perhaps a widget in the layout as a template? spellCoord.height = 24; // TODO: This should be fetched from the skin somehow, or perhaps a widget in the layout as a template?
spellWidget->createEffectWidgets(spellItems, spellArea, spellCoord, (category == 0) ? MWEffectList::EF_Constant : 0); spellWidget->createEffectWidgets(mSpellItems, mSpellArea, spellCoord, (category == 0) ? MWEffectList::EF_Constant : 0);
coord.top = spellCoord.top; coord.top = spellCoord.top;
++i; ++i;

View file

@ -25,7 +25,7 @@ namespace MWGui
GM_Female GM_Female
}; };
const std::string &getBirthId() const { return currentBirthId; } const std::string &getBirthId() const { return mCurrentBirthId; }
void setBirthId(const std::string &raceId); void setBirthId(const std::string &raceId);
void setNextButtonShow(bool shown); void setNextButtonShow(bool shown);
@ -49,12 +49,12 @@ namespace MWGui
void updateBirths(); void updateBirths();
void updateSpells(); void updateSpells();
MyGUI::ListBox* birthList; MyGUI::ListBox* mBirthList;
MyGUI::WidgetPtr spellArea; MyGUI::WidgetPtr mSpellArea;
MyGUI::ImageBox* birthImage; MyGUI::ImageBox* mBirthImage;
std::vector<MyGUI::WidgetPtr> spellItems; std::vector<MyGUI::WidgetPtr> mSpellItems;
std::string currentBirthId; std::string mCurrentBirthId;
}; };
} }
#endif #endif

View file

@ -1,6 +1,5 @@
#include "class.hpp" #include "class.hpp"
#include <assert.h>
#include <iterator> #include <iterator>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
@ -26,8 +25,8 @@ GenerateClassResultDialog::GenerateClassResultDialog(WindowManager& parWindowMan
setText("ReflectT", mWindowManager.getGameSettingString("sMessageQuestionAnswer1", "")); setText("ReflectT", mWindowManager.getGameSettingString("sMessageQuestionAnswer1", ""));
getWidget(classImage, "ClassImage"); getWidget(mClassImage, "ClassImage");
getWidget(className, "ClassName"); getWidget(mClassName, "ClassName");
MyGUI::ButtonPtr backButton; MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
@ -51,15 +50,15 @@ void GenerateClassResultDialog::open()
std::string GenerateClassResultDialog::getClassId() const std::string GenerateClassResultDialog::getClassId() const
{ {
return className->getCaption(); return mClassName->getCaption();
} }
void GenerateClassResultDialog::setClassId(const std::string &classId) void GenerateClassResultDialog::setClassId(const std::string &classId)
{ {
currentClassId = classId; mCurrentClassId = classId;
classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds"); mClassImage->setImageTexture(std::string("textures\\levelup\\") + mCurrentClassId + ".dds");
const ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
className->setCaption(store.classes.find(currentClassId)->name); mClassName->setCaption(store.classes.find(mCurrentClassId)->name);
} }
// widget controls // widget controls
@ -82,29 +81,29 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager)
// Centre dialog // Centre dialog
center(); center();
getWidget(specializationName, "SpecializationName"); getWidget(mSpecializationName, "SpecializationName");
getWidget(favoriteAttribute[0], "FavoriteAttribute0"); getWidget(mFavoriteAttribute[0], "FavoriteAttribute0");
getWidget(favoriteAttribute[1], "FavoriteAttribute1"); getWidget(mFavoriteAttribute[1], "FavoriteAttribute1");
favoriteAttribute[0]->setWindowManager(&mWindowManager); mFavoriteAttribute[0]->setWindowManager(&mWindowManager);
favoriteAttribute[1]->setWindowManager(&mWindowManager); mFavoriteAttribute[1]->setWindowManager(&mWindowManager);
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(mMajorSkill[i], std::string("MajorSkill").append(1, theIndex));
getWidget(minorSkill[i], std::string("MinorSkill").append(1, theIndex)); getWidget(mMinorSkill[i], std::string("MinorSkill").append(1, theIndex));
majorSkill[i]->setWindowManager(&mWindowManager); mMajorSkill[i]->setWindowManager(&mWindowManager);
minorSkill[i]->setWindowManager(&mWindowManager); mMinorSkill[i]->setWindowManager(&mWindowManager);
} }
getWidget(classList, "ClassList"); getWidget(mClassList, "ClassList");
classList->setScrollVisible(true); mClassList->setScrollVisible(true);
classList->eventListSelectAccept += MyGUI::newDelegate(this, &PickClassDialog::onSelectClass); mClassList->eventListSelectAccept += MyGUI::newDelegate(this, &PickClassDialog::onSelectClass);
classList->eventListMouseItemActivate += MyGUI::newDelegate(this, &PickClassDialog::onSelectClass); mClassList->eventListMouseItemActivate += MyGUI::newDelegate(this, &PickClassDialog::onSelectClass);
classList->eventListChangePosition += MyGUI::newDelegate(this, &PickClassDialog::onSelectClass); mClassList->eventListChangePosition += MyGUI::newDelegate(this, &PickClassDialog::onSelectClass);
getWidget(classImage, "ClassImage"); getWidget(mClassImage, "ClassImage");
MyGUI::ButtonPtr backButton; MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
@ -148,14 +147,14 @@ void PickClassDialog::open()
void PickClassDialog::setClassId(const std::string &classId) void PickClassDialog::setClassId(const std::string &classId)
{ {
currentClassId = classId; mCurrentClassId = classId;
classList->setIndexSelected(MyGUI::ITEM_NONE); mClassList->setIndexSelected(MyGUI::ITEM_NONE);
size_t count = classList->getItemCount(); size_t count = mClassList->getItemCount();
for (size_t i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
if (boost::iequals(*classList->getItemDataAt<std::string>(i), classId)) if (boost::iequals(*mClassList->getItemDataAt<std::string>(i), classId))
{ {
classList->setIndexSelected(i); mClassList->setIndexSelected(i);
break; break;
} }
} }
@ -180,11 +179,11 @@ void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index)
if (_index == MyGUI::ITEM_NONE) if (_index == MyGUI::ITEM_NONE)
return; return;
const std::string *classId = classList->getItemDataAt<std::string>(_index); const std::string *classId = mClassList->getItemDataAt<std::string>(_index);
if (boost::iequals(currentClassId, *classId)) if (boost::iequals(mCurrentClassId, *classId))
return; return;
currentClassId = *classId; mCurrentClassId = *classId;
updateStats(); updateStats();
} }
@ -192,7 +191,7 @@ void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index)
void PickClassDialog::updateClasses() void PickClassDialog::updateClasses()
{ {
classList->removeAllItems(); mClassList->removeAllItems();
const ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
@ -207,19 +206,19 @@ void PickClassDialog::updateClasses()
continue; continue;
const std::string &id = it->first; const std::string &id = it->first;
classList->addItem(klass.name, id); mClassList->addItem(klass.name, id);
if (boost::iequals(id, currentClassId)) if (boost::iequals(id, mCurrentClassId))
classList->setIndexSelected(index); mClassList->setIndexSelected(index);
++index; ++index;
} }
} }
void PickClassDialog::updateStats() void PickClassDialog::updateStats()
{ {
if (currentClassId.empty()) if (mCurrentClassId.empty())
return; return;
const ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::Class *klass = store.classes.search(currentClassId); const ESM::Class *klass = store.classes.search(mCurrentClassId);
if (!klass) if (!klass)
return; return;
@ -231,23 +230,23 @@ void PickClassDialog::updateStats()
"sSpecializationStealth" "sSpecializationStealth"
}; };
std::string specName = mWindowManager.getGameSettingString(specIds[specialization], specIds[specialization]); std::string specName = mWindowManager.getGameSettingString(specIds[specialization], specIds[specialization]);
specializationName->setCaption(specName); mSpecializationName->setCaption(specName);
ToolTips::createSpecializationToolTip(specializationName, specName, specialization); ToolTips::createSpecializationToolTip(mSpecializationName, specName, specialization);
favoriteAttribute[0]->setAttributeId(klass->data.attribute[0]); mFavoriteAttribute[0]->setAttributeId(klass->data.attribute[0]);
favoriteAttribute[1]->setAttributeId(klass->data.attribute[1]); mFavoriteAttribute[1]->setAttributeId(klass->data.attribute[1]);
ToolTips::createAttributeToolTip(favoriteAttribute[0], favoriteAttribute[0]->getAttributeId()); ToolTips::createAttributeToolTip(mFavoriteAttribute[0], mFavoriteAttribute[0]->getAttributeId());
ToolTips::createAttributeToolTip(favoriteAttribute[1], favoriteAttribute[1]->getAttributeId()); ToolTips::createAttributeToolTip(mFavoriteAttribute[1], mFavoriteAttribute[1]->getAttributeId());
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
minorSkill[i]->setSkillNumber(klass->data.skills[i][0]); mMinorSkill[i]->setSkillNumber(klass->data.skills[i][0]);
majorSkill[i]->setSkillNumber(klass->data.skills[i][1]); mMajorSkill[i]->setSkillNumber(klass->data.skills[i][1]);
ToolTips::createSkillToolTip(minorSkill[i], klass->data.skills[i][0]); ToolTips::createSkillToolTip(mMinorSkill[i], klass->data.skills[i][0]);
ToolTips::createSkillToolTip(majorSkill[i], klass->data.skills[i][1]); ToolTips::createSkillToolTip(mMajorSkill[i], klass->data.skills[i][1]);
} }
classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds"); mClassImage->setImageTexture(std::string("textures\\levelup\\") + mCurrentClassId + ".dds");
} }
/* InfoBoxDialog */ /* InfoBoxDialog */
@ -284,59 +283,59 @@ void InfoBoxDialog::layoutVertically(MyGUI::WidgetPtr widget, int margin)
InfoBoxDialog::InfoBoxDialog(WindowManager& parWindowManager) InfoBoxDialog::InfoBoxDialog(WindowManager& parWindowManager)
: WindowBase("openmw_infobox.layout", parWindowManager) : WindowBase("openmw_infobox.layout", parWindowManager)
, currentButton(-1) , mCurrentButton(-1)
{ {
getWidget(textBox, "TextBox"); getWidget(mTextBox, "TextBox");
getWidget(text, "Text"); getWidget(mText, "Text");
text->getSubWidgetText()->setWordWrap(true); mText->getSubWidgetText()->setWordWrap(true);
getWidget(buttonBar, "ButtonBar"); getWidget(mButtonBar, "ButtonBar");
center(); center();
} }
void InfoBoxDialog::setText(const std::string &str) void InfoBoxDialog::setText(const std::string &str)
{ {
text->setCaption(str); mText->setCaption(str);
textBox->setVisible(!str.empty()); mTextBox->setVisible(!str.empty());
fitToText(text); fitToText(mText);
} }
std::string InfoBoxDialog::getText() const std::string InfoBoxDialog::getText() const
{ {
return text->getCaption(); return mText->getCaption();
} }
void InfoBoxDialog::setButtons(ButtonList &buttons) void InfoBoxDialog::setButtons(ButtonList &buttons)
{ {
for (std::vector<MyGUI::ButtonPtr>::iterator it = this->buttons.begin(); it != this->buttons.end(); ++it) for (std::vector<MyGUI::ButtonPtr>::iterator it = this->mButtons.begin(); it != this->mButtons.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }
this->buttons.clear(); this->mButtons.clear();
currentButton = -1; mCurrentButton = -1;
// TODO: The buttons should be generated from a template in the layout file, ie. cloning an existing widget // TODO: The buttons should be generated from a template in the layout file, ie. cloning an existing widget
MyGUI::ButtonPtr button; MyGUI::ButtonPtr button;
MyGUI::IntCoord coord = MyGUI::IntCoord(0, 0, buttonBar->getWidth(), 10); MyGUI::IntCoord coord = MyGUI::IntCoord(0, 0, mButtonBar->getWidth(), 10);
ButtonList::const_iterator end = buttons.end(); ButtonList::const_iterator end = buttons.end();
for (ButtonList::const_iterator it = buttons.begin(); it != end; ++it) for (ButtonList::const_iterator it = buttons.begin(); it != end; ++it)
{ {
const std::string &text = *it; const std::string &text = *it;
button = buttonBar->createWidget<MyGUI::Button>("MW_Button", coord, MyGUI::Align::Top | MyGUI::Align::HCenter, ""); button = mButtonBar->createWidget<MyGUI::Button>("MW_Button", coord, MyGUI::Align::Top | MyGUI::Align::HCenter, "");
button->getSubWidgetText()->setWordWrap(true); button->getSubWidgetText()->setWordWrap(true);
button->setCaption(text); button->setCaption(text);
fitToText(button); fitToText(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &InfoBoxDialog::onButtonClicked); button->eventMouseButtonClick += MyGUI::newDelegate(this, &InfoBoxDialog::onButtonClicked);
coord.top += button->getHeight(); coord.top += button->getHeight();
this->buttons.push_back(button); this->mButtons.push_back(button);
} }
} }
void InfoBoxDialog::open() void InfoBoxDialog::open()
{ {
// Fix layout // Fix layout
layoutVertically(textBox, 4); layoutVertically(mTextBox, 4);
layoutVertically(buttonBar, 6); layoutVertically(mButtonBar, 6);
layoutVertically(mMainWidget, 4 + 6); layoutVertically(mMainWidget, 4 + 6);
center(); center();
@ -345,18 +344,18 @@ void InfoBoxDialog::open()
int InfoBoxDialog::getChosenButton() const int InfoBoxDialog::getChosenButton() const
{ {
return currentButton; return mCurrentButton;
} }
void InfoBoxDialog::onButtonClicked(MyGUI::WidgetPtr _sender) void InfoBoxDialog::onButtonClicked(MyGUI::WidgetPtr _sender)
{ {
std::vector<MyGUI::ButtonPtr>::const_iterator end = buttons.end(); std::vector<MyGUI::ButtonPtr>::const_iterator end = mButtons.end();
int i = 0; int i = 0;
for (std::vector<MyGUI::ButtonPtr>::const_iterator it = buttons.begin(); it != end; ++it) for (std::vector<MyGUI::ButtonPtr>::const_iterator it = mButtons.begin(); it != end; ++it)
{ {
if (*it == _sender) if (*it == _sender)
{ {
currentButton = i; mCurrentButton = i;
eventButtonSelected(i); eventButtonSelected(i);
return; return;
} }
@ -382,49 +381,49 @@ ClassChoiceDialog::ClassChoiceDialog(WindowManager& parWindowManager)
CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_create_class.layout", parWindowManager) : WindowBase("openmw_chargen_create_class.layout", parWindowManager)
, specDialog(nullptr) , mSpecDialog(nullptr)
, attribDialog(nullptr) , mAttribDialog(nullptr)
, skillDialog(nullptr) , mSkillDialog(nullptr)
, descDialog(nullptr) , mDescDialog(nullptr)
{ {
// Centre dialog // Centre dialog
center(); center();
setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization")); setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization"));
getWidget(specializationName, "SpecializationName"); getWidget(mSpecializationName, "SpecializationName");
specializationName->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); mSpecializationName->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked);
setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:"));
getWidget(favoriteAttribute0, "FavoriteAttribute0"); getWidget(mFavoriteAttribute0, "FavoriteAttribute0");
getWidget(favoriteAttribute1, "FavoriteAttribute1"); getWidget(mFavoriteAttribute1, "FavoriteAttribute1");
favoriteAttribute0->setWindowManager(&mWindowManager); mFavoriteAttribute0->setWindowManager(&mWindowManager);
favoriteAttribute1->setWindowManager(&mWindowManager); mFavoriteAttribute1->setWindowManager(&mWindowManager);
favoriteAttribute0->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); mFavoriteAttribute0->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked);
favoriteAttribute1->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); mFavoriteAttribute1->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked);
setText("MajorSkillT", mWindowManager.getGameSettingString("sSkillClassMajor", "")); setText("MajorSkillT", mWindowManager.getGameSettingString("sSkillClassMajor", ""));
setText("MinorSkillT", mWindowManager.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;
getWidget(majorSkill[i], std::string("MajorSkill").append(1, theIndex)); getWidget(mMajorSkill[i], std::string("MajorSkill").append(1, theIndex));
getWidget(minorSkill[i], std::string("MinorSkill").append(1, theIndex)); getWidget(mMinorSkill[i], std::string("MinorSkill").append(1, theIndex));
skills.push_back(majorSkill[i]); mSkills.push_back(mMajorSkill[i]);
skills.push_back(minorSkill[i]); mSkills.push_back(mMinorSkill[i]);
} }
std::vector<Widgets::MWSkillPtr>::const_iterator end = skills.end(); std::vector<Widgets::MWSkillPtr>::const_iterator end = mSkills.end();
for (std::vector<Widgets::MWSkillPtr>::const_iterator it = skills.begin(); it != end; ++it) for (std::vector<Widgets::MWSkillPtr>::const_iterator it = mSkills.begin(); it != end; ++it)
{ {
(*it)->setWindowManager(&mWindowManager); (*it)->setWindowManager(&mWindowManager);
(*it)->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onSkillClicked); (*it)->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onSkillClicked);
} }
setText("LabelT", mWindowManager.getGameSettingString("sName", "")); setText("LabelT", mWindowManager.getGameSettingString("sName", ""));
getWidget(editName, "EditName"); getWidget(mEditName, "EditName");
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(editName); MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName);
MyGUI::ButtonPtr descriptionButton; MyGUI::ButtonPtr descriptionButton;
getWidget(descriptionButton, "DescriptionButton"); getWidget(descriptionButton, "DescriptionButton");
@ -441,20 +440,20 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
// Set default skills, attributes // Set default skills, attributes
favoriteAttribute0->setAttributeId(ESM::Attribute::Strength); mFavoriteAttribute0->setAttributeId(ESM::Attribute::Strength);
favoriteAttribute1->setAttributeId(ESM::Attribute::Agility); mFavoriteAttribute1->setAttributeId(ESM::Attribute::Agility);
majorSkill[0]->setSkillId(ESM::Skill::Block); mMajorSkill[0]->setSkillId(ESM::Skill::Block);
majorSkill[1]->setSkillId(ESM::Skill::Armorer); mMajorSkill[1]->setSkillId(ESM::Skill::Armorer);
majorSkill[2]->setSkillId(ESM::Skill::MediumArmor); mMajorSkill[2]->setSkillId(ESM::Skill::MediumArmor);
majorSkill[3]->setSkillId(ESM::Skill::HeavyArmor); mMajorSkill[3]->setSkillId(ESM::Skill::HeavyArmor);
majorSkill[4]->setSkillId(ESM::Skill::BluntWeapon); mMajorSkill[4]->setSkillId(ESM::Skill::BluntWeapon);
minorSkill[0]->setSkillId(ESM::Skill::LongBlade); mMinorSkill[0]->setSkillId(ESM::Skill::LongBlade);
minorSkill[1]->setSkillId(ESM::Skill::Axe); mMinorSkill[1]->setSkillId(ESM::Skill::Axe);
minorSkill[2]->setSkillId(ESM::Skill::Spear); mMinorSkill[2]->setSkillId(ESM::Skill::Spear);
minorSkill[3]->setSkillId(ESM::Skill::Athletics); mMinorSkill[3]->setSkillId(ESM::Skill::Athletics);
minorSkill[4]->setSkillId(ESM::Skill::Enchant); mMinorSkill[4]->setSkillId(ESM::Skill::Enchant);
setSpecialization(0); setSpecialization(0);
update(); update();
@ -462,44 +461,44 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
CreateClassDialog::~CreateClassDialog() CreateClassDialog::~CreateClassDialog()
{ {
delete specDialog; delete mSpecDialog;
delete attribDialog; delete mAttribDialog;
delete skillDialog; delete mSkillDialog;
delete descDialog; delete mDescDialog;
} }
void CreateClassDialog::update() void CreateClassDialog::update()
{ {
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
ToolTips::createSkillToolTip(majorSkill[i], majorSkill[i]->getSkillId()); ToolTips::createSkillToolTip(mMajorSkill[i], mMajorSkill[i]->getSkillId());
ToolTips::createSkillToolTip(minorSkill[i], minorSkill[i]->getSkillId()); ToolTips::createSkillToolTip(mMinorSkill[i], mMinorSkill[i]->getSkillId());
} }
ToolTips::createAttributeToolTip(favoriteAttribute0, favoriteAttribute0->getAttributeId()); ToolTips::createAttributeToolTip(mFavoriteAttribute0, mFavoriteAttribute0->getAttributeId());
ToolTips::createAttributeToolTip(favoriteAttribute1, favoriteAttribute1->getAttributeId()); ToolTips::createAttributeToolTip(mFavoriteAttribute1, mFavoriteAttribute1->getAttributeId());
} }
std::string CreateClassDialog::getName() const std::string CreateClassDialog::getName() const
{ {
return editName->getOnlyText(); return mEditName->getOnlyText();
} }
std::string CreateClassDialog::getDescription() const std::string CreateClassDialog::getDescription() const
{ {
return description; return mDescription;
} }
ESM::Class::Specialization CreateClassDialog::getSpecializationId() const ESM::Class::Specialization CreateClassDialog::getSpecializationId() const
{ {
return specializationId; return mSpecializationId;
} }
std::vector<int> CreateClassDialog::getFavoriteAttributes() const std::vector<int> CreateClassDialog::getFavoriteAttributes() const
{ {
std::vector<int> v; std::vector<int> v;
v.push_back(favoriteAttribute0->getAttributeId()); v.push_back(mFavoriteAttribute0->getAttributeId());
v.push_back(favoriteAttribute1->getAttributeId()); v.push_back(mFavoriteAttribute1->getAttributeId());
return v; return v;
} }
@ -508,7 +507,7 @@ std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMajorSkills() const
std::vector<ESM::Skill::SkillEnum> v; std::vector<ESM::Skill::SkillEnum> v;
for(int i = 0; i < 5; i++) for(int i = 0; i < 5; i++)
{ {
v.push_back(majorSkill[i]->getSkillId()); v.push_back(mMajorSkill[i]->getSkillId());
} }
return v; return v;
} }
@ -518,7 +517,7 @@ std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMinorSkills() const
std::vector<ESM::Skill::SkillEnum> v; std::vector<ESM::Skill::SkillEnum> v;
for(int i=0; i < 5; i++) for(int i=0; i < 5; i++)
{ {
v.push_back(minorSkill[i]->getSkillId()); v.push_back(mMinorSkill[i]->getSkillId());
} }
return v; return v;
} }
@ -557,108 +556,108 @@ void CreateClassDialog::open()
void CreateClassDialog::onDialogCancel() void CreateClassDialog::onDialogCancel()
{ {
if (specDialog) if (mSpecDialog)
{ {
mWindowManager.removeDialog(specDialog); mWindowManager.removeDialog(mSpecDialog);
specDialog = 0; mSpecDialog = 0;
} }
if (attribDialog) if (mAttribDialog)
{ {
mWindowManager.removeDialog(attribDialog); mWindowManager.removeDialog(mAttribDialog);
attribDialog = 0; mAttribDialog = 0;
} }
if (skillDialog) if (mSkillDialog)
{ {
mWindowManager.removeDialog(skillDialog); mWindowManager.removeDialog(mSkillDialog);
skillDialog = 0; mSkillDialog = 0;
} }
if (descDialog) if (mDescDialog)
{ {
mWindowManager.removeDialog(descDialog); mWindowManager.removeDialog(mDescDialog);
descDialog = 0; mDescDialog = 0;
} }
} }
void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender)
{ {
delete specDialog; delete mSpecDialog;
specDialog = new SelectSpecializationDialog(mWindowManager); mSpecDialog = new SelectSpecializationDialog(mWindowManager);
specDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); mSpecDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
specDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected); mSpecDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected);
specDialog->setVisible(true); mSpecDialog->setVisible(true);
} }
void CreateClassDialog::onSpecializationSelected() void CreateClassDialog::onSpecializationSelected()
{ {
specializationId = specDialog->getSpecializationId(); mSpecializationId = mSpecDialog->getSpecializationId();
setSpecialization(specializationId); setSpecialization(mSpecializationId);
mWindowManager.removeDialog(specDialog); mWindowManager.removeDialog(mSpecDialog);
specDialog = 0; mSpecDialog = 0;
} }
void CreateClassDialog::setSpecialization(int id) void CreateClassDialog::setSpecialization(int id)
{ {
specializationId = (ESM::Class::Specialization) id; mSpecializationId = (ESM::Class::Specialization) id;
static const char *specIds[3] = { static const char *specIds[3] = {
"sSpecializationCombat", "sSpecializationCombat",
"sSpecializationMagic", "sSpecializationMagic",
"sSpecializationStealth" "sSpecializationStealth"
}; };
std::string specName = mWindowManager.getGameSettingString(specIds[specializationId], specIds[specializationId]); std::string specName = mWindowManager.getGameSettingString(specIds[mSpecializationId], specIds[mSpecializationId]);
specializationName->setCaption(specName); mSpecializationName->setCaption(specName);
ToolTips::createSpecializationToolTip(specializationName, specName, specializationId); ToolTips::createSpecializationToolTip(mSpecializationName, specName, mSpecializationId);
} }
void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender) void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
{ {
delete attribDialog; delete mAttribDialog;
attribDialog = new SelectAttributeDialog(mWindowManager); mAttribDialog = new SelectAttributeDialog(mWindowManager);
attribDialog->setAffectedWidget(_sender); mAttribDialog->setAffectedWidget(_sender);
attribDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); mAttribDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
attribDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected); mAttribDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected);
attribDialog->setVisible(true); mAttribDialog->setVisible(true);
} }
void CreateClassDialog::onAttributeSelected() void CreateClassDialog::onAttributeSelected()
{ {
ESM::Attribute::AttributeID id = attribDialog->getAttributeId(); ESM::Attribute::AttributeID id = mAttribDialog->getAttributeId();
Widgets::MWAttributePtr attribute = attribDialog->getAffectedWidget(); Widgets::MWAttributePtr attribute = mAttribDialog->getAffectedWidget();
if (attribute == favoriteAttribute0) if (attribute == mFavoriteAttribute0)
{ {
if (favoriteAttribute1->getAttributeId() == id) if (mFavoriteAttribute1->getAttributeId() == id)
favoriteAttribute1->setAttributeId(favoriteAttribute0->getAttributeId()); mFavoriteAttribute1->setAttributeId(mFavoriteAttribute0->getAttributeId());
} }
else if (attribute == favoriteAttribute1) else if (attribute == mFavoriteAttribute1)
{ {
if (favoriteAttribute0->getAttributeId() == id) if (mFavoriteAttribute0->getAttributeId() == id)
favoriteAttribute0->setAttributeId(favoriteAttribute1->getAttributeId()); mFavoriteAttribute0->setAttributeId(mFavoriteAttribute1->getAttributeId());
} }
attribute->setAttributeId(id); attribute->setAttributeId(id);
mWindowManager.removeDialog(attribDialog); mWindowManager.removeDialog(mAttribDialog);
attribDialog = 0; mAttribDialog = 0;
update(); update();
} }
void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender) void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
{ {
delete skillDialog; delete mSkillDialog;
skillDialog = new SelectSkillDialog(mWindowManager); mSkillDialog = new SelectSkillDialog(mWindowManager);
skillDialog->setAffectedWidget(_sender); mSkillDialog->setAffectedWidget(_sender);
skillDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); mSkillDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
skillDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected); mSkillDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected);
skillDialog->setVisible(true); mSkillDialog->setVisible(true);
} }
void CreateClassDialog::onSkillSelected() void CreateClassDialog::onSkillSelected()
{ {
ESM::Skill::SkillEnum id = skillDialog->getSkillId(); ESM::Skill::SkillEnum id = mSkillDialog->getSkillId();
Widgets::MWSkillPtr skill = skillDialog->getAffectedWidget(); Widgets::MWSkillPtr skill = mSkillDialog->getAffectedWidget();
// Avoid duplicate skills by swapping any skill field that matches the selected one // Avoid duplicate skills by swapping any skill field that matches the selected one
std::vector<Widgets::MWSkillPtr>::const_iterator end = skills.end(); std::vector<Widgets::MWSkillPtr>::const_iterator end = mSkills.end();
for (std::vector<Widgets::MWSkillPtr>::const_iterator it = skills.begin(); it != end; ++it) for (std::vector<Widgets::MWSkillPtr>::const_iterator it = mSkills.begin(); it != end; ++it)
{ {
if (*it == skill) if (*it == skill)
continue; continue;
@ -669,25 +668,25 @@ void CreateClassDialog::onSkillSelected()
} }
} }
skill->setSkillId(skillDialog->getSkillId()); skill->setSkillId(mSkillDialog->getSkillId());
mWindowManager.removeDialog(skillDialog); mWindowManager.removeDialog(mSkillDialog);
skillDialog = 0; mSkillDialog = 0;
update(); update();
} }
void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender) void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender)
{ {
descDialog = new DescriptionDialog(mWindowManager); mDescDialog = new DescriptionDialog(mWindowManager);
descDialog->setTextInput(description); mDescDialog->setTextInput(mDescription);
descDialog->eventDone += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionEntered); mDescDialog->eventDone += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionEntered);
descDialog->setVisible(true); mDescDialog->setVisible(true);
} }
void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow) void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow)
{ {
description = descDialog->getTextInput(); mDescription = mDescDialog->getTextInput();
mWindowManager.removeDialog(descDialog); mWindowManager.removeDialog(mDescDialog);
descDialog = 0; mDescDialog = 0;
} }
void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender) void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender)
@ -710,24 +709,24 @@ SelectSpecializationDialog::SelectSpecializationDialog(WindowManager& parWindowM
setText("LabelT", mWindowManager.getGameSettingString("sSpecializationMenu1", "")); setText("LabelT", mWindowManager.getGameSettingString("sSpecializationMenu1", ""));
getWidget(specialization0, "Specialization0"); getWidget(mSpecialization0, "Specialization0");
getWidget(specialization1, "Specialization1"); getWidget(mSpecialization1, "Specialization1");
getWidget(specialization2, "Specialization2"); getWidget(mSpecialization2, "Specialization2");
std::string combat = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], ""); std::string combat = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "");
std::string magic = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], ""); std::string magic = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], "");
std::string stealth = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], ""); std::string stealth = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], "");
specialization0->setCaption(combat); mSpecialization0->setCaption(combat);
specialization0->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); mSpecialization0->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked);
specialization1->setCaption(magic); mSpecialization1->setCaption(magic);
specialization1->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); mSpecialization1->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked);
specialization2->setCaption(stealth); mSpecialization2->setCaption(stealth);
specialization2->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); mSpecialization2->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked);
specializationId = ESM::Class::Combat; mSpecializationId = ESM::Class::Combat;
ToolTips::createSpecializationToolTip(specialization0, combat, ESM::Class::Combat); ToolTips::createSpecializationToolTip(mSpecialization0, combat, ESM::Class::Combat);
ToolTips::createSpecializationToolTip(specialization1, magic, ESM::Class::Magic); ToolTips::createSpecializationToolTip(mSpecialization1, magic, ESM::Class::Magic);
ToolTips::createSpecializationToolTip(specialization2, stealth, ESM::Class::Stealth); ToolTips::createSpecializationToolTip(mSpecialization2, stealth, ESM::Class::Stealth);
MyGUI::ButtonPtr cancelButton; MyGUI::ButtonPtr cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
@ -748,12 +747,12 @@ SelectSpecializationDialog::~SelectSpecializationDialog()
void SelectSpecializationDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) void SelectSpecializationDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender)
{ {
if (_sender == specialization0) if (_sender == mSpecialization0)
specializationId = ESM::Class::Combat; mSpecializationId = ESM::Class::Combat;
else if (_sender == specialization1) else if (_sender == mSpecialization1)
specializationId = ESM::Class::Magic; mSpecializationId = ESM::Class::Magic;
else if (_sender == specialization2) else if (_sender == mSpecialization2)
specializationId = ESM::Class::Stealth; mSpecializationId = ESM::Class::Stealth;
else else
return; return;
@ -807,7 +806,7 @@ SelectAttributeDialog::~SelectAttributeDialog()
void SelectAttributeDialog::onAttributeClicked(Widgets::MWAttributePtr _sender) void SelectAttributeDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
{ {
// TODO: Change MWAttribute to set and get AttributeID enum instead of int // TODO: Change MWAttribute to set and get AttributeID enum instead of int
attributeId = static_cast<ESM::Attribute::AttributeID>(_sender->getAttributeId()); mAttributeId = static_cast<ESM::Attribute::AttributeID>(_sender->getAttributeId());
eventItemSelected(); eventItemSelected();
} }
@ -833,44 +832,44 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager)
for(int i = 0; i < 9; i++) for(int i = 0; i < 9; i++)
{ {
char theIndex = '0'+i; char theIndex = '0'+i;
getWidget(combatSkill[i], std::string("CombatSkill").append(1, theIndex)); getWidget(mCombatSkill[i], std::string("CombatSkill").append(1, theIndex));
getWidget(magicSkill[i], std::string("MagicSkill").append(1, theIndex)); getWidget(mMagicSkill[i], std::string("MagicSkill").append(1, theIndex));
getWidget(stealthSkill[i], std::string("StealthSkill").append(1, theIndex)); getWidget(mStealthSkill[i], std::string("StealthSkill").append(1, theIndex));
} }
struct {Widgets::MWSkillPtr widget; ESM::Skill::SkillEnum skillId;} skills[3][9] = { struct {Widgets::MWSkillPtr widget; ESM::Skill::SkillEnum skillId;} mSkills[3][9] = {
{ {
{combatSkill[0], ESM::Skill::Block}, {mCombatSkill[0], ESM::Skill::Block},
{combatSkill[1], ESM::Skill::Armorer}, {mCombatSkill[1], ESM::Skill::Armorer},
{combatSkill[2], ESM::Skill::MediumArmor}, {mCombatSkill[2], ESM::Skill::MediumArmor},
{combatSkill[3], ESM::Skill::HeavyArmor}, {mCombatSkill[3], ESM::Skill::HeavyArmor},
{combatSkill[4], ESM::Skill::BluntWeapon}, {mCombatSkill[4], ESM::Skill::BluntWeapon},
{combatSkill[5], ESM::Skill::LongBlade}, {mCombatSkill[5], ESM::Skill::LongBlade},
{combatSkill[6], ESM::Skill::Axe}, {mCombatSkill[6], ESM::Skill::Axe},
{combatSkill[7], ESM::Skill::Spear}, {mCombatSkill[7], ESM::Skill::Spear},
{combatSkill[8], ESM::Skill::Athletics} {mCombatSkill[8], ESM::Skill::Athletics}
}, },
{ {
{magicSkill[0], ESM::Skill::Enchant}, {mMagicSkill[0], ESM::Skill::Enchant},
{magicSkill[1], ESM::Skill::Destruction}, {mMagicSkill[1], ESM::Skill::Destruction},
{magicSkill[2], ESM::Skill::Alteration}, {mMagicSkill[2], ESM::Skill::Alteration},
{magicSkill[3], ESM::Skill::Illusion}, {mMagicSkill[3], ESM::Skill::Illusion},
{magicSkill[4], ESM::Skill::Conjuration}, {mMagicSkill[4], ESM::Skill::Conjuration},
{magicSkill[5], ESM::Skill::Mysticism}, {mMagicSkill[5], ESM::Skill::Mysticism},
{magicSkill[6], ESM::Skill::Restoration}, {mMagicSkill[6], ESM::Skill::Restoration},
{magicSkill[7], ESM::Skill::Alchemy}, {mMagicSkill[7], ESM::Skill::Alchemy},
{magicSkill[8], ESM::Skill::Unarmored} {mMagicSkill[8], ESM::Skill::Unarmored}
}, },
{ {
{stealthSkill[0], ESM::Skill::Security}, {mStealthSkill[0], ESM::Skill::Security},
{stealthSkill[1], ESM::Skill::Sneak}, {mStealthSkill[1], ESM::Skill::Sneak},
{stealthSkill[2], ESM::Skill::Acrobatics}, {mStealthSkill[2], ESM::Skill::Acrobatics},
{stealthSkill[3], ESM::Skill::LightArmor}, {mStealthSkill[3], ESM::Skill::LightArmor},
{stealthSkill[4], ESM::Skill::ShortBlade}, {mStealthSkill[4], ESM::Skill::ShortBlade},
{stealthSkill[5] ,ESM::Skill::Marksman}, {mStealthSkill[5] ,ESM::Skill::Marksman},
{stealthSkill[6] ,ESM::Skill::Mercantile}, {mStealthSkill[6] ,ESM::Skill::Mercantile},
{stealthSkill[7] ,ESM::Skill::Speechcraft}, {mStealthSkill[7] ,ESM::Skill::Speechcraft},
{stealthSkill[8] ,ESM::Skill::HandToHand} {mStealthSkill[8] ,ESM::Skill::HandToHand}
} }
}; };
@ -878,10 +877,10 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager)
{ {
for (int i = 0; i < 9; ++i) for (int i = 0; i < 9; ++i)
{ {
skills[spec][i].widget->setWindowManager(&mWindowManager); mSkills[spec][i].widget->setWindowManager(&mWindowManager);
skills[spec][i].widget->setSkillId(skills[spec][i].skillId); mSkills[spec][i].widget->setSkillId(mSkills[spec][i].skillId);
skills[spec][i].widget->eventClicked += MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked); mSkills[spec][i].widget->eventClicked += MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked);
ToolTips::createSkillToolTip(skills[spec][i].widget, skills[spec][i].widget->getSkillId()); ToolTips::createSkillToolTip(mSkills[spec][i].widget, mSkills[spec][i].widget->getSkillId());
} }
} }
@ -904,7 +903,7 @@ SelectSkillDialog::~SelectSkillDialog()
void SelectSkillDialog::onSkillClicked(Widgets::MWSkillPtr _sender) void SelectSkillDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
{ {
skillId = _sender->getSkillId(); mSkillId = _sender->getSkillId();
eventItemSelected(); eventItemSelected();
} }
@ -921,7 +920,7 @@ DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager)
// Centre dialog // Centre dialog
center(); center();
getWidget(textEdit, "TextEdit"); getWidget(mTextEdit, "TextEdit");
MyGUI::ButtonPtr okButton; MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
@ -931,7 +930,7 @@ DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager)
okButton->setCoord(234 - buttonWidth, 214, buttonWidth, 24); okButton->setCoord(234 - buttonWidth, 214, buttonWidth, 24);
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
} }

View file

@ -45,11 +45,11 @@ namespace MWGui
void fitToText(MyGUI::TextBox* widget); void fitToText(MyGUI::TextBox* widget);
void layoutVertically(MyGUI::WidgetPtr widget, int margin); void layoutVertically(MyGUI::WidgetPtr widget, int margin);
int currentButton; int mCurrentButton;
MyGUI::WidgetPtr textBox; MyGUI::WidgetPtr mTextBox;
MyGUI::TextBox* text; MyGUI::TextBox* mText;
MyGUI::WidgetPtr buttonBar; MyGUI::WidgetPtr mButtonBar;
std::vector<MyGUI::ButtonPtr> buttons; std::vector<MyGUI::ButtonPtr> mButtons;
}; };
// Lets the player choose between 3 ways of creating a class // Lets the player choose between 3 ways of creating a class
@ -90,10 +90,10 @@ namespace MWGui
void onBackClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender);
private: private:
MyGUI::ImageBox* classImage; MyGUI::ImageBox* mClassImage;
MyGUI::TextBox* className; MyGUI::TextBox* mClassName;
std::string currentClassId; std::string mCurrentClassId;
}; };
class PickClassDialog : public WindowBase class PickClassDialog : public WindowBase
@ -101,7 +101,7 @@ namespace MWGui
public: public:
PickClassDialog(WindowManager& parWindowManager); PickClassDialog(WindowManager& parWindowManager);
const std::string &getClassId() const { return currentClassId; } const std::string &getClassId() const { return mCurrentClassId; }
void setClassId(const std::string &classId); void setClassId(const std::string &classId);
void setNextButtonShow(bool shown); void setNextButtonShow(bool shown);
@ -125,14 +125,14 @@ namespace MWGui
void updateClasses(); void updateClasses();
void updateStats(); void updateStats();
MyGUI::ImageBox* classImage; MyGUI::ImageBox* mClassImage;
MyGUI::ListBox* classList; MyGUI::ListBox* mClassList;
MyGUI::TextBox* specializationName; MyGUI::TextBox* mSpecializationName;
Widgets::MWAttributePtr favoriteAttribute[2]; Widgets::MWAttributePtr mFavoriteAttribute[2];
Widgets::MWSkillPtr majorSkill[5]; Widgets::MWSkillPtr mMajorSkill[5];
Widgets::MWSkillPtr minorSkill[5]; Widgets::MWSkillPtr mMinorSkill[5];
std::string currentClassId; std::string mCurrentClassId;
}; };
class SelectSpecializationDialog : public WindowBase class SelectSpecializationDialog : public WindowBase
@ -141,7 +141,7 @@ namespace MWGui
SelectSpecializationDialog(WindowManager& parWindowManager); SelectSpecializationDialog(WindowManager& parWindowManager);
~SelectSpecializationDialog(); ~SelectSpecializationDialog();
ESM::Class::Specialization getSpecializationId() const { return specializationId; } ESM::Class::Specialization getSpecializationId() const { return mSpecializationId; }
// Events // Events
typedef delegates::CMultiDelegate0 EventHandle_Void; typedef delegates::CMultiDelegate0 EventHandle_Void;
@ -161,9 +161,9 @@ namespace MWGui
void onCancelClicked(MyGUI::Widget* _sender); void onCancelClicked(MyGUI::Widget* _sender);
private: private:
MyGUI::TextBox *specialization0, *specialization1, *specialization2; MyGUI::TextBox *mSpecialization0, *mSpecialization1, *mSpecialization2;
ESM::Class::Specialization specializationId; ESM::Class::Specialization mSpecializationId;
}; };
class SelectAttributeDialog : public WindowBase class SelectAttributeDialog : public WindowBase
@ -172,9 +172,9 @@ namespace MWGui
SelectAttributeDialog(WindowManager& parWindowManager); SelectAttributeDialog(WindowManager& parWindowManager);
~SelectAttributeDialog(); ~SelectAttributeDialog();
ESM::Attribute::AttributeID getAttributeId() const { return attributeId; } ESM::Attribute::AttributeID getAttributeId() const { return mAttributeId; }
Widgets::MWAttributePtr getAffectedWidget() const { return affectedWidget; } Widgets::MWAttributePtr getAffectedWidget() const { return mAffectedWidget; }
void setAffectedWidget(Widgets::MWAttributePtr widget) { affectedWidget = widget; } void setAffectedWidget(Widgets::MWAttributePtr widget) { mAffectedWidget = widget; }
// Events // Events
typedef delegates::CMultiDelegate0 EventHandle_Void; typedef delegates::CMultiDelegate0 EventHandle_Void;
@ -194,9 +194,9 @@ namespace MWGui
void onCancelClicked(MyGUI::Widget* _sender); void onCancelClicked(MyGUI::Widget* _sender);
private: private:
Widgets::MWAttributePtr affectedWidget; Widgets::MWAttributePtr mAffectedWidget;
ESM::Attribute::AttributeID attributeId; ESM::Attribute::AttributeID mAttributeId;
}; };
class SelectSkillDialog : public WindowBase class SelectSkillDialog : public WindowBase
@ -205,9 +205,9 @@ namespace MWGui
SelectSkillDialog(WindowManager& parWindowManager); SelectSkillDialog(WindowManager& parWindowManager);
~SelectSkillDialog(); ~SelectSkillDialog();
ESM::Skill::SkillEnum getSkillId() const { return skillId; } ESM::Skill::SkillEnum getSkillId() const { return mSkillId; }
Widgets::MWSkillPtr getAffectedWidget() const { return affectedWidget; } Widgets::MWSkillPtr getAffectedWidget() const { return mAffectedWidget; }
void setAffectedWidget(Widgets::MWSkillPtr widget) { affectedWidget = widget; } void setAffectedWidget(Widgets::MWSkillPtr widget) { mAffectedWidget = widget; }
// Events // Events
typedef delegates::CMultiDelegate0 EventHandle_Void; typedef delegates::CMultiDelegate0 EventHandle_Void;
@ -227,12 +227,12 @@ namespace MWGui
void onCancelClicked(MyGUI::Widget* _sender); void onCancelClicked(MyGUI::Widget* _sender);
private: private:
Widgets::MWSkillPtr combatSkill[9]; Widgets::MWSkillPtr mCombatSkill[9];
Widgets::MWSkillPtr magicSkill[9]; Widgets::MWSkillPtr mMagicSkill[9];
Widgets::MWSkillPtr stealthSkill[9]; Widgets::MWSkillPtr mStealthSkill[9];
Widgets::MWSkillPtr affectedWidget; Widgets::MWSkillPtr mAffectedWidget;
ESM::Skill::SkillEnum skillId; ESM::Skill::SkillEnum mSkillId;
}; };
class DescriptionDialog : public WindowBase class DescriptionDialog : public WindowBase
@ -241,14 +241,14 @@ namespace MWGui
DescriptionDialog(WindowManager& parWindowManager); DescriptionDialog(WindowManager& parWindowManager);
~DescriptionDialog(); ~DescriptionDialog();
std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; } std::string getTextInput() const { return mTextEdit ? mTextEdit->getOnlyText() : ""; }
void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); } void setTextInput(const std::string &text) { if (mTextEdit) mTextEdit->setOnlyText(text); }
protected: protected:
void onOkClicked(MyGUI::Widget* _sender); void onOkClicked(MyGUI::Widget* _sender);
private: private:
MyGUI::EditPtr textEdit; MyGUI::EditPtr mTextEdit;
}; };
class CreateClassDialog : public WindowBase class CreateClassDialog : public WindowBase
@ -294,20 +294,20 @@ namespace MWGui
void update(); void update();
private: private:
MyGUI::EditPtr editName; MyGUI::EditPtr mEditName;
MyGUI::TextBox* specializationName; MyGUI::TextBox* mSpecializationName;
Widgets::MWAttributePtr favoriteAttribute0, favoriteAttribute1; Widgets::MWAttributePtr mFavoriteAttribute0, mFavoriteAttribute1;
Widgets::MWSkillPtr majorSkill[5]; Widgets::MWSkillPtr mMajorSkill[5];
Widgets::MWSkillPtr minorSkill[5]; Widgets::MWSkillPtr mMinorSkill[5];
std::vector<Widgets::MWSkillPtr> skills; std::vector<Widgets::MWSkillPtr> mSkills;
std::string description; std::string mDescription;
SelectSpecializationDialog *specDialog; SelectSpecializationDialog *mSpecDialog;
SelectAttributeDialog *attribDialog; SelectAttributeDialog *mAttribDialog;
SelectSkillDialog *skillDialog; SelectSkillDialog *mSkillDialog;
DescriptionDialog *descDialog; DescriptionDialog *mDescDialog;
ESM::Class::Specialization specializationId; ESM::Class::Specialization mSpecializationId;
}; };
} }
#endif #endif

View file

@ -1,6 +1,5 @@
#include "dialogue.hpp" #include "dialogue.hpp"
#include <assert.h>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
@ -51,9 +50,9 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
center(); center();
//History view //History view
getWidget(history, "History"); getWidget(mHistory, "History");
history->setOverflowToTheLeft(true); mHistory->setOverflowToTheLeft(true);
history->setMaxTextLength(1000000); mHistory->setMaxTextLength(1000000);
Widget* eventbox; Widget* eventbox;
//An EditBox cannot receive mouse click events, so we use an //An EditBox cannot receive mouse click events, so we use an
@ -63,36 +62,36 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
eventbox->eventMouseWheel += MyGUI::newDelegate(this, &DialogueWindow::onMouseWheel); eventbox->eventMouseWheel += MyGUI::newDelegate(this, &DialogueWindow::onMouseWheel);
//Topics list //Topics list
getWidget(topicsList, "TopicsList"); getWidget(mTopicsList, "TopicsList");
topicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
MyGUI::ButtonPtr byeButton; MyGUI::ButtonPtr byeButton;
getWidget(byeButton, "ByeButton"); getWidget(byeButton, "ByeButton");
byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
getWidget(pDispositionBar, "Disposition"); getWidget(mDispositionBar, "Disposition");
getWidget(pDispositionText,"DispositionText"); getWidget(mDispositionText,"DispositionText");
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize); static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
} }
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
{ {
ISubWidgetText* t = history->getClient()->getSubWidgetText(); ISubWidgetText* t = mHistory->getClient()->getSubWidgetText();
if(t == nullptr) if(t == nullptr)
return; return;
const IntPoint& lastPressed = InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left); const IntPoint& lastPressed = InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left);
size_t cursorPosition = t->getCursorPosition(lastPressed); size_t cursorPosition = t->getCursorPosition(lastPressed);
MyGUI::UString color = history->getColorAtPos(cursorPosition); MyGUI::UString color = mHistory->getColorAtPos(cursorPosition);
if (!mEnabled && color == "#572D21") if (!mEnabled && color == "#572D21")
MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
if(color != "#B29154") if(color != "#B29154")
{ {
UString key = history->getColorTextAt(cursorPosition); UString key = mHistory->getColorTextAt(cursorPosition);
if(color == "#686EBA") MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(key)); if(color == "#686EBA") MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(key));
if(color == "#572D21") MWBase::Environment::get().getDialogueManager()->questionAnswered(lower_string(key)); if(color == "#572D21") MWBase::Environment::get().getDialogueManager()->questionAnswered(lower_string(key));
@ -101,15 +100,15 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
void DialogueWindow::onWindowResize(MyGUI::Window* _sender) void DialogueWindow::onWindowResize(MyGUI::Window* _sender)
{ {
topicsList->adjustSize(); mTopicsList->adjustSize();
} }
void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{ {
if (history->getVScrollPosition() - _rel*0.3 < 0) if (mHistory->getVScrollPosition() - _rel*0.3 < 0)
history->setVScrollPosition(0); mHistory->setVScrollPosition(0);
else else
history->setVScrollPosition(history->getVScrollPosition() - _rel*0.3); mHistory->setVScrollPosition(mHistory->getVScrollPosition() - _rel*0.3);
} }
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
@ -136,40 +135,40 @@ void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
{ {
mEnabled = true; mEnabled = true;
mPtr = actor; mPtr = actor;
topicsList->setEnabled(true); mTopicsList->setEnabled(true);
setTitle(npcName); setTitle(npcName);
topicsList->clear(); mTopicsList->clear();
history->eraseText(0,history->getTextLength()); mHistory->eraseText(0,mHistory->getTextLength());
updateOptions(); updateOptions();
} }
void DialogueWindow::setKeywords(std::list<std::string> keyWords) void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{ {
topicsList->clear(); mTopicsList->clear();
bool anyService = mShowTrade; bool anyService = mShowTrade;
if (mShowTrade) if (mShowTrade)
topicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str); mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str);
if (anyService) if (anyService)
topicsList->addSeparator(); mTopicsList->addSeparator();
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it) for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
{ {
topicsList->addItem(*it); mTopicsList->addItem(*it);
} }
topicsList->adjustSize(); mTopicsList->adjustSize();
} }
void DialogueWindow::removeKeyword(std::string keyWord) void DialogueWindow::removeKeyword(std::string keyWord)
{ {
if(topicsList->hasItem(keyWord)) if(mTopicsList->hasItem(keyWord))
{ {
topicsList->removeItem(keyWord); mTopicsList->removeItem(keyWord);
} }
topicsList->adjustSize(); mTopicsList->adjustSize();
} }
void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2) void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2)
@ -206,9 +205,9 @@ void addColorInString(std::string& str, const std::string& keyword,std::string c
std::string DialogueWindow::parseText(std::string text) std::string DialogueWindow::parseText(std::string text)
{ {
bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored) bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored)
for(unsigned int i = 0;i<topicsList->getItemCount();i++) for(unsigned int i = 0;i<mTopicsList->getItemCount();i++)
{ {
std::string keyWord = topicsList->getItemNameAt(i); std::string keyWord = mTopicsList->getItemNameAt(i);
if (separatorReached && keyWord != "") if (separatorReached && keyWord != "")
addColorInString(text,keyWord,"#686EBA","#B29154"); addColorInString(text,keyWord,"#686EBA","#B29154");
else else
@ -219,7 +218,7 @@ std::string DialogueWindow::parseText(std::string text)
void DialogueWindow::addText(std::string text) void DialogueWindow::addText(std::string text)
{ {
history->addDialogText("#B29154"+parseText(text)+"#B29154"); mHistory->addDialogText("#B29154"+parseText(text)+"#B29154");
} }
void DialogueWindow::addTitle(std::string text) void DialogueWindow::addTitle(std::string text)
@ -227,37 +226,37 @@ void DialogueWindow::addTitle(std::string text)
// This is called from the dialogue manager, so text is // This is called from the dialogue manager, so text is
// case-smashed - thus we have to retrieve the correct case // case-smashed - thus we have to retrieve the correct case
// of the text through the topic list. // of the text through the topic list.
for (size_t i=0; i<topicsList->getItemCount(); ++i) for (size_t i=0; i<mTopicsList->getItemCount(); ++i)
{ {
std::string item = topicsList->getItemNameAt(i); std::string item = mTopicsList->getItemNameAt(i);
if (lower_string(item) == text) if (lower_string(item) == text)
text = item; text = item;
} }
history->addDialogHeading(text); mHistory->addDialogHeading(text);
} }
void DialogueWindow::askQuestion(std::string question) void DialogueWindow::askQuestion(std::string question)
{ {
history->addDialogText("#572D21"+question+"#B29154"+" "); mHistory->addDialogText("#572D21"+question+"#B29154"+" ");
} }
void DialogueWindow::updateOptions() void DialogueWindow::updateOptions()
{ {
//Clear the list of topics //Clear the list of topics
topicsList->clear(); mTopicsList->clear();
history->eraseText(0,history->getTextLength()); mHistory->eraseText(0, mHistory->getTextLength());
pDispositionBar->setProgressRange(100); mDispositionBar->setProgressRange(100);
pDispositionBar->setProgressPosition(40); mDispositionBar->setProgressPosition(40);
pDispositionText->eraseText(0,pDispositionText->getTextLength()); mDispositionText->eraseText(0, mDispositionText->getTextLength());
pDispositionText->addText("#B29154"+std::string("40/100")+"#B29154"); mDispositionText->addText("#B29154"+std::string("40/100")+"#B29154");
} }
void DialogueWindow::goodbye() void DialogueWindow::goodbye()
{ {
history->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->str); mHistory->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->str);
topicsList->setEnabled(false); mTopicsList->setEnabled(false);
mEnabled = false; mEnabled = false;
} }

View file

@ -73,10 +73,10 @@ namespace MWGui
bool mEnabled; bool mEnabled;
DialogueHistory* history; DialogueHistory* mHistory;
Widgets::MWList* topicsList; Widgets::MWList* mTopicsList;
MyGUI::ProgressPtr pDispositionBar; MyGUI::ProgressPtr mDispositionBar;
MyGUI::EditPtr pDispositionText; MyGUI::EditPtr mDispositionText;
}; };
} }
#endif #endif

View file

@ -3,7 +3,6 @@
#include "widgets.hpp" #include "widgets.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
#include <assert.h>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>

View file

@ -28,24 +28,24 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
, health(NULL) , health(NULL)
, magicka(NULL) , magicka(NULL)
, stamina(NULL) , stamina(NULL)
, weapImage(NULL) , mWeapImage(NULL)
, spellImage(NULL) , mSpellImage(NULL)
, weapStatus(NULL) , mWeapStatus(NULL)
, spellStatus(NULL) , mSpellStatus(NULL)
, effectBox(NULL) , mEffectBox(NULL)
, effect1(NULL) , mEffect1(NULL)
, minimap(NULL) , mMinimap(NULL)
, compass(NULL) , mCompass(NULL)
, crosshair(NULL) , mCrosshair(NULL)
, fpsbox(NULL) , fpsbox(NULL)
, fpscounter(NULL) , fpscounter(NULL)
, trianglecounter(NULL) , trianglecounter(NULL)
, batchcounter(NULL) , batchcounter(NULL)
, hmsBaseLeft(0) , mHealthManaStaminaBaseLeft(0)
, weapBoxBaseLeft(0) , mWeapBoxBaseLeft(0)
, spellBoxBaseLeft(0) , mSpellBoxBaseLeft(0)
, effectBoxBaseRight(0) , mEffectBoxBaseRight(0)
, minimapBoxBaseRight(0) , mMinimapBoxBaseRight(0)
, mDragAndDrop(dragAndDrop) , mDragAndDrop(dragAndDrop)
, mCellNameTimer(0.0f) , mCellNameTimer(0.0f)
, mCellNameBox(NULL) , mCellNameBox(NULL)
@ -62,7 +62,7 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
getWidget(magicka, "Magicka"); getWidget(magicka, "Magicka");
getWidget(stamina, "Stamina"); getWidget(stamina, "Stamina");
hmsBaseLeft = mHealthFrame->getLeft(); mHealthManaStaminaBaseLeft = mHealthFrame->getLeft();
MyGUI::Widget *healthFrame, *magickaFrame, *fatigueFrame; MyGUI::Widget *healthFrame, *magickaFrame, *fatigueFrame;
getWidget(healthFrame, "HealthFrame"); getWidget(healthFrame, "HealthFrame");
@ -75,33 +75,33 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
// Item and spell images and status bars // Item and spell images and status bars
getWidget(weapBox, "WeapBox"); getWidget(mWeapBox, "WeapBox");
getWidget(weapImage, "WeapImage"); getWidget(mWeapImage, "WeapImage");
getWidget(weapStatus, "WeapStatus"); getWidget(mWeapStatus, "WeapStatus");
weapBoxBaseLeft = weapBox->getLeft(); mWeapBoxBaseLeft = mWeapBox->getLeft();
weapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWeaponClicked); mWeapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWeaponClicked);
getWidget(spellBox, "SpellBox"); getWidget(mSpellBox, "SpellBox");
getWidget(spellImage, "SpellImage"); getWidget(mSpellImage, "SpellImage");
getWidget(spellStatus, "SpellStatus"); getWidget(mSpellStatus, "SpellStatus");
spellBoxBaseLeft = spellBox->getLeft(); mSpellBoxBaseLeft = mSpellBox->getLeft();
spellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); mSpellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
getWidget(effectBox, "EffectBox"); getWidget(mEffectBox, "EffectBox");
getWidget(effect1, "Effect1"); getWidget(mEffect1, "Effect1");
effectBoxBaseRight = viewSize.width - effectBox->getRight(); mEffectBoxBaseRight = viewSize.width - mEffectBox->getRight();
effectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); mEffectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
getWidget(minimapBox, "MiniMapBox"); getWidget(mMinimapBox, "MiniMapBox");
minimapBoxBaseRight = viewSize.width - minimapBox->getRight(); mMinimapBoxBaseRight = viewSize.width - mMinimapBox->getRight();
minimapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked); mMinimapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
getWidget(minimap, "MiniMap"); getWidget(mMinimap, "MiniMap");
getWidget(compass, "Compass"); getWidget(mCompass, "Compass");
getWidget(mCellNameBox, "CellName"); getWidget(mCellNameBox, "CellName");
getWidget(mWeaponSpellBox, "WeaponSpellName"); getWidget(mWeaponSpellBox, "WeaponSpellName");
getWidget(crosshair, "Crosshair"); getWidget(mCrosshair, "Crosshair");
setFpsLevel(fpsLevel); setFpsLevel(fpsLevel);
@ -110,7 +110,7 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
setEffect("icons\\s\\tx_s_chameleon.dds"); setEffect("icons\\s\\tx_s_chameleon.dds");
LocalMapBase::init(minimap, compass, this); LocalMapBase::init(mMinimap, mCompass, this);
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked); mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver); mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
@ -159,7 +159,7 @@ void HUD::setBatchCount(unsigned int count)
void HUD::setEffect(const char *img) void HUD::setEffect(const char *img)
{ {
effect1->setImageTexture(img); mEffect1->setImageTexture(img);
} }
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& value) void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& value)
@ -202,10 +202,10 @@ void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellV
{ {
int weapDx = 0, spellDx = 0; int weapDx = 0, spellDx = 0;
if (!hmsVisible) if (!hmsVisible)
spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft; spellDx = weapDx = mWeapBoxBaseLeft - mHealthManaStaminaBaseLeft;
if (!weapVisible) if (!weapVisible)
spellDx += spellBoxBaseLeft - weapBoxBaseLeft; spellDx += mSpellBoxBaseLeft - mWeapBoxBaseLeft;
mWeaponVisible = weapVisible; mWeaponVisible = weapVisible;
mSpellVisible = spellVisible; mSpellVisible = spellVisible;
@ -215,10 +215,10 @@ void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellV
health->setVisible(hmsVisible); health->setVisible(hmsVisible);
stamina->setVisible(hmsVisible); stamina->setVisible(hmsVisible);
magicka->setVisible(hmsVisible); magicka->setVisible(hmsVisible);
weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop()); mWeapBox->setPosition(mWeapBoxBaseLeft - weapDx, mWeapBox->getTop());
weapBox->setVisible(weapVisible); mWeapBox->setVisible(weapVisible);
spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop()); mSpellBox->setPosition(mSpellBoxBaseLeft - spellDx, mSpellBox->getTop());
spellBox->setVisible(spellVisible); mSpellBox->setVisible(spellVisible);
} }
void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible) void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible)
@ -228,12 +228,12 @@ void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible
// effect box can have variable width -> variable left coordinate // effect box can have variable width -> variable left coordinate
int effectsDx = 0; int effectsDx = 0;
if (!minimapBoxVisible) if (!minimapBoxVisible)
effectsDx = (viewSize.width - minimapBoxBaseRight) - (viewSize.width - effectBoxBaseRight); effectsDx = (viewSize.width - mMinimapBoxBaseRight) - (viewSize.width - mEffectBoxBaseRight);
mMapVisible = minimapBoxVisible; mMapVisible = minimapBoxVisible;
minimapBox->setVisible(minimapBoxVisible); mMinimapBox->setVisible(minimapBoxVisible);
effectBox->setPosition((viewSize.width - effectBoxBaseRight) - effectBox->getWidth() + effectsDx, effectBox->getTop()); mEffectBox->setPosition((viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop());
effectBox->setVisible(effectBoxVisible); mEffectBox->setVisible(effectBoxVisible);
} }
void HUD::onWorldClicked(MyGUI::Widget* _sender) void HUD::onWorldClicked(MyGUI::Widget* _sender)
@ -395,14 +395,14 @@ void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
mWeaponSpellBox->setVisible(true); mWeaponSpellBox->setVisible(true);
} }
spellStatus->setProgressRange(100); mSpellStatus->setProgressRange(100);
spellStatus->setProgressPosition(successChancePercent); mSpellStatus->setProgressPosition(successChancePercent);
if (spellImage->getChildCount()) if (mSpellImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(mSpellImage->getChildAt(0));
spellBox->setUserString("ToolTipType", "Spell"); mSpellBox->setUserString("ToolTipType", "Spell");
spellBox->setUserString("Spell", spellId); mSpellBox->setUserString("Spell", spellId);
// use the icon of the first effect // use the icon of the first effect
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(spell->effects.list.front().effectID); const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(spell->effects.list.front().effectID);
@ -411,7 +411,7 @@ void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
icon.insert(slashPos+1, "b_"); icon.insert(slashPos+1, "b_");
icon = std::string("icons\\") + icon; icon = std::string("icons\\") + icon;
Widgets::fixTexturePath(icon); Widgets::fixTexturePath(icon);
spellImage->setImageTexture(icon); mSpellImage->setImageTexture(icon);
} }
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent) void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
@ -425,17 +425,17 @@ void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
mWeaponSpellBox->setVisible(true); mWeaponSpellBox->setVisible(true);
} }
spellStatus->setProgressRange(100); mSpellStatus->setProgressRange(100);
spellStatus->setProgressPosition(chargePercent); mSpellStatus->setProgressPosition(chargePercent);
if (spellImage->getChildCount()) if (mSpellImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(mSpellImage->getChildAt(0));
spellBox->setUserString("ToolTipType", "ItemPtr"); mSpellBox->setUserString("ToolTipType", "ItemPtr");
spellBox->setUserData(item); mSpellBox->setUserData(item);
spellImage->setImageTexture("textures\\menu_icon_magic_mini.dds"); mSpellImage->setImageTexture("textures\\menu_icon_magic_mini.dds");
MyGUI::ImageBox* itemBox = spellImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1) MyGUI::ImageBox* itemBox = mSpellImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
, MyGUI::Align::Stretch); , MyGUI::Align::Stretch);
std::string path = std::string("icons\\"); std::string path = std::string("icons\\");
@ -456,14 +456,14 @@ void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
mWeaponSpellBox->setVisible(true); mWeaponSpellBox->setVisible(true);
} }
weapBox->setUserString("ToolTipType", "ItemPtr"); mWeapBox->setUserString("ToolTipType", "ItemPtr");
weapBox->setUserData(item); mWeapBox->setUserData(item);
weapStatus->setProgressRange(100); mWeapStatus->setProgressRange(100);
weapStatus->setProgressPosition(durabilityPercent); mWeapStatus->setProgressPosition(durabilityPercent);
if (weapImage->getChildCount()) if (mWeapImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(weapImage->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(mWeapImage->getChildAt(0));
std::string path = std::string("icons\\"); std::string path = std::string("icons\\");
path+=MWWorld::Class::get(item).getInventoryIcon(item); path+=MWWorld::Class::get(item).getInventoryIcon(item);
@ -471,14 +471,14 @@ void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
if (MWWorld::Class::get(item).getEnchantment(item) != "") if (MWWorld::Class::get(item).getEnchantment(item) != "")
{ {
weapImage->setImageTexture("textures\\menu_icon_magic_mini.dds"); mWeapImage->setImageTexture("textures\\menu_icon_magic_mini.dds");
MyGUI::ImageBox* itemBox = weapImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1) MyGUI::ImageBox* itemBox = mWeapImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
, MyGUI::Align::Stretch); , MyGUI::Align::Stretch);
itemBox->setImageTexture(path); itemBox->setImageTexture(path);
itemBox->setNeedMouseFocus(false); itemBox->setNeedMouseFocus(false);
} }
else else
weapImage->setImageTexture(path); mWeapImage->setImageTexture(path);
} }
void HUD::unsetSelectedSpell() void HUD::unsetSelectedSpell()
@ -492,12 +492,12 @@ void HUD::unsetSelectedSpell()
mWeaponSpellBox->setVisible(true); mWeaponSpellBox->setVisible(true);
} }
if (spellImage->getChildCount()) if (mSpellImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(mSpellImage->getChildAt(0));
spellStatus->setProgressRange(100); mSpellStatus->setProgressRange(100);
spellStatus->setProgressPosition(0); mSpellStatus->setProgressPosition(0);
spellImage->setImageTexture(""); mSpellImage->setImageTexture("");
spellBox->clearUserStrings(); mSpellBox->clearUserStrings();
} }
void HUD::unsetSelectedWeapon() void HUD::unsetSelectedWeapon()
@ -511,10 +511,10 @@ void HUD::unsetSelectedWeapon()
mWeaponSpellBox->setVisible(true); mWeaponSpellBox->setVisible(true);
} }
if (weapImage->getChildCount()) if (mWeapImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(weapImage->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(mWeapImage->getChildAt(0));
weapStatus->setProgressRange(100); mWeapStatus->setProgressRange(100);
weapStatus->setProgressPosition(0); mWeapStatus->setProgressPosition(0);
weapImage->setImageTexture("icons\\k\\stealth_handtohand.dds"); mWeapImage->setImageTexture("icons\\k\\stealth_handtohand.dds");
weapBox->clearUserStrings(); mWeapBox->clearUserStrings();
} }

View file

@ -37,14 +37,14 @@ namespace MWGui
MyGUI::ProgressPtr health, magicka, stamina; MyGUI::ProgressPtr health, magicka, stamina;
MyGUI::Widget* mHealthFrame; MyGUI::Widget* mHealthFrame;
MyGUI::Widget *weapBox, *spellBox; MyGUI::Widget *mWeapBox, *mSpellBox;
MyGUI::ImageBox *weapImage, *spellImage; MyGUI::ImageBox *mWeapImage, *mSpellImage;
MyGUI::ProgressPtr weapStatus, spellStatus; MyGUI::ProgressPtr mWeapStatus, mSpellStatus;
MyGUI::Widget *effectBox, *minimapBox; MyGUI::Widget *mEffectBox, *mMinimapBox;
MyGUI::ImageBox* effect1; MyGUI::ImageBox* mEffect1;
MyGUI::ScrollView* minimap; MyGUI::ScrollView* mMinimap;
MyGUI::ImageBox* compass; MyGUI::ImageBox* mCompass;
MyGUI::ImageBox* crosshair; MyGUI::ImageBox* mCrosshair;
MyGUI::TextBox* mCellNameBox; MyGUI::TextBox* mCellNameBox;
MyGUI::TextBox* mWeaponSpellBox; MyGUI::TextBox* mWeaponSpellBox;
@ -55,9 +55,9 @@ namespace MWGui
private: private:
// bottom left elements // bottom left elements
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft; int mHealthManaStaminaBaseLeft, mWeapBoxBaseLeft, mSpellBoxBaseLeft;
// bottom right elements // bottom right elements
int minimapBoxBaseRight, effectBoxBaseRight; int mMinimapBoxBaseRight, mEffectBoxBaseRight;
DragAndDrop* mDragAndDrop; DragAndDrop* mDragAndDrop;

View file

@ -84,7 +84,7 @@ book formatText(std::string text,book mBook,int maxLine, int lineSize)
MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager) MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager)
: WindowBase("openmw_journal.layout", parWindowManager) : WindowBase("openmw_journal.layout", parWindowManager)
, lastPos(0) , mLastPos(0)
, mVisible(false) , mVisible(false)
{ {
//setCoord(0,0,498, 342); //setCoord(0,0,498, 342);
@ -148,19 +148,19 @@ void MWGui::JournalWindow::open()
{ {
if(left) if(left)
{ {
leftPages.push_back(*it); mLeftPages.push_back(*it);
} }
else else
{ {
rightPages.push_back(*it); mRightPages.push_back(*it);
} }
left = !left; left = !left;
} }
if(!left) rightPages.push_back(""); if(!left) mRightPages.push_back("");
mPageNumber = leftPages.size()-1; mPageNumber = mLeftPages.size()-1;
displayLeftText(leftPages[mPageNumber]); displayLeftText(mLeftPages[mPageNumber]);
displayRightText(rightPages[mPageNumber]); displayRightText(mRightPages[mPageNumber]);
} }
else else
@ -184,13 +184,13 @@ void MWGui::JournalWindow::displayRightText(std::string text)
void MWGui::JournalWindow::notifyNextPage(MyGUI::WidgetPtr _sender) void MWGui::JournalWindow::notifyNextPage(MyGUI::WidgetPtr _sender)
{ {
if(mPageNumber < int(leftPages.size())-1) if(mPageNumber < int(mLeftPages.size())-1)
{ {
std::string nextSound = "book page2"; std::string nextSound = "book page2";
MWBase::Environment::get().getSoundManager()->playSound (nextSound, 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound (nextSound, 1.0, 1.0);
mPageNumber = mPageNumber + 1; mPageNumber = mPageNumber + 1;
displayLeftText(leftPages[mPageNumber]); displayLeftText(mLeftPages[mPageNumber]);
displayRightText(rightPages[mPageNumber]); displayRightText(mRightPages[mPageNumber]);
} }
} }
@ -201,7 +201,7 @@ void MWGui::JournalWindow::notifyPrevPage(MyGUI::WidgetPtr _sender)
std::string prevSound = "book page"; std::string prevSound = "book page";
MWBase::Environment::get().getSoundManager()->playSound (prevSound, 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound (prevSound, 1.0, 1.0);
mPageNumber = mPageNumber - 1; mPageNumber = mPageNumber - 1;
displayLeftText(leftPages[mPageNumber]); displayLeftText(mLeftPages[mPageNumber]);
displayRightText(rightPages[mPageNumber]); displayRightText(mRightPages[mPageNumber]);
} }
} }

View file

@ -31,17 +31,17 @@ namespace MWGui
void notifyNextPage(MyGUI::WidgetPtr _sender); void notifyNextPage(MyGUI::WidgetPtr _sender);
void notifyPrevPage(MyGUI::WidgetPtr _sender); void notifyPrevPage(MyGUI::WidgetPtr _sender);
static const int lineHeight; static const int sLineHeight;
MyGUI::WidgetPtr skillAreaWidget, skillClientWidget; MyGUI::WidgetPtr mSkillAreaWidget, mSkillClientWidget;
MyGUI::ScrollBar* skillScrollerWidget; MyGUI::ScrollBar* mSkillScrollerWidget;
int lastPos, clientHeight; int mLastPos, mClientHeight;
MyGUI::EditPtr mLeftTextWidget; MyGUI::EditPtr mLeftTextWidget;
MyGUI::EditPtr mRightTextWidget; MyGUI::EditPtr mRightTextWidget;
MyGUI::ButtonPtr mPrevBtn; MyGUI::ButtonPtr mPrevBtn;
MyGUI::ButtonPtr mNextBtn; MyGUI::ButtonPtr mNextBtn;
std::vector<std::string> leftPages; std::vector<std::string> mLeftPages;
std::vector<std::string> rightPages; std::vector<std::string> mRightPages;
int mPageNumber; //store the number of the current left page int mPageNumber; //store the number of the current left page
bool mVisible; bool mVisible;
}; };

View file

@ -149,7 +149,7 @@ int MessageBoxManager::readPressedButton ()
MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message) MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message)
: Layout("openmw_messagebox.layout") : Layout("openmw_messagebox.layout")
, mMessageBoxManager(parMessageBoxManager) , mMessageBoxManager(parMessageBoxManager)
, cMessage(message) , mMessage(message)
{ {
// defines // defines
mFixedWidth = 300; mFixedWidth = 300;
@ -160,7 +160,7 @@ MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::strin
getWidget(mMessageWidget, "message"); getWidget(mMessageWidget, "message");
mMessageWidget->setOverflowToTheLeft(true); mMessageWidget->setOverflowToTheLeft(true);
mMessageWidget->setCaptionWithReplacing(cMessage); mMessageWidget->setCaptionWithReplacing(mMessage);
MyGUI::IntSize size; MyGUI::IntSize size;
size.width = mFixedWidth; size.width = mFixedWidth;

View file

@ -59,7 +59,7 @@ namespace MWGui
protected: protected:
MessageBoxManager& mMessageBoxManager; MessageBoxManager& mMessageBoxManager;
int mHeight; int mHeight;
const std::string& cMessage; const std::string& mMessage;
MyGUI::EditPtr mMessageWidget; MyGUI::EditPtr mMessageWidget;
int mFixedWidth; int mFixedWidth;
int mBottomPadding; int mBottomPadding;

View file

@ -1,6 +1,5 @@
#include "race.hpp" #include "race.hpp"
#include <assert.h>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
@ -18,11 +17,11 @@ using namespace Widgets;
RaceDialog::RaceDialog(WindowManager& parWindowManager) RaceDialog::RaceDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_race.layout", parWindowManager) : WindowBase("openmw_chargen_race.layout", parWindowManager)
, genderIndex(0) , mGenderIndex(0)
, faceIndex(0) , mFaceIndex(0)
, hairIndex(0) , mHairIndex(0)
, faceCount(10) , mFaceCount(10)
, hairCount(14) , mHairCount(14)
{ {
// Centre dialog // Centre dialog
center(); center();
@ -31,13 +30,13 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager)
// real calls from outside the class later. // real calls from outside the class later.
setText("AppearanceT", mWindowManager.getGameSettingString("sRaceMenu1", "Appearance")); setText("AppearanceT", mWindowManager.getGameSettingString("sRaceMenu1", "Appearance"));
getWidget(appearanceBox, "AppearanceBox"); getWidget(mAppearanceBox, "AppearanceBox");
getWidget(headRotate, "HeadRotate"); getWidget(mHeadRotate, "HeadRotate");
headRotate->setScrollRange(50); mHeadRotate->setScrollRange(50);
headRotate->setScrollPosition(20); mHeadRotate->setScrollPosition(20);
headRotate->setScrollViewPage(10); mHeadRotate->setScrollViewPage(10);
headRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate); mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate);
// Set up next/previous buttons // Set up next/previous buttons
MyGUI::ButtonPtr prevButton, nextButton; MyGUI::ButtonPtr prevButton, nextButton;
@ -61,16 +60,16 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager)
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair); nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair);
setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu4", "Race")); setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu4", "Race"));
getWidget(raceList, "RaceList"); getWidget(mRaceList, "RaceList");
raceList->setScrollVisible(true); mRaceList->setScrollVisible(true);
raceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace); mRaceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
raceList->eventListMouseItemActivate += MyGUI::newDelegate(this, &RaceDialog::onSelectRace); mRaceList->eventListMouseItemActivate += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
raceList->eventListChangePosition += MyGUI::newDelegate(this, &RaceDialog::onSelectRace); mRaceList->eventListChangePosition += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
setText("SkillsT", mWindowManager.getGameSettingString("sBonusSkillTitle", "Skill Bonus")); setText("SkillsT", mWindowManager.getGameSettingString("sBonusSkillTitle", "Skill Bonus"));
getWidget(skillList, "SkillList"); getWidget(mSkillList, "SkillList");
setText("SpellPowerT", mWindowManager.getGameSettingString("sRaceMenu7", "Specials")); setText("SpellPowerT", mWindowManager.getGameSettingString("sRaceMenu7", "Specials"));
getWidget(spellPowerList, "SpellPowerList"); getWidget(mSpellPowerList, "SpellPowerList");
MyGUI::ButtonPtr backButton; MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
@ -117,14 +116,14 @@ void RaceDialog::open()
void RaceDialog::setRaceId(const std::string &raceId) void RaceDialog::setRaceId(const std::string &raceId)
{ {
currentRaceId = raceId; mCurrentRaceId = raceId;
raceList->setIndexSelected(MyGUI::ITEM_NONE); mRaceList->setIndexSelected(MyGUI::ITEM_NONE);
size_t count = raceList->getItemCount(); size_t count = mRaceList->getItemCount();
for (size_t i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
if (boost::iequals(*raceList->getItemDataAt<std::string>(i), raceId)) if (boost::iequals(*mRaceList->getItemDataAt<std::string>(i), raceId))
{ {
raceList->setIndexSelected(i); mRaceList->setIndexSelected(i);
break; break;
} }
} }
@ -162,32 +161,32 @@ void RaceDialog::onHeadRotate(MyGUI::ScrollBar*, size_t _position)
void RaceDialog::onSelectPreviousGender(MyGUI::Widget*) void RaceDialog::onSelectPreviousGender(MyGUI::Widget*)
{ {
genderIndex = wrap(genderIndex - 1, 2); mGenderIndex = wrap(mGenderIndex - 1, 2);
} }
void RaceDialog::onSelectNextGender(MyGUI::Widget*) void RaceDialog::onSelectNextGender(MyGUI::Widget*)
{ {
genderIndex = wrap(genderIndex + 1, 2); mGenderIndex = wrap(mGenderIndex + 1, 2);
} }
void RaceDialog::onSelectPreviousFace(MyGUI::Widget*) void RaceDialog::onSelectPreviousFace(MyGUI::Widget*)
{ {
faceIndex = wrap(faceIndex - 1, faceCount); mFaceIndex = wrap(mFaceIndex - 1, mFaceCount);
} }
void RaceDialog::onSelectNextFace(MyGUI::Widget*) void RaceDialog::onSelectNextFace(MyGUI::Widget*)
{ {
faceIndex = wrap(faceIndex + 1, faceCount); mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
} }
void RaceDialog::onSelectPreviousHair(MyGUI::Widget*) void RaceDialog::onSelectPreviousHair(MyGUI::Widget*)
{ {
hairIndex = wrap(hairIndex - 1, hairCount); mHairIndex = wrap(mHairIndex - 1, mHairCount);
} }
void RaceDialog::onSelectNextHair(MyGUI::Widget*) void RaceDialog::onSelectNextHair(MyGUI::Widget*)
{ {
hairIndex = wrap(hairIndex - 1, hairCount); mHairIndex = wrap(mHairIndex - 1, mHairCount);
} }
void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index) void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
@ -195,11 +194,11 @@ void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
if (_index == MyGUI::ITEM_NONE) if (_index == MyGUI::ITEM_NONE)
return; return;
const std::string *raceId = raceList->getItemDataAt<std::string>(_index); const std::string *raceId = mRaceList->getItemDataAt<std::string>(_index);
if (boost::iequals(currentRaceId, *raceId)) if (boost::iequals(mCurrentRaceId, *raceId))
return; return;
currentRaceId = *raceId; mCurrentRaceId = *raceId;
updateSkills(); updateSkills();
updateSpellPowers(); updateSpellPowers();
} }
@ -208,7 +207,7 @@ void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
void RaceDialog::updateRaces() void RaceDialog::updateRaces()
{ {
raceList->removeAllItems(); mRaceList->removeAllItems();
const ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
@ -222,30 +221,30 @@ void RaceDialog::updateRaces()
if (!playable) // Only display playable races if (!playable) // Only display playable races
continue; continue;
raceList->addItem(race.name, it->first); mRaceList->addItem(race.name, it->first);
if (boost::iequals(it->first, currentRaceId)) if (boost::iequals(it->first, mCurrentRaceId))
raceList->setIndexSelected(index); mRaceList->setIndexSelected(index);
++index; ++index;
} }
} }
void RaceDialog::updateSkills() void RaceDialog::updateSkills()
{ {
for (std::vector<MyGUI::WidgetPtr>::iterator it = skillItems.begin(); it != skillItems.end(); ++it) for (std::vector<MyGUI::WidgetPtr>::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }
skillItems.clear(); mSkillItems.clear();
if (currentRaceId.empty()) if (mCurrentRaceId.empty())
return; return;
MWSkillPtr skillWidget; MWSkillPtr skillWidget;
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord1(0, 0, skillList->getWidth(), 18); MyGUI::IntCoord coord1(0, 0, mSkillList->getWidth(), 18);
const ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::Race *race = store.races.find(currentRaceId); const ESM::Race *race = store.races.find(mCurrentRaceId);
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)
{ {
@ -253,7 +252,7 @@ void RaceDialog::updateSkills()
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
continue; continue;
skillWidget = skillList->createWidget<MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default, skillWidget = mSkillList->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(&mWindowManager); skillWidget->setWindowManager(&mWindowManager);
skillWidget->setSkillNumber(skillId); skillWidget->setSkillNumber(skillId);
@ -261,7 +260,7 @@ void RaceDialog::updateSkills()
ToolTips::createSkillToolTip(skillWidget, skillId); ToolTips::createSkillToolTip(skillWidget, skillId);
skillItems.push_back(skillWidget); mSkillItems.push_back(skillWidget);
coord1.top += lineHeight; coord1.top += lineHeight;
} }
@ -269,34 +268,34 @@ void RaceDialog::updateSkills()
void RaceDialog::updateSpellPowers() void RaceDialog::updateSpellPowers()
{ {
for (std::vector<MyGUI::WidgetPtr>::iterator it = spellPowerItems.begin(); it != spellPowerItems.end(); ++it) for (std::vector<MyGUI::WidgetPtr>::iterator it = mSpellPowerItems.begin(); it != mSpellPowerItems.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }
spellPowerItems.clear(); mSpellPowerItems.clear();
if (currentRaceId.empty()) if (mCurrentRaceId.empty())
return; return;
MWSpellPtr spellPowerWidget; MWSpellPtr spellPowerWidget;
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, spellPowerList->getWidth(), 18); MyGUI::IntCoord coord(0, 0, mSpellPowerList->getWidth(), 18);
const ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::Race *race = store.races.find(currentRaceId); const ESM::Race *race = store.races.find(mCurrentRaceId);
std::vector<std::string>::const_iterator it = race->powers.list.begin(); std::vector<std::string>::const_iterator it = race->powers.list.begin();
std::vector<std::string>::const_iterator end = race->powers.list.end(); std::vector<std::string>::const_iterator end = race->powers.list.end();
for (int i = 0; it != end; ++it) for (int i = 0; it != end; ++it)
{ {
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 = mSpellPowerList->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i));
spellPowerWidget->setWindowManager(&mWindowManager); spellPowerWidget->setWindowManager(&mWindowManager);
spellPowerWidget->setSpellId(spellpower); spellPowerWidget->setSpellId(spellpower);
spellPowerWidget->setUserString("ToolTipType", "Spell"); spellPowerWidget->setUserString("ToolTipType", "Spell");
spellPowerWidget->setUserString("Spell", spellpower); spellPowerWidget->setUserString("Spell", spellpower);
spellPowerItems.push_back(spellPowerWidget); mSpellPowerItems.push_back(spellPowerWidget);
coord.top += lineHeight; coord.top += lineHeight;
++i; ++i;

View file

@ -32,13 +32,13 @@ namespace MWGui
GM_Female GM_Female
}; };
const std::string &getRaceId() const { return currentRaceId; } const std::string &getRaceId() const { return mCurrentRaceId; }
Gender getGender() const { return genderIndex == 0 ? GM_Male : GM_Female; } Gender getGender() const { return mGenderIndex == 0 ? GM_Male : GM_Female; }
// getFace() // getFace()
// getHair() // getHair()
void setRaceId(const std::string &raceId); void setRaceId(const std::string &raceId);
void setGender(Gender gender) { genderIndex = gender == GM_Male ? 0 : 1; } void setGender(Gender gender) { mGenderIndex = gender == GM_Male ? 0 : 1; }
// setFace() // setFace()
// setHair() // setHair()
@ -75,20 +75,20 @@ namespace MWGui
void updateSkills(); void updateSkills();
void updateSpellPowers(); void updateSpellPowers();
MyGUI::CanvasPtr appearanceBox; MyGUI::CanvasPtr mAppearanceBox;
MyGUI::ListBox* raceList; MyGUI::ListBox* mRaceList;
MyGUI::ScrollBar* headRotate; MyGUI::ScrollBar* mHeadRotate;
MyGUI::WidgetPtr skillList; MyGUI::WidgetPtr mSkillList;
std::vector<MyGUI::WidgetPtr> skillItems; std::vector<MyGUI::WidgetPtr> mSkillItems;
MyGUI::WidgetPtr spellPowerList; MyGUI::WidgetPtr mSpellPowerList;
std::vector<MyGUI::WidgetPtr> spellPowerItems; std::vector<MyGUI::WidgetPtr> mSpellPowerItems;
int genderIndex, faceIndex, hairIndex; int mGenderIndex, mFaceIndex, mHairIndex;
int faceCount, hairCount; int mFaceCount, mHairCount;
std::string currentRaceId; std::string mCurrentRaceId;
}; };
} }
#endif #endif

View file

@ -17,49 +17,49 @@
using namespace MWGui; using namespace MWGui;
using namespace Widgets; using namespace Widgets;
const int ReviewDialog::lineHeight = 18; const int ReviewDialog::sLineHeight = 18;
ReviewDialog::ReviewDialog(WindowManager& parWindowManager) ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
: WindowBase("openmw_chargen_review.layout", parWindowManager) : WindowBase("openmw_chargen_review.layout", parWindowManager)
, lastPos(0) , mLastPos(0)
{ {
// Centre dialog // Centre dialog
center(); center();
// Setup static stats // Setup static stats
ButtonPtr button; ButtonPtr button;
getWidget(nameWidget, "NameText"); getWidget(mNameWidget, "NameText");
getWidget(button, "NameButton"); getWidget(button, "NameButton");
adjustButtonSize(button); adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);; button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);;
getWidget(raceWidget, "RaceText"); getWidget(mRaceWidget, "RaceText");
getWidget(button, "RaceButton"); getWidget(button, "RaceButton");
adjustButtonSize(button); adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);; button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);;
getWidget(classWidget, "ClassText"); getWidget(mClassWidget, "ClassText");
getWidget(button, "ClassButton"); getWidget(button, "ClassButton");
adjustButtonSize(button); adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);; button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);;
getWidget(birthSignWidget, "SignText"); getWidget(mBirthSignWidget, "SignText");
getWidget(button, "SignButton"); getWidget(button, "SignButton");
adjustButtonSize(button); adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);; button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);;
// Setup dynamic stats // Setup dynamic stats
getWidget(health, "Health"); getWidget(mHealth, "Health");
health->setTitle(mWindowManager.getGameSettingString("sHealth", "")); mHealth->setTitle(mWindowManager.getGameSettingString("sHealth", ""));
health->setValue(45, 45); mHealth->setValue(45, 45);
getWidget(magicka, "Magicka"); getWidget(mMagicka, "Magicka");
magicka->setTitle(mWindowManager.getGameSettingString("sMagic", "")); mMagicka->setTitle(mWindowManager.getGameSettingString("sMagic", ""));
magicka->setValue(50, 50); mMagicka->setValue(50, 50);
getWidget(fatigue, "Fatigue"); getWidget(mFatigue, "Fatigue");
fatigue->setTitle(mWindowManager.getGameSettingString("sFatigue", "")); mFatigue->setTitle(mWindowManager.getGameSettingString("sFatigue", ""));
fatigue->setValue(160, 160); mFatigue->setValue(160, 160);
// Setup attributes // Setup attributes
@ -67,24 +67,24 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
for (int idx = 0; idx < ESM::Attribute::Length; ++idx) for (int idx = 0; idx < ESM::Attribute::Length; ++idx)
{ {
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)); mAttributeWidgets.insert(std::make_pair(static_cast<int>(ESM::Attribute::attributeIds[idx]), attribute));
attribute->setWindowManager(&mWindowManager); 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));
} }
// Setup skills // Setup skills
getWidget(skillAreaWidget, "Skills"); getWidget(mSkillAreaWidget, "Skills");
getWidget(skillClientWidget, "SkillClient"); getWidget(mSkillClientWidget, "SkillClient");
getWidget(skillScrollerWidget, "SkillScroller"); getWidget(mSkillScrollerWidget, "SkillScroller");
skillClientWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); mSkillClientWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
skillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &ReviewDialog::onScrollChangePosition); mSkillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &ReviewDialog::onScrollChangePosition);
updateScroller(); updateScroller();
for (int i = 0; i < ESM::Skill::Length; ++i) for (int i = 0; i < ESM::Skill::Length; ++i)
{ {
skillValues.insert(std::make_pair(i, MWMechanics::Stat<float>())); mSkillValues.insert(std::make_pair(i, MWMechanics::Stat<float>()));
skillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0))); mSkillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0)));
} }
static_cast<MyGUI::WindowPtr>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ReviewDialog::onWindowResize); static_cast<MyGUI::WindowPtr>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ReviewDialog::onWindowResize);
@ -112,14 +112,14 @@ void ReviewDialog::open()
void ReviewDialog::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos) void ReviewDialog::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos)
{ {
int diff = lastPos - pos; int diff = mLastPos - pos;
// Adjust position of all widget according to difference // Adjust position of all widget according to difference
if (diff == 0) if (diff == 0)
return; return;
lastPos = pos; mLastPos = pos;
std::vector<MyGUI::WidgetPtr>::const_iterator end = skillWidgets.end(); std::vector<MyGUI::WidgetPtr>::const_iterator end = mSkillWidgets.end();
for (std::vector<MyGUI::WidgetPtr>::const_iterator it = skillWidgets.begin(); it != end; ++it) for (std::vector<MyGUI::WidgetPtr>::const_iterator it = mSkillWidgets.begin(); it != end; ++it)
{ {
(*it)->setCoord((*it)->getCoord() + MyGUI::IntPoint(0, diff)); (*it)->setCoord((*it)->getCoord() + MyGUI::IntPoint(0, diff));
} }
@ -132,63 +132,63 @@ void ReviewDialog::onWindowResize(MyGUI::Window* window)
void ReviewDialog::setPlayerName(const std::string &name) void ReviewDialog::setPlayerName(const std::string &name)
{ {
nameWidget->setCaption(name); mNameWidget->setCaption(name);
} }
void ReviewDialog::setRace(const std::string &raceId_) void ReviewDialog::setRace(const std::string &raceId)
{ {
raceId = raceId_; mRaceId = raceId;
const ESM::Race *race = mWindowManager.getStore().races.search(raceId); const ESM::Race *race = mWindowManager.getStore().races.search(mRaceId);
if (race) if (race)
{ {
ToolTips::createRaceToolTip(raceWidget, race); ToolTips::createRaceToolTip(mRaceWidget, race);
raceWidget->setCaption(race->name); mRaceWidget->setCaption(race->name);
} }
} }
void ReviewDialog::setClass(const ESM::Class& class_) void ReviewDialog::setClass(const ESM::Class& class_)
{ {
klass = class_; mKlass = class_;
classWidget->setCaption(klass.name); mClassWidget->setCaption(mKlass.name);
ToolTips::createClassToolTip(classWidget, klass); ToolTips::createClassToolTip(mClassWidget, mKlass);
} }
void ReviewDialog::setBirthSign(const std::string& signId) void ReviewDialog::setBirthSign(const std::string& signId)
{ {
birthSignId = signId; mBirthSignId = signId;
const ESM::BirthSign *sign = mWindowManager.getStore().birthSigns.search(birthSignId); const ESM::BirthSign *sign = mWindowManager.getStore().birthSigns.search(mBirthSignId);
if (sign) if (sign)
{ {
birthSignWidget->setCaption(sign->name); mBirthSignWidget->setCaption(sign->name);
ToolTips::createBirthsignToolTip(birthSignWidget, birthSignId); ToolTips::createBirthsignToolTip(mBirthSignWidget, mBirthSignId);
} }
} }
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<int>& value) void ReviewDialog::setHealth(const MWMechanics::DynamicStat<int>& value)
{ {
health->setValue(value.getCurrent(), value.getModified()); mHealth->setValue(value.getCurrent(), value.getModified());
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified()); std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
health->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr); mHealth->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
} }
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<int>& value) void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<int>& value)
{ {
magicka->setValue(value.getCurrent(), value.getModified()); mMagicka->setValue(value.getCurrent(), value.getModified());
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified()); std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
magicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr); mMagicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
} }
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<int>& value) void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<int>& value)
{ {
fatigue->setValue(value.getCurrent(), value.getModified()); mFatigue->setValue(value.getCurrent(), value.getModified());
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified()); std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
fatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr); mFatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
} }
void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value) void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value)
{ {
std::map<int, MWAttributePtr>::iterator attr = attributeWidgets.find(static_cast<int>(attributeId)); std::map<int, MWAttributePtr>::iterator attr = mAttributeWidgets.find(static_cast<int>(attributeId));
if (attr == attributeWidgets.end()) if (attr == mAttributeWidgets.end())
return; return;
attr->second->setAttributeValue(value); attr->second->setAttributeValue(value);
@ -196,8 +196,8 @@ void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const M
void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value) void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value)
{ {
skillValues[skillId] = value; mSkillValues[skillId] = value;
MyGUI::TextBox* widget = skillWidgetMap[skillId]; MyGUI::TextBox* widget = mSkillWidgetMap[skillId];
if (widget) if (widget)
{ {
float modified = value.getModified(), base = value.getBase(); float modified = value.getModified(), base = value.getBase();
@ -216,20 +216,20 @@ void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanic
void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor) void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor)
{ {
majorSkills = major; mMajorSkills = major;
minorSkills = minor; mMinorSkills = minor;
// Update misc skills with the remaining skills not in major or minor // Update misc skills with the remaining skills not in major or minor
std::set<int> skillSet; std::set<int> skillSet;
std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin())); std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin()));
std::copy(minor.begin(), minor.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(); boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator end = ESM::Skill::skillIds.end();
miscSkills.clear(); mMiscSkills.clear();
for (boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator it = ESM::Skill::skillIds.begin(); it != end; ++it) for (boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator it = ESM::Skill::skillIds.begin(); it != end; ++it)
{ {
int skill = *it; int skill = *it;
if (skillSet.find(skill) == skillSet.end()) if (skillSet.find(skill) == skillSet.end())
miscSkills.push_back(skill); mMiscSkills.push_back(skill);
} }
updateSkillArea(); updateSkillArea();
@ -237,10 +237,10 @@ void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vec
void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{ {
MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default); MyGUI::ImageBox* separator = mSkillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
skillWidgets.push_back(separator); mSkillWidgets.push_back(separator);
coord1.top += separator->getHeight(); coord1.top += separator->getHeight();
coord2.top += separator->getHeight(); coord2.top += separator->getHeight();
@ -248,13 +248,13 @@ void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2
void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{ {
MyGUI::TextBox* groupWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default); MyGUI::TextBox* groupWidget = mSkillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default);
groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
groupWidget->setCaption(label); groupWidget->setCaption(label);
skillWidgets.push_back(groupWidget); mSkillWidgets.push_back(groupWidget);
coord1.top += lineHeight; coord1.top += sLineHeight;
coord2.top += lineHeight; coord2.top += sLineHeight;
} }
MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
@ -262,20 +262,20 @@ MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::s
MyGUI::TextBox* skillNameWidget; MyGUI::TextBox* skillNameWidget;
MyGUI::TextBox* skillValueWidget; MyGUI::TextBox* skillValueWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default); skillNameWidget = mSkillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default);
skillNameWidget->setCaption(text); skillNameWidget->setCaption(text);
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right); skillValueWidget = mSkillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right);
skillValueWidget->setCaption(value); skillValueWidget->setCaption(value);
skillValueWidget->_setWidgetState(state); skillValueWidget->_setWidgetState(state);
skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
skillWidgets.push_back(skillNameWidget); mSkillWidgets.push_back(skillNameWidget);
skillWidgets.push_back(skillValueWidget); mSkillWidgets.push_back(skillValueWidget);
coord1.top += lineHeight; coord1.top += sLineHeight;
coord2.top += lineHeight; coord2.top += sLineHeight;
return skillValueWidget; return skillValueWidget;
} }
@ -284,20 +284,20 @@ void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyG
{ {
MyGUI::TextBox* skillNameWidget; MyGUI::TextBox* skillNameWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); skillNameWidget = mSkillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
skillNameWidget->setCaption(text); skillNameWidget->setCaption(text);
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
skillWidgets.push_back(skillNameWidget); mSkillWidgets.push_back(skillNameWidget);
coord1.top += lineHeight; coord1.top += sLineHeight;
coord2.top += lineHeight; coord2.top += sLineHeight;
} }
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)
{ {
// Add a line separator if there are items above // Add a line separator if there are items above
if (!skillWidgets.empty()) if (!mSkillWidgets.empty())
{ {
addSeparator(coord1, coord2); addSeparator(coord1, coord2);
} }
@ -312,7 +312,7 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId
continue; continue;
assert(skillId >= 0 && skillId < ESM::Skill::Length); assert(skillId >= 0 && skillId < ESM::Skill::Length);
const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId]; const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId];
const MWMechanics::Stat<float> &stat = skillValues.find(skillId)->second; const MWMechanics::Stat<float> &stat = mSkillValues.find(skillId)->second;
float base = stat.getBase(); float base = stat.getBase();
float modified = stat.getModified(); float modified = stat.getModified();
@ -325,44 +325,44 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId
for (int i=0; i<2; ++i) for (int i=0; i<2; ++i)
{ {
ToolTips::createSkillToolTip(skillWidgets[skillWidgets.size()-1-i], skillId); ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size()-1-i], skillId);
} }
skillWidgetMap[skillId] = widget; mSkillWidgetMap[skillId] = widget;
} }
} }
void ReviewDialog::updateSkillArea() void ReviewDialog::updateSkillArea()
{ {
for (std::vector<MyGUI::WidgetPtr>::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it) for (std::vector<MyGUI::WidgetPtr>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }
skillWidgets.clear(); mSkillWidgets.clear();
const int valueSize = 40; const int valueSize = 40;
MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18); MyGUI::IntCoord coord1(10, 0, mSkillClientWidget->getWidth() - (10 + valueSize), 18);
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height); MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
if (!majorSkills.empty()) if (!mMajorSkills.empty())
addSkills(majorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2); addSkills(mMajorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2);
if (!minorSkills.empty()) if (!mMinorSkills.empty())
addSkills(minorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2); addSkills(mMinorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2);
if (!miscSkills.empty()) if (!mMiscSkills.empty())
addSkills(miscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2); addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
clientHeight = coord1.top; mClientHeight = coord1.top;
updateScroller(); updateScroller();
} }
void ReviewDialog::updateScroller() void ReviewDialog::updateScroller()
{ {
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); mSkillScrollerWidget->setScrollRange(std::max(mClientHeight - mSkillClientWidget->getHeight(), 0));
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); mSkillScrollerWidget->setScrollPage(std::max(mSkillClientWidget->getHeight() - sLineHeight, 0));
if (clientHeight != 0) if (mClientHeight != 0)
skillScrollerWidget->setTrackSize( (skillAreaWidget->getHeight() / float(clientHeight)) * skillScrollerWidget->getLineSize() ); mSkillScrollerWidget->setTrackSize( (mSkillAreaWidget->getHeight() / float(mClientHeight)) * mSkillScrollerWidget->getLineSize() );
} }
// widget controls // widget controls
@ -399,12 +399,12 @@ void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender)
void ReviewDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel) void ReviewDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{ {
if (skillScrollerWidget->getScrollPosition() - _rel*0.3 < 0) if (mSkillScrollerWidget->getScrollPosition() - _rel*0.3 < 0)
skillScrollerWidget->setScrollPosition(0); mSkillScrollerWidget->setScrollPosition(0);
else if (skillScrollerWidget->getScrollPosition() - _rel*0.3 > skillScrollerWidget->getScrollRange()-1) else if (mSkillScrollerWidget->getScrollPosition() - _rel*0.3 > mSkillScrollerWidget->getScrollRange()-1)
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollRange()-1); mSkillScrollerWidget->setScrollPosition(mSkillScrollerWidget->getScrollRange()-1);
else else
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollPosition() - _rel*0.3); mSkillScrollerWidget->setScrollPosition(mSkillScrollerWidget->getScrollPosition() - _rel*0.3);
onScrollChangePosition(skillScrollerWidget, skillScrollerWidget->getScrollPosition()); onScrollChangePosition(mSkillScrollerWidget, mSkillScrollerWidget->getScrollPosition());
} }

View file

@ -82,23 +82,23 @@ namespace MWGui
void onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos); void onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos);
void onWindowResize(MyGUI::Window* window); void onWindowResize(MyGUI::Window* window);
static const int lineHeight; static const int sLineHeight;
MyGUI::TextBox *nameWidget, *raceWidget, *classWidget, *birthSignWidget; MyGUI::TextBox *mNameWidget, *mRaceWidget, *mClassWidget, *mBirthSignWidget;
MyGUI::WidgetPtr skillAreaWidget, skillClientWidget; MyGUI::WidgetPtr mSkillAreaWidget, mSkillClientWidget;
MyGUI::ScrollBar* skillScrollerWidget; MyGUI::ScrollBar* mSkillScrollerWidget;
int lastPos, clientHeight; int mLastPos, mClientHeight;
Widgets::MWDynamicStatPtr health, magicka, fatigue; Widgets::MWDynamicStatPtr mHealth, mMagicka, mFatigue;
std::map<int, Widgets::MWAttributePtr> attributeWidgets; std::map<int, Widgets::MWAttributePtr> mAttributeWidgets;
SkillList majorSkills, minorSkills, miscSkills; SkillList mMajorSkills, mMinorSkills, mMiscSkills;
std::map<int, MWMechanics::Stat<float> > skillValues; std::map<int, MWMechanics::Stat<float> > mSkillValues;
std::map<int, MyGUI::TextBox*> skillWidgetMap; std::map<int, MyGUI::TextBox*> mSkillWidgetMap;
std::string name, raceId, birthSignId; std::string mName, mRaceId, mBirthSignId;
ESM::Class klass; ESM::Class mKlass;
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information std::vector<MyGUI::WidgetPtr> mSkillWidgets; //< Skills and other information
}; };
} }
#endif #endif

View file

@ -19,26 +19,26 @@
using namespace MWGui; using namespace MWGui;
const int StatsWindow::lineHeight = 18; const int StatsWindow::sLineHeight = 18;
StatsWindow::StatsWindow (WindowManager& parWindowManager) StatsWindow::StatsWindow (WindowManager& parWindowManager)
: WindowPinnableBase("openmw_stats_window.layout", parWindowManager) : WindowPinnableBase("openmw_stats_window.layout", parWindowManager)
, skillAreaWidget(NULL) , mSkillAreaWidget(NULL)
, skillClientWidget(NULL) , mSkillClientWidget(NULL)
, skillScrollerWidget(NULL) , mSkillScrollerWidget(NULL)
, lastPos(0) , mLastPos(0)
, clientHeight(0) , mClientHeight(0)
, majorSkills() , mMajorSkills()
, minorSkills() , mMinorSkills()
, miscSkills() , mMiscSkills()
, skillValues() , mSkillValues()
, skillWidgetMap() , mSkillWidgetMap()
, factionWidgetMap() , mFactionWidgetMap()
, mFactions() , mFactions()
, birthSignId() , mBirthSignId()
, reputation(0) , mReputation(0)
, bounty(0) , mBounty(0)
, skillWidgets() , mSkillWidgets()
, mChanged(true) , mChanged(true)
{ {
setCoord(0,0,498, 342); setCoord(0,0,498, 342);
@ -62,21 +62,21 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
setText (names[i][0], store.gameSettings.find (names[i][1])->str); setText (names[i][0], store.gameSettings.find (names[i][1])->str);
} }
getWidget(skillAreaWidget, "Skills"); getWidget(mSkillAreaWidget, "Skills");
getWidget(skillClientWidget, "SkillClient"); getWidget(mSkillClientWidget, "SkillClient");
getWidget(skillScrollerWidget, "SkillScroller"); getWidget(mSkillScrollerWidget, "SkillScroller");
getWidget(mLeftPane, "LeftPane"); getWidget(mLeftPane, "LeftPane");
getWidget(mRightPane, "RightPane"); getWidget(mRightPane, "RightPane");
skillClientWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); mSkillClientWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
skillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &StatsWindow::onScrollChangePosition); mSkillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &StatsWindow::onScrollChangePosition);
updateScroller(); updateScroller();
for (int i = 0; i < ESM::Skill::Length; ++i) for (int i = 0; i < ESM::Skill::Length; ++i)
{ {
skillValues.insert(std::pair<int, MWMechanics::Stat<float> >(i, MWMechanics::Stat<float>())); mSkillValues.insert(std::pair<int, MWMechanics::Stat<float> >(i, MWMechanics::Stat<float>()));
skillWidgetMap.insert(std::pair<int, MyGUI::TextBox*>(i, nullptr)); mSkillWidgetMap.insert(std::pair<int, MyGUI::TextBox*>(i, nullptr));
} }
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget); MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget);
@ -85,14 +85,14 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos) void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos)
{ {
int diff = lastPos - pos; int diff = mLastPos - pos;
// Adjust position of all widget according to difference // Adjust position of all widget according to difference
if (diff == 0) if (diff == 0)
return; return;
lastPos = pos; mLastPos = pos;
std::vector<MyGUI::WidgetPtr>::const_iterator end = skillWidgets.end(); std::vector<MyGUI::WidgetPtr>::const_iterator end = mSkillWidgets.end();
for (std::vector<MyGUI::WidgetPtr>::const_iterator it = skillWidgets.begin(); it != end; ++it) for (std::vector<MyGUI::WidgetPtr>::const_iterator it = mSkillWidgets.begin(); it != end; ++it)
{ {
(*it)->setCoord((*it)->getCoord() + MyGUI::IntPoint(0, diff)); (*it)->setCoord((*it)->getCoord() + MyGUI::IntPoint(0, diff));
} }
@ -100,14 +100,14 @@ void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos)
void StatsWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) void StatsWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{ {
if (skillScrollerWidget->getScrollPosition() - _rel*0.3 < 0) if (mSkillScrollerWidget->getScrollPosition() - _rel*0.3 < 0)
skillScrollerWidget->setScrollPosition(0); mSkillScrollerWidget->setScrollPosition(0);
else if (skillScrollerWidget->getScrollPosition() - _rel*0.3 > skillScrollerWidget->getScrollRange()-1) else if (mSkillScrollerWidget->getScrollPosition() - _rel*0.3 > mSkillScrollerWidget->getScrollRange()-1)
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollRange()-1); mSkillScrollerWidget->setScrollPosition(mSkillScrollerWidget->getScrollRange()-1);
else else
skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollPosition() - _rel*0.3); mSkillScrollerWidget->setScrollPosition(mSkillScrollerWidget->getScrollPosition() - _rel*0.3);
onScrollChangePosition(skillScrollerWidget, skillScrollerWidget->getScrollPosition()); onScrollChangePosition(mSkillScrollerWidget, mSkillScrollerWidget->getScrollPosition());
} }
void StatsWindow::onWindowResize(MyGUI::Window* window) void StatsWindow::onWindowResize(MyGUI::Window* window)
@ -224,8 +224,8 @@ void StatsWindow::setValue (const std::string& id, int value)
void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value) void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
{ {
skillValues[parSkill] = value; mSkillValues[parSkill] = value;
MyGUI::TextBox* widget = skillWidgetMap[(int)parSkill]; MyGUI::TextBox* widget = mSkillWidgetMap[(int)parSkill];
if (widget) if (widget)
{ {
float modified = value.getModified(), base = value.getBase(); float modified = value.getModified(), base = value.getBase();
@ -243,20 +243,20 @@ void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechani
void StatsWindow::configureSkills (const std::vector<int>& major, const std::vector<int>& minor) void StatsWindow::configureSkills (const std::vector<int>& major, const std::vector<int>& minor)
{ {
majorSkills = major; mMajorSkills = major;
minorSkills = minor; mMinorSkills = minor;
// Update misc skills with the remaining skills not in major or minor // Update misc skills with the remaining skills not in major or minor
std::set<int> skillSet; std::set<int> skillSet;
std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin())); std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin()));
std::copy(minor.begin(), minor.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(); boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator end = ESM::Skill::skillIds.end();
miscSkills.clear(); mMiscSkills.clear();
for (boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator it = ESM::Skill::skillIds.begin(); it != end; ++it) for (boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator it = ESM::Skill::skillIds.begin(); it != end; ++it)
{ {
int skill = *it; int skill = *it;
if (skillSet.find(skill) == skillSet.end()) if (skillSet.find(skill) == skillSet.end())
miscSkills.push_back(skill); mMiscSkills.push_back(skill);
} }
updateSkillArea(); updateSkillArea();
@ -289,20 +289,20 @@ void StatsWindow::setFactions (const FactionList& factions)
void StatsWindow::setBirthSign (const std::string& signId) void StatsWindow::setBirthSign (const std::string& signId)
{ {
if (signId != birthSignId) if (signId != mBirthSignId)
{ {
birthSignId = signId; mBirthSignId = signId;
mChanged = true; mChanged = true;
} }
} }
void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{ {
MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::ImageBox* separator = mSkillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine",
MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18),
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch); MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
separator->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); separator->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
skillWidgets.push_back(separator); mSkillWidgets.push_back(separator);
coord1.top += separator->getHeight(); coord1.top += separator->getHeight();
coord2.top += separator->getHeight(); coord2.top += separator->getHeight();
@ -310,35 +310,35 @@ void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{ {
MyGUI::TextBox* groupWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::TextBox* groupWidget = mSkillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText",
MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height),
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch); MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
groupWidget->setCaption(label); groupWidget->setCaption(label);
groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
skillWidgets.push_back(groupWidget); mSkillWidgets.push_back(groupWidget);
coord1.top += lineHeight; coord1.top += sLineHeight;
coord2.top += lineHeight; coord2.top += sLineHeight;
} }
MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{ {
MyGUI::TextBox *skillNameWidget, *skillValueWidget; MyGUI::TextBox *skillNameWidget, *skillValueWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch); skillNameWidget = mSkillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
skillNameWidget->setCaption(text); skillNameWidget->setCaption(text);
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Right | MyGUI::Align::Top); skillValueWidget = mSkillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Right | MyGUI::Align::Top);
skillValueWidget->setCaption(value); skillValueWidget->setCaption(value);
skillValueWidget->_setWidgetState(state); skillValueWidget->_setWidgetState(state);
skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
skillWidgets.push_back(skillNameWidget); mSkillWidgets.push_back(skillNameWidget);
skillWidgets.push_back(skillValueWidget); mSkillWidgets.push_back(skillValueWidget);
coord1.top += lineHeight; coord1.top += sLineHeight;
coord2.top += lineHeight; coord2.top += sLineHeight;
return skillValueWidget; return skillValueWidget;
} }
@ -347,14 +347,14 @@ MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &co
{ {
MyGUI::TextBox* skillNameWidget; MyGUI::TextBox* skillNameWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); skillNameWidget = mSkillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
skillNameWidget->setCaption(text); skillNameWidget->setCaption(text);
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
skillWidgets.push_back(skillNameWidget); mSkillWidgets.push_back(skillNameWidget);
coord1.top += lineHeight; coord1.top += sLineHeight;
coord2.top += lineHeight; coord2.top += sLineHeight;
return skillNameWidget; return skillNameWidget;
} }
@ -362,7 +362,7 @@ MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &co
void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) 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 // Add a line separator if there are items above
if (!skillWidgets.empty()) if (!mSkillWidgets.empty())
{ {
addSeparator(coord1, coord2); addSeparator(coord1, coord2);
} }
@ -377,7 +377,7 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId,
continue; continue;
assert(skillId >= 0 && skillId < ESM::Skill::Length); assert(skillId >= 0 && skillId < ESM::Skill::Length);
const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId]; const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId];
const MWMechanics::Stat<float> &stat = skillValues.find(skillId)->second; const MWMechanics::Stat<float> &stat = mSkillValues.find(skillId)->second;
float base = stat.getBase(); float base = stat.getBase();
float modified = stat.getModified(); float modified = stat.getModified();
int progressPercent = (modified - float(static_cast<int>(modified))) * 100; int progressPercent = (modified - float(static_cast<int>(modified))) * 100;
@ -400,18 +400,18 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId,
for (int i=0; i<2; ++i) for (int i=0; i<2; ++i)
{ {
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "SkillToolTip"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipLayout", "SkillToolTip");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillName", "#{"+skillNameId+"}"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillName", "#{"+skillNameId+"}");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillDescription", skill->description); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillDescription", skill->description);
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillAttribute", "#{sGoverningAttribute}: #{" + attr->name + "}"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillAttribute", "#{sGoverningAttribute}: #{" + attr->name + "}");
skillWidgets[skillWidgets.size()-1-i]->setUserString("ImageTexture_SkillImage", icon); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ImageTexture_SkillImage", icon);
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillProgressText", boost::lexical_cast<std::string>(progressPercent)+"/100"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillProgressText", boost::lexical_cast<std::string>(progressPercent)+"/100");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Range_SkillProgress", "100"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Range_SkillProgress", "100");
skillWidgets[skillWidgets.size()-1-i]->setUserString("RangePosition_SkillProgress", boost::lexical_cast<std::string>(progressPercent)); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("RangePosition_SkillProgress", boost::lexical_cast<std::string>(progressPercent));
} }
skillWidgetMap[skillId] = widget; mSkillWidgetMap[skillId] = widget;
} }
} }
@ -419,28 +419,28 @@ void StatsWindow::updateSkillArea()
{ {
mChanged = false; mChanged = false;
for (std::vector<MyGUI::WidgetPtr>::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it) for (std::vector<MyGUI::WidgetPtr>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }
skillWidgets.clear(); mSkillWidgets.clear();
skillScrollerWidget->setScrollPosition(0); mSkillScrollerWidget->setScrollPosition(0);
onScrollChangePosition(skillScrollerWidget, 0); onScrollChangePosition(mSkillScrollerWidget, 0);
clientHeight = 0; mClientHeight = 0;
const int valueSize = 40; const int valueSize = 40;
MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18); MyGUI::IntCoord coord1(10, 0, mSkillClientWidget->getWidth() - (10 + valueSize), 18);
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height); MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
if (!majorSkills.empty()) if (!mMajorSkills.empty())
addSkills(majorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2); addSkills(mMajorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2);
if (!minorSkills.empty()) if (!mMinorSkills.empty())
addSkills(minorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2); addSkills(mMinorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2);
if (!miscSkills.empty()) if (!mMiscSkills.empty())
addSkills(miscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2); addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
const ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
@ -463,7 +463,7 @@ void StatsWindow::updateSkillArea()
if (!mFactions.empty()) if (!mFactions.empty())
{ {
// Add a line separator if there are items above // Add a line separator if there are items above
if (!skillWidgets.empty()) if (!mSkillWidgets.empty())
addSeparator(coord1, coord2); addSeparator(coord1, coord2);
addGroup(mWindowManager.getGameSettingString("sFaction", "Faction"), coord1, coord2); addGroup(mWindowManager.getGameSettingString("sFaction", "Faction"), coord1, coord2);
@ -516,53 +516,53 @@ void StatsWindow::updateSkillArea()
} }
} }
if (!birthSignId.empty()) if (!mBirthSignId.empty())
{ {
// Add a line separator if there are items above // Add a line separator if there are items above
if (!skillWidgets.empty()) if (!mSkillWidgets.empty())
addSeparator(coord1, coord2); addSeparator(coord1, coord2);
addGroup(mWindowManager.getGameSettingString("sBirthSign", "Sign"), coord1, coord2); addGroup(mWindowManager.getGameSettingString("sBirthSign", "Sign"), coord1, coord2);
const ESM::BirthSign *sign = store.birthSigns.find(birthSignId); const ESM::BirthSign *sign = store.birthSigns.find(mBirthSignId);
MyGUI::Widget* w = addItem(sign->name, coord1, coord2); MyGUI::Widget* w = addItem(sign->name, coord1, coord2);
ToolTips::createBirthsignToolTip(w, birthSignId); ToolTips::createBirthsignToolTip(w, mBirthSignId);
} }
// Add a line separator if there are items above // Add a line separator if there are items above
if (!skillWidgets.empty()) if (!mSkillWidgets.empty())
addSeparator(coord1, coord2); addSeparator(coord1, coord2);
addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"), addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"),
boost::lexical_cast<std::string>(static_cast<int>(reputation)), "normal", coord1, coord2); boost::lexical_cast<std::string>(static_cast<int>(mReputation)), "normal", coord1, coord2);
for (int i=0; i<2; ++i) for (int i=0; i<2; ++i)
{ {
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sSkillsMenuReputationHelp}"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sSkillsMenuReputationHelp}");
} }
addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"), addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"),
boost::lexical_cast<std::string>(static_cast<int>(bounty)), "normal", coord1, coord2); boost::lexical_cast<std::string>(static_cast<int>(mBounty)), "normal", coord1, coord2);
for (int i=0; i<2; ++i) for (int i=0; i<2; ++i)
{ {
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sCrimeHelp}"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sCrimeHelp}");
} }
clientHeight = coord1.top; mClientHeight = coord1.top;
updateScroller(); updateScroller();
} }
void StatsWindow::updateScroller() void StatsWindow::updateScroller()
{ {
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); mSkillScrollerWidget->setScrollRange(std::max(mClientHeight - mSkillClientWidget->getHeight(), 0));
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); mSkillScrollerWidget->setScrollPage(std::max(mSkillClientWidget->getHeight() - sLineHeight, 0));
if (clientHeight != 0) if (mClientHeight != 0)
skillScrollerWidget->setTrackSize( (skillAreaWidget->getHeight() / float(clientHeight)) * skillScrollerWidget->getLineSize() ); mSkillScrollerWidget->setTrackSize( (mSkillAreaWidget->getHeight() / float(mClientHeight)) * mSkillScrollerWidget->getLineSize() );
} }
void StatsWindow::onPinToggled() void StatsWindow::onPinToggled()

View file

@ -38,8 +38,8 @@ namespace MWGui
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value); void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
void configureSkills (const SkillList& major, const SkillList& minor); void configureSkills (const SkillList& major, const SkillList& minor);
void setReputation (int reputation) { this->reputation = reputation; } void setReputation (int reputation) { this->mReputation = reputation; }
void setBounty (int bounty) { this->bounty = bounty; } void setBounty (int bounty) { this->mBounty = bounty; }
void updateSkillArea(); void updateSkillArea();
private: private:
@ -57,23 +57,23 @@ namespace MWGui
void onWindowResize(MyGUI::Window* window); void onWindowResize(MyGUI::Window* window);
void onMouseWheel(MyGUI::Widget* _sender, int _rel); void onMouseWheel(MyGUI::Widget* _sender, int _rel);
static const int lineHeight; static const int sLineHeight;
MyGUI::Widget* mLeftPane; MyGUI::Widget* mLeftPane;
MyGUI::Widget* mRightPane; MyGUI::Widget* mRightPane;
MyGUI::WidgetPtr skillAreaWidget, skillClientWidget; MyGUI::WidgetPtr mSkillAreaWidget, mSkillClientWidget;
MyGUI::ScrollBar* skillScrollerWidget; MyGUI::ScrollBar* mSkillScrollerWidget;
int lastPos, clientHeight; int mLastPos, mClientHeight;
SkillList majorSkills, minorSkills, miscSkills; SkillList mMajorSkills, mMinorSkills, mMiscSkills;
std::map<int, MWMechanics::Stat<float> > skillValues; std::map<int, MWMechanics::Stat<float> > mSkillValues;
std::map<int, MyGUI::TextBox*> skillWidgetMap; std::map<int, MyGUI::TextBox*> mSkillWidgetMap;
std::map<std::string, MyGUI::WidgetPtr> factionWidgetMap; std::map<std::string, MyGUI::WidgetPtr> mFactionWidgetMap;
FactionList mFactions; ///< Stores a list of factions and the current rank FactionList mFactions; ///< Stores a list of factions and the current rank
std::string birthSignId; std::string mBirthSignId;
int reputation, bounty; int mReputation, mBounty;
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information std::vector<MyGUI::WidgetPtr> mSkillWidgets; //< Skills and other information
bool mChanged; bool mChanged;

View file

@ -9,15 +9,15 @@ TextInputDialog::TextInputDialog(WindowManager& parWindowManager)
// Centre dialog // Centre dialog
center(); center();
getWidget(textEdit, "TextEdit"); getWidget(mTextEdit, "TextEdit");
textEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted); mTextEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted);
MyGUI::ButtonPtr okButton; MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked);
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
} }
void TextInputDialog::setNextButtonShow(bool shown) void TextInputDialog::setNextButtonShow(bool shown)
@ -43,7 +43,7 @@ void TextInputDialog::setTextLabel(const std::string &label)
void TextInputDialog::open() void TextInputDialog::open()
{ {
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
setVisible(true); setVisible(true);
} }

View file

@ -20,8 +20,8 @@ namespace MWGui
public: public:
TextInputDialog(WindowManager& parWindowManager); TextInputDialog(WindowManager& parWindowManager);
std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; } std::string getTextInput() const { return mTextEdit ? mTextEdit->getOnlyText() : ""; }
void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); } void setTextInput(const std::string &text) { if (mTextEdit) mTextEdit->setOnlyText(text); }
void setNextButtonShow(bool shown); void setNextButtonShow(bool shown);
void setTextLabel(const std::string &label); void setTextLabel(const std::string &label);
@ -32,7 +32,7 @@ namespace MWGui
void onTextAccepted(MyGUI::Edit* _sender); void onTextAccepted(MyGUI::Edit* _sender);
private: private:
MyGUI::EditPtr textEdit; MyGUI::EditPtr mTextEdit;
}; };
} }
#endif #endif

View file

@ -27,16 +27,16 @@ void MWGui::Widgets::fixTexturePath(std::string &path)
/* MWSkill */ /* MWSkill */
MWSkill::MWSkill() MWSkill::MWSkill()
: manager(nullptr) : mManager(nullptr)
, skillId(ESM::Skill::Length) , mSkillId(ESM::Skill::Length)
, skillNameWidget(nullptr) , mSkillNameWidget(nullptr)
, skillValueWidget(nullptr) , mSkillValueWidget(nullptr)
{ {
} }
void MWSkill::setSkillId(ESM::Skill::SkillEnum skill) void MWSkill::setSkillId(ESM::Skill::SkillEnum skill)
{ {
skillId = skill; mSkillId = skill;
updateWidgets(); updateWidgets();
} }
@ -50,36 +50,36 @@ void MWSkill::setSkillNumber(int skill)
throw new std::runtime_error("Skill number out of range"); throw new std::runtime_error("Skill number out of range");
} }
void MWSkill::setSkillValue(const SkillValue& value_) void MWSkill::setSkillValue(const SkillValue& value)
{ {
value = value_; mValue = value;
updateWidgets(); updateWidgets();
} }
void MWSkill::updateWidgets() void MWSkill::updateWidgets()
{ {
if (skillNameWidget && manager) if (mSkillNameWidget && mManager)
{ {
if (skillId == ESM::Skill::Length) if (mSkillId == ESM::Skill::Length)
{ {
static_cast<MyGUI::TextBox*>(skillNameWidget)->setCaption(""); static_cast<MyGUI::TextBox*>(mSkillNameWidget)->setCaption("");
} }
else else
{ {
const std::string &name = manager->getGameSettingString(ESM::Skill::sSkillNameIds[skillId], ""); const std::string &name = mManager->getGameSettingString(ESM::Skill::sSkillNameIds[mSkillId], "");
static_cast<MyGUI::TextBox*>(skillNameWidget)->setCaption(name); static_cast<MyGUI::TextBox*>(mSkillNameWidget)->setCaption(name);
} }
} }
if (skillValueWidget) if (mSkillValueWidget)
{ {
SkillValue::Type modified = value.getModified(), base = value.getBase(); SkillValue::Type modified = mValue.getModified(), base = mValue.getBase();
static_cast<MyGUI::TextBox*>(skillValueWidget)->setCaption(boost::lexical_cast<std::string>(modified)); static_cast<MyGUI::TextBox*>(mSkillValueWidget)->setCaption(boost::lexical_cast<std::string>(modified));
if (modified > base) if (modified > base)
skillValueWidget->_setWidgetState("increased"); mSkillValueWidget->_setWidgetState("increased");
else if (modified < base) else if (modified < base)
skillValueWidget->_setWidgetState("decreased"); mSkillValueWidget->_setWidgetState("decreased");
else else
skillValueWidget->_setWidgetState("normal"); mSkillValueWidget->_setWidgetState("normal");
} }
} }
@ -96,14 +96,14 @@ void MWSkill::initialiseOverride()
{ {
Base::initialiseOverride(); Base::initialiseOverride();
assignWidget(skillNameWidget, "StatName"); assignWidget(mSkillNameWidget, "StatName");
assignWidget(skillValueWidget, "StatValue"); assignWidget(mSkillValueWidget, "StatValue");
MyGUI::ButtonPtr button; MyGUI::ButtonPtr button;
assignWidget(button, "StatNameButton"); assignWidget(button, "StatNameButton");
if (button) if (button)
{ {
skillNameWidget = button; mSkillNameWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked); button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked);
} }
@ -111,7 +111,7 @@ void MWSkill::initialiseOverride()
assignWidget(button, "StatValueButton"); assignWidget(button, "StatValueButton");
if (button) if (button)
{ {
skillNameWidget = button; mSkillNameWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked); button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked);
} }
} }
@ -119,22 +119,22 @@ void MWSkill::initialiseOverride()
/* MWAttribute */ /* MWAttribute */
MWAttribute::MWAttribute() MWAttribute::MWAttribute()
: manager(nullptr) : mManager(nullptr)
, id(-1) , mId(-1)
, attributeNameWidget(nullptr) , mAttributeNameWidget(nullptr)
, attributeValueWidget(nullptr) , mAttributeValueWidget(nullptr)
{ {
} }
void MWAttribute::setAttributeId(int attributeId) void MWAttribute::setAttributeId(int attributeId)
{ {
id = attributeId; mId = attributeId;
updateWidgets(); updateWidgets();
} }
void MWAttribute::setAttributeValue(const AttributeValue& value_) void MWAttribute::setAttributeValue(const AttributeValue& value)
{ {
value = value_; mValue = value;
updateWidgets(); updateWidgets();
} }
@ -145,11 +145,11 @@ void MWAttribute::onClicked(MyGUI::Widget* _sender)
void MWAttribute::updateWidgets() void MWAttribute::updateWidgets()
{ {
if (attributeNameWidget && manager) if (mAttributeNameWidget && mManager)
{ {
if (id < 0 || id >= 8) if (mId < 0 || mId >= 8)
{ {
static_cast<MyGUI::TextBox*>(attributeNameWidget)->setCaption(""); static_cast<MyGUI::TextBox*>(mAttributeNameWidget)->setCaption("");
} }
else else
{ {
@ -163,20 +163,20 @@ void MWAttribute::updateWidgets()
"sAttributePersonality", "sAttributePersonality",
"sAttributeLuck" "sAttributeLuck"
}; };
const std::string &name = manager->getGameSettingString(attributes[id], ""); const std::string &name = mManager->getGameSettingString(attributes[mId], "");
static_cast<MyGUI::TextBox*>(attributeNameWidget)->setCaption(name); static_cast<MyGUI::TextBox*>(mAttributeNameWidget)->setCaption(name);
} }
} }
if (attributeValueWidget) if (mAttributeValueWidget)
{ {
AttributeValue::Type modified = value.getModified(), base = value.getBase(); AttributeValue::Type modified = mValue.getModified(), base = mValue.getBase();
static_cast<MyGUI::TextBox*>(attributeValueWidget)->setCaption(boost::lexical_cast<std::string>(modified)); static_cast<MyGUI::TextBox*>(mAttributeValueWidget)->setCaption(boost::lexical_cast<std::string>(modified));
if (modified > base) if (modified > base)
attributeValueWidget->_setWidgetState("increased"); mAttributeValueWidget->_setWidgetState("increased");
else if (modified < base) else if (modified < base)
attributeValueWidget->_setWidgetState("decreased"); mAttributeValueWidget->_setWidgetState("decreased");
else else
attributeValueWidget->_setWidgetState("normal"); mAttributeValueWidget->_setWidgetState("normal");
} }
} }
@ -188,14 +188,14 @@ void MWAttribute::initialiseOverride()
{ {
Base::initialiseOverride(); Base::initialiseOverride();
assignWidget(attributeNameWidget, "StatName"); assignWidget(mAttributeNameWidget, "StatName");
assignWidget(attributeValueWidget, "StatValue"); assignWidget(mAttributeValueWidget, "StatValue");
MyGUI::ButtonPtr button; MyGUI::ButtonPtr button;
assignWidget(button, "StatNameButton"); assignWidget(button, "StatNameButton");
if (button) if (button)
{ {
attributeNameWidget = button; mAttributeNameWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked); button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked);
} }
@ -203,7 +203,7 @@ void MWAttribute::initialiseOverride()
assignWidget(button, "StatValueButton"); assignWidget(button, "StatValueButton");
if (button) if (button)
{ {
attributeValueWidget = button; mAttributeValueWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked); button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked);
} }
} }
@ -212,21 +212,21 @@ void MWAttribute::initialiseOverride()
MWSpell::MWSpell() MWSpell::MWSpell()
: mWindowManager(nullptr) : mWindowManager(nullptr)
, spellNameWidget(nullptr) , mSpellNameWidget(nullptr)
{ {
} }
void MWSpell::setSpellId(const std::string &spellId) void MWSpell::setSpellId(const std::string &spellId)
{ {
id = spellId; mId = spellId;
updateWidgets(); updateWidgets();
} }
void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags) void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags)
{ {
const ESMS::ESMStore &store = mWindowManager->getStore(); const ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::Spell *spell = store.spells.search(id); const ESM::Spell *spell = store.spells.search(mId);
MYGUI_ASSERT(spell, "spell with id '" << id << "' not found"); MYGUI_ASSERT(spell, "spell with id '" << mId << "' not found");
MWSpellEffectPtr effect = nullptr; MWSpellEffectPtr effect = nullptr;
std::vector<ESM::ENAMstruct>::const_iterator end = spell->effects.list.end(); std::vector<ESM::ENAMstruct>::const_iterator end = spell->effects.list.end();
@ -253,14 +253,14 @@ void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI:
void MWSpell::updateWidgets() void MWSpell::updateWidgets()
{ {
if (spellNameWidget && mWindowManager) if (mSpellNameWidget && mWindowManager)
{ {
const ESMS::ESMStore &store = mWindowManager->getStore(); const ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::Spell *spell = store.spells.search(id); const ESM::Spell *spell = store.spells.search(mId);
if (spell) if (spell)
static_cast<MyGUI::TextBox*>(spellNameWidget)->setCaption(spell->name); static_cast<MyGUI::TextBox*>(mSpellNameWidget)->setCaption(spell->name);
else else
static_cast<MyGUI::TextBox*>(spellNameWidget)->setCaption(""); static_cast<MyGUI::TextBox*>(mSpellNameWidget)->setCaption("");
} }
} }
@ -268,7 +268,7 @@ void MWSpell::initialiseOverride()
{ {
Base::initialiseOverride(); Base::initialiseOverride();
assignWidget(spellNameWidget, "StatName"); assignWidget(mSpellNameWidget, "StatName");
} }
MWSpell::~MWSpell() MWSpell::~MWSpell()
@ -367,8 +367,8 @@ SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects)
MWSpellEffect::MWSpellEffect() MWSpellEffect::MWSpellEffect()
: mWindowManager(nullptr) : mWindowManager(nullptr)
, imageWidget(nullptr) , mImageWidget(nullptr)
, textWidget(nullptr) , mTextWidget(nullptr)
, mRequestedWidth(0) , mRequestedWidth(0)
{ {
} }
@ -388,7 +388,7 @@ void MWSpellEffect::updateWidgets()
const ESM::MagicEffect *magicEffect = store.magicEffects.search(mEffectParams.mEffectID); const ESM::MagicEffect *magicEffect = store.magicEffects.search(mEffectParams.mEffectID);
if (!magicEffect) if (!magicEffect)
return; return;
if (textWidget) if (mTextWidget)
{ {
std::string pt = mWindowManager->getGameSettingString("spoint", ""); std::string pt = mWindowManager->getGameSettingString("spoint", "");
std::string pts = mWindowManager->getGameSettingString("spoints", ""); std::string pts = mWindowManager->getGameSettingString("spoints", "");
@ -448,14 +448,14 @@ void MWSpellEffect::updateWidgets()
} }
} }
static_cast<MyGUI::TextBox*>(textWidget)->setCaption(spellLine); static_cast<MyGUI::TextBox*>(mTextWidget)->setCaption(spellLine);
mRequestedWidth = textWidget->getTextSize().width + 24; mRequestedWidth = mTextWidget->getTextSize().width + 24;
} }
if (imageWidget) if (mImageWidget)
{ {
std::string path = std::string("icons\\") + magicEffect->icon; std::string path = std::string("icons\\") + magicEffect->icon;
fixTexturePath(path); fixTexturePath(path);
imageWidget->setImageTexture(path); mImageWidget->setImageTexture(path);
} }
} }
@ -728,49 +728,49 @@ void MWSpellEffect::initialiseOverride()
{ {
Base::initialiseOverride(); Base::initialiseOverride();
assignWidget(textWidget, "Text"); assignWidget(mTextWidget, "Text");
assignWidget(imageWidget, "Image"); assignWidget(mImageWidget, "Image");
} }
/* MWDynamicStat */ /* MWDynamicStat */
MWDynamicStat::MWDynamicStat() MWDynamicStat::MWDynamicStat()
: value(0) : mValue(0)
, max(1) , mMax(1)
, textWidget(nullptr) , mTextWidget(nullptr)
, barWidget(nullptr) , mBarWidget(nullptr)
, barTextWidget(nullptr) , mBarTextWidget(nullptr)
{ {
} }
void MWDynamicStat::setValue(int cur, int max_) void MWDynamicStat::setValue(int cur, int max)
{ {
value = cur; mValue = cur;
max = max_; mMax = max;
if (barWidget) if (mBarWidget)
{ {
barWidget->setProgressRange(max); mBarWidget->setProgressRange(mMax);
barWidget->setProgressPosition(value); mBarWidget->setProgressPosition(mValue);
} }
if (barTextWidget) if (mBarTextWidget)
{ {
if (value >= 0 && max > 0) if (mValue >= 0 && mMax > 0)
{ {
std::stringstream out; std::stringstream out;
out << value << "/" << max; out << mValue << "/" << mMax;
static_cast<MyGUI::TextBox*>(barTextWidget)->setCaption(out.str().c_str()); static_cast<MyGUI::TextBox*>(mBarTextWidget)->setCaption(out.str().c_str());
} }
else else
static_cast<MyGUI::TextBox*>(barTextWidget)->setCaption(""); static_cast<MyGUI::TextBox*>(mBarTextWidget)->setCaption("");
} }
} }
void MWDynamicStat::setTitle(const std::string& text) void MWDynamicStat::setTitle(const std::string& text)
{ {
if (textWidget) if (mTextWidget)
static_cast<MyGUI::TextBox*>(textWidget)->setCaption(text); static_cast<MyGUI::TextBox*>(mTextWidget)->setCaption(text);
} }
MWDynamicStat::~MWDynamicStat() MWDynamicStat::~MWDynamicStat()
@ -781,7 +781,7 @@ void MWDynamicStat::initialiseOverride()
{ {
Base::initialiseOverride(); Base::initialiseOverride();
assignWidget(textWidget, "Text"); assignWidget(mTextWidget, "Text");
assignWidget(barWidget, "Bar"); assignWidget(mBarWidget, "Bar");
assignWidget(barTextWidget, "BarText"); assignWidget(mBarTextWidget, "BarText");
} }

View file

@ -73,7 +73,7 @@ namespace MWGui
typedef std::vector<SpellEffectParams> SpellEffectList; typedef std::vector<SpellEffectParams> SpellEffectList;
class MYGUI_EXPORT MWSkill : public Widget class MYGUI_EXPORT MWSkill : public MyGUI::Widget
{ {
MYGUI_RTTI_DERIVED( MWSkill ); MYGUI_RTTI_DERIVED( MWSkill );
public: public:
@ -81,14 +81,14 @@ namespace MWGui
typedef MWMechanics::Stat<float> SkillValue; typedef MWMechanics::Stat<float> SkillValue;
void setWindowManager(WindowManager *m) { manager = m; } void setWindowManager(WindowManager *m) { mManager = m; }
void setSkillId(ESM::Skill::SkillEnum skillId); void setSkillId(ESM::Skill::SkillEnum skillId);
void setSkillNumber(int skillId); void setSkillNumber(int skillId);
void setSkillValue(const SkillValue& value); void setSkillValue(const SkillValue& value);
WindowManager *getWindowManager() const { return manager; } WindowManager *getWindowManager() const { return mManager; }
ESM::Skill::SkillEnum getSkillId() const { return skillId; } ESM::Skill::SkillEnum getSkillId() const { return mSkillId; }
const SkillValue& getSkillValue() const { return value; } const SkillValue& getSkillValue() const { return mValue; }
// Events // Events
typedef delegates::CMultiDelegate1<MWSkill*> EventHandle_SkillVoid; typedef delegates::CMultiDelegate1<MWSkill*> EventHandle_SkillVoid;
@ -109,14 +109,14 @@ namespace MWGui
void updateWidgets(); void updateWidgets();
WindowManager *manager; WindowManager *mManager;
ESM::Skill::SkillEnum skillId; ESM::Skill::SkillEnum mSkillId;
SkillValue value; SkillValue mValue;
MyGUI::WidgetPtr skillNameWidget, skillValueWidget; MyGUI::WidgetPtr mSkillNameWidget, mSkillValueWidget;
}; };
typedef MWSkill* MWSkillPtr; typedef MWSkill* MWSkillPtr;
class MYGUI_EXPORT MWAttribute : public Widget class MYGUI_EXPORT MWAttribute : public MyGUI::Widget
{ {
MYGUI_RTTI_DERIVED( MWAttribute ); MYGUI_RTTI_DERIVED( MWAttribute );
public: public:
@ -124,13 +124,13 @@ namespace MWGui
typedef MWMechanics::Stat<int> AttributeValue; typedef MWMechanics::Stat<int> AttributeValue;
void setWindowManager(WindowManager *m) { manager = m; } void setWindowManager(WindowManager *m) { mManager = m; }
void setAttributeId(int attributeId); void setAttributeId(int attributeId);
void setAttributeValue(const AttributeValue& value); void setAttributeValue(const AttributeValue& value);
WindowManager *getWindowManager() const { return manager; } WindowManager *getWindowManager() const { return mManager; }
int getAttributeId() const { return id; } int getAttributeId() const { return mId; }
const AttributeValue& getAttributeValue() const { return value; } const AttributeValue& getAttributeValue() const { return mValue; }
// Events // Events
typedef delegates::CMultiDelegate1<MWAttribute*> EventHandle_AttributeVoid; typedef delegates::CMultiDelegate1<MWAttribute*> EventHandle_AttributeVoid;
@ -151,10 +151,10 @@ namespace MWGui
void updateWidgets(); void updateWidgets();
WindowManager *manager; WindowManager *mManager;
int id; int mId;
AttributeValue value; AttributeValue mValue;
MyGUI::WidgetPtr attributeNameWidget, attributeValueWidget; MyGUI::WidgetPtr mAttributeNameWidget, mAttributeValueWidget;
}; };
typedef MWAttribute* MWAttributePtr; typedef MWAttribute* MWAttributePtr;
@ -162,7 +162,7 @@ namespace MWGui
* @todo remove this class and use MWEffectList instead * @todo remove this class and use MWEffectList instead
*/ */
class MWSpellEffect; class MWSpellEffect;
class MYGUI_EXPORT MWSpell : public Widget class MYGUI_EXPORT MWSpell : public MyGUI::Widget
{ {
MYGUI_RTTI_DERIVED( MWSpell ); MYGUI_RTTI_DERIVED( MWSpell );
public: public:
@ -182,7 +182,7 @@ namespace MWGui
*/ */
void createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags); void createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags);
const std::string &getSpellId() const { return id; } const std::string &getSpellId() const { return mId; }
protected: protected:
virtual ~MWSpell(); virtual ~MWSpell();
@ -193,12 +193,12 @@ namespace MWGui
void updateWidgets(); void updateWidgets();
WindowManager* mWindowManager; WindowManager* mWindowManager;
std::string id; std::string mId;
MyGUI::TextBox* spellNameWidget; MyGUI::TextBox* mSpellNameWidget;
}; };
typedef MWSpell* MWSpellPtr; typedef MWSpell* MWSpellPtr;
class MYGUI_EXPORT MWEffectList : public Widget class MYGUI_EXPORT MWEffectList : public MyGUI::Widget
{ {
MYGUI_RTTI_DERIVED( MWEffectList ); MYGUI_RTTI_DERIVED( MWEffectList );
public: public:
@ -239,7 +239,7 @@ namespace MWGui
}; };
typedef MWEffectList* MWEffectListPtr; typedef MWEffectList* MWEffectListPtr;
class MYGUI_EXPORT MWSpellEffect : public Widget class MYGUI_EXPORT MWSpellEffect : public MyGUI::Widget
{ {
MYGUI_RTTI_DERIVED( MWSpellEffect ); MYGUI_RTTI_DERIVED( MWSpellEffect );
public: public:
@ -269,13 +269,13 @@ namespace MWGui
WindowManager* mWindowManager; WindowManager* mWindowManager;
SpellEffectParams mEffectParams; SpellEffectParams mEffectParams;
MyGUI::ImageBox* imageWidget; MyGUI::ImageBox* mImageWidget;
MyGUI::TextBox* textWidget; MyGUI::TextBox* mTextWidget;
int mRequestedWidth; int mRequestedWidth;
}; };
typedef MWSpellEffect* MWSpellEffectPtr; typedef MWSpellEffect* MWSpellEffectPtr;
class MYGUI_EXPORT MWDynamicStat : public Widget class MYGUI_EXPORT MWDynamicStat : public MyGUI::Widget
{ {
MYGUI_RTTI_DERIVED( MWDynamicStat ); MYGUI_RTTI_DERIVED( MWDynamicStat );
public: public:
@ -284,8 +284,8 @@ namespace MWGui
void setValue(int value, int max); void setValue(int value, int max);
void setTitle(const std::string& text); void setTitle(const std::string& text);
int getValue() const { return value; } int getValue() const { return mValue; }
int getMax() const { return max; } int getMax() const { return mMax; }
protected: protected:
virtual ~MWDynamicStat(); virtual ~MWDynamicStat();
@ -294,10 +294,10 @@ namespace MWGui
private: private:
int value, max; int mValue, mMax;
MyGUI::TextBox* textWidget; MyGUI::TextBox* mTextWidget;
MyGUI::ProgressPtr barWidget; MyGUI::ProgressPtr mBarWidget;
MyGUI::TextBox* barTextWidget; MyGUI::TextBox* mBarTextWidget;
}; };
typedef MWDynamicStat* MWDynamicStatPtr; typedef MWDynamicStat* MWDynamicStatPtr;
} }

View file

@ -43,13 +43,13 @@ using namespace MWGui;
WindowManager::WindowManager( WindowManager::WindowManager(
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath) const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath)
: mGuiManager(NULL) : mGuiManager(NULL)
, hud(NULL) , mHud(NULL)
, map(NULL) , mMap(NULL)
, menu(NULL) , mMenu(NULL)
, mStatsWindow(NULL) , mStatsWindow(NULL)
, mToolTips(NULL) , mToolTips(NULL)
, mMessageBoxManager(NULL) , mMessageBoxManager(NULL)
, console(NULL) , mConsole(NULL)
, mJournal(NULL) , mJournal(NULL)
, mDialogueWindow(NULL) , mDialogueWindow(NULL)
, mBookWindow(NULL) , mBookWindow(NULL)
@ -61,21 +61,21 @@ WindowManager::WindowManager(
, mAlchemyWindow(NULL) , mAlchemyWindow(NULL)
, mSpellWindow(NULL) , mSpellWindow(NULL)
, mCharGen(NULL) , mCharGen(NULL)
, playerClass() , mPlayerClass()
, playerName() , mPlayerName()
, playerRaceId() , mPlayerRaceId()
, playerAttributes() , mPlayerAttributes()
, playerMajorSkills() , mPlayerMajorSkills()
, playerMinorSkills() , mPlayerMinorSkills()
, playerSkillValues() , mPlayerSkillValues()
, playerHealth() , mPlayerHealth()
, playerMagicka() , mPlayerMagicka()
, playerFatigue() , mPlayerFatigue()
, gui(NULL) , mGui(NULL)
, garbageDialogs() , mGarbageDialogs()
, shown(GW_ALL) , mShown(GW_ALL)
, allowed(newGame ? GW_None : GW_ALL) , mAllowed(newGame ? GW_None : GW_ALL)
, showFPSLevel(fpsLevel) , mShowFPSLevel(fpsLevel)
, mFPS(0.0f) , mFPS(0.0f)
, mTriangleCount(0) , mTriangleCount(0)
, mBatchCount(0) , mBatchCount(0)
@ -83,7 +83,7 @@ WindowManager::WindowManager(
// Set up the GUI system // Set up the GUI system
mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath); mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath);
gui = mGuiManager->getGui(); mGui = mGuiManager->getGui();
//Register own widgets with MyGUI //Register own widgets with MyGUI
MyGUI::FactoryManager::getInstance().registerFactory<DialogueHistory>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<DialogueHistory>("Widget");
@ -98,11 +98,11 @@ WindowManager::WindowManager(
MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag); MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag);
// Get size info from the Gui object // Get size info from the Gui object
assert(gui); assert(mGui);
int w = MyGUI::RenderManager::getInstance().getViewSize().width; int w = MyGUI::RenderManager::getInstance().getViewSize().width;
int h = MyGUI::RenderManager::getInstance().getViewSize().height; int h = MyGUI::RenderManager::getInstance().getViewSize().height;
MyGUI::Widget* dragAndDropWidget = gui->createWidgetT("Widget","",0,0,w,h,MyGUI::Align::Default,"DragAndDrop","DragAndDropWidget"); MyGUI::Widget* dragAndDropWidget = mGui->createWidgetT("Widget","",0,0,w,h,MyGUI::Align::Default,"DragAndDrop","DragAndDropWidget");
dragAndDropWidget->setVisible(false); dragAndDropWidget->setVisible(false);
mDragAndDrop = new DragAndDrop(); mDragAndDrop = new DragAndDrop();
@ -110,17 +110,17 @@ WindowManager::WindowManager(
mDragAndDrop->mDraggedWidget = 0; mDragAndDrop->mDraggedWidget = 0;
mDragAndDrop->mDragAndDropWidget = dragAndDropWidget; mDragAndDrop->mDragAndDropWidget = dragAndDropWidget;
menu = new MainMenu(w,h); mMenu = new MainMenu(w,h);
map = new MapWindow(*this); mMap = new MapWindow(*this);
mStatsWindow = new StatsWindow(*this); mStatsWindow = new StatsWindow(*this);
console = new Console(w,h, extensions); mConsole = new Console(w,h, extensions);
mJournal = new JournalWindow(*this); mJournal = new JournalWindow(*this);
mMessageBoxManager = new MessageBoxManager(this); mMessageBoxManager = new MessageBoxManager(this);
mInventoryWindow = new InventoryWindow(*this,mDragAndDrop); mInventoryWindow = new InventoryWindow(*this,mDragAndDrop);
mTradeWindow = new TradeWindow(*this); mTradeWindow = new TradeWindow(*this);
mDialogueWindow = new DialogueWindow(*this); mDialogueWindow = new DialogueWindow(*this);
mContainerWindow = new ContainerWindow(*this,mDragAndDrop); mContainerWindow = new ContainerWindow(*this,mDragAndDrop);
hud = new HUD(w,h, showFPSLevel, mDragAndDrop); mHud = new HUD(w,h, mShowFPSLevel, mDragAndDrop);
mToolTips = new ToolTips(this); mToolTips = new ToolTips(this);
mScrollWindow = new ScrollWindow(*this); mScrollWindow = new ScrollWindow(*this);
mBookWindow = new BookWindow(*this); mBookWindow = new BookWindow(*this);
@ -131,19 +131,19 @@ WindowManager::WindowManager(
mSpellWindow = new SpellWindow(*this); mSpellWindow = new SpellWindow(*this);
// The HUD is always on // The HUD is always on
hud->setVisible(true); mHud->setVisible(true);
mCharGen = new CharacterCreation(this); mCharGen = new CharacterCreation(this);
// 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>())); mPlayerAttributes.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>())); mPlayerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>()));
} }
unsetSelectedSpell(); unsetSelectedSpell();
@ -156,11 +156,11 @@ WindowManager::WindowManager(
WindowManager::~WindowManager() WindowManager::~WindowManager()
{ {
delete mGuiManager; delete mGuiManager;
delete console; delete mConsole;
delete mMessageBoxManager; delete mMessageBoxManager;
delete hud; delete mHud;
delete map; delete mMap;
delete menu; delete mMenu;
delete mStatsWindow; delete mStatsWindow;
delete mJournal; delete mJournal;
delete mDialogueWindow; delete mDialogueWindow;
@ -183,13 +183,13 @@ WindowManager::~WindowManager()
void WindowManager::cleanupGarbage() void WindowManager::cleanupGarbage()
{ {
// Delete any dialogs which are no longer in use // Delete any dialogs which are no longer in use
if (!garbageDialogs.empty()) if (!mGarbageDialogs.empty())
{ {
for (std::vector<OEngine::GUI::Layout*>::iterator it = garbageDialogs.begin(); it != garbageDialogs.end(); ++it) for (std::vector<OEngine::GUI::Layout*>::iterator it = mGarbageDialogs.begin(); it != mGarbageDialogs.end(); ++it)
{ {
delete *it; delete *it;
} }
garbageDialogs.clear(); mGarbageDialogs.clear();
} }
} }
@ -197,18 +197,18 @@ void WindowManager::update()
{ {
cleanupGarbage(); cleanupGarbage();
hud->setFPS(mFPS); mHud->setFPS(mFPS);
hud->setTriangleCount(mTriangleCount); mHud->setTriangleCount(mTriangleCount);
hud->setBatchCount(mBatchCount); mHud->setBatchCount(mBatchCount);
} }
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); mMap->setVisible(false);
menu->setVisible(false); mMenu->setVisible(false);
mStatsWindow->setVisible(false); mStatsWindow->setVisible(false);
console->disable(); mConsole->disable();
mJournal->setVisible(false); mJournal->setVisible(false);
mDialogueWindow->setVisible(false); mDialogueWindow->setVisible(false);
mContainerWindow->setVisible(false); mContainerWindow->setVisible(false);
@ -230,10 +230,10 @@ void WindowManager::updateVisible()
else else
mToolTips->enterGuiMode(); mToolTips->enterGuiMode();
setMinimapVisibility((allowed & GW_Map) && !map->pinned()); setMinimapVisibility((mAllowed & GW_Map) && !mMap->pinned());
setWeaponVisibility((allowed & GW_Inventory) && !mInventoryWindow->pinned()); setWeaponVisibility((mAllowed & GW_Inventory) && !mInventoryWindow->pinned());
setSpellVisibility((allowed & GW_Magic) && !mSpellWindow->pinned()); setSpellVisibility((mAllowed & GW_Magic) && !mSpellWindow->pinned());
setHMSVisibility((allowed & GW_Stats) && !mStatsWindow->pinned()); setHMSVisibility((mAllowed & GW_Stats) && !mStatsWindow->pinned());
// If in game mode, don't show anything. // If in game mode, don't show anything.
if (gameMode) if (gameMode)
@ -243,13 +243,13 @@ void WindowManager::updateVisible()
switch(mode) { switch(mode) {
case GM_MainMenu: case GM_MainMenu:
menu->setVisible(true); mMenu->setVisible(true);
break; break;
case GM_Settings: case GM_Settings:
mSettingsWindow->setVisible(true); mSettingsWindow->setVisible(true);
break; break;
case GM_Console: case GM_Console:
console->enable(); mConsole->enable();
break; break;
case GM_Scroll: case GM_Scroll:
mScrollWindow->setVisible(true); mScrollWindow->setVisible(true);
@ -276,13 +276,13 @@ void WindowManager::updateVisible()
// This is controlled both by what windows the // This is controlled both by what windows the
// user has opened/closed (the 'shown' variable) and by what // user has opened/closed (the 'shown' variable) and by what
// windows we are allowed to show (the 'allowed' var.) // windows we are allowed to show (the 'allowed' var.)
int eff = shown & allowed; int eff = mShown & mAllowed;
// Show the windows we want // Show the windows we want
map -> setVisible(eff & GW_Map); mMap ->setVisible(eff & GW_Map);
mStatsWindow -> setVisible(eff & GW_Stats); mStatsWindow ->setVisible(eff & GW_Stats);
mInventoryWindow->setVisible(eff & GW_Inventory); mInventoryWindow->setVisible(eff & GW_Inventory);
mSpellWindow->setVisible(eff & GW_Magic); mSpellWindow ->setVisible(eff & GW_Magic);
break; break;
} }
case GM_Container: case GM_Container:
@ -333,7 +333,7 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int
{ {
if (id != ids[i]) if (id != ids[i])
continue; continue;
playerAttributes[attributes[i]] = value; mPlayerAttributes[attributes[i]] = value;
break; break;
} }
} }
@ -343,27 +343,27 @@ void WindowManager::setValue(const ESM::Skill::SkillEnum parSkill, const MWMecha
{ {
mStatsWindow->setValue(parSkill, value); mStatsWindow->setValue(parSkill, value);
mCharGen->setValue(parSkill, value); mCharGen->setValue(parSkill, value);
playerSkillValues[parSkill] = value; mPlayerSkillValues[parSkill] = value;
} }
void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value) void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
{ {
mStatsWindow->setValue (id, value); mStatsWindow->setValue (id, value);
hud->setValue (id, value); mHud->setValue (id, value);
mCharGen->setValue(id, value); mCharGen->setValue(id, value);
if (id == "HBar") if (id == "HBar")
{ {
playerHealth = value; mPlayerHealth = value;
mCharGen->setPlayerHealth (value); mCharGen->setPlayerHealth (value);
} }
else if (id == "MBar") else if (id == "MBar")
{ {
playerMagicka = value; mPlayerMagicka = value;
mCharGen->setPlayerMagicka (value); mCharGen->setPlayerMagicka (value);
} }
else if (id == "FBar") else if (id == "FBar")
{ {
playerFatigue = value; mPlayerFatigue = value;
mCharGen->setPlayerFatigue (value); mCharGen->setPlayerFatigue (value);
} }
} }
@ -372,11 +372,11 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicS
MWMechanics::DynamicStat<int> WindowManager::getValue(const std::string& id) MWMechanics::DynamicStat<int> WindowManager::getValue(const std::string& id)
{ {
if(id == "HBar") if(id == "HBar")
return playerHealth; return layerHealth;
else if (id == "MBar") else if (id == "MBar")
return playerMagicka; return mPlayerMagicka;
else if (id == "FBar") else if (id == "FBar")
return playerFatigue; return mPlayerFatigue;
} }
#endif #endif
@ -384,9 +384,9 @@ void WindowManager::setValue (const std::string& id, const std::string& value)
{ {
mStatsWindow->setValue (id, value); mStatsWindow->setValue (id, value);
if (id=="name") if (id=="name")
playerName = value; mPlayerName = value;
else if (id=="race") else if (id=="race")
playerRaceId = value; mPlayerRaceId = value;
} }
void WindowManager::setValue (const std::string& id, int value) void WindowManager::setValue (const std::string& id, int value)
@ -396,16 +396,16 @@ void WindowManager::setValue (const std::string& id, int value)
void WindowManager::setPlayerClass (const ESM::Class &class_) void WindowManager::setPlayerClass (const ESM::Class &class_)
{ {
playerClass = class_; mPlayerClass = class_;
mStatsWindow->setValue("class", playerClass.name); mStatsWindow->setValue("class", mPlayerClass.name);
} }
void WindowManager::configureSkills (const SkillList& major, const SkillList& minor) void WindowManager::configureSkills (const SkillList& major, const SkillList& minor)
{ {
mStatsWindow->configureSkills (major, minor); mStatsWindow->configureSkills (major, minor);
mCharGen->configureSkills(major, minor); mCharGen->configureSkills(major, minor);
playerMajorSkills = major; mPlayerMajorSkills = major;
playerMinorSkills = minor; mPlayerMinorSkills = minor;
} }
void WindowManager::setReputation (int reputation) void WindowManager::setReputation (int reputation)
@ -429,7 +429,7 @@ void WindowManager::removeDialog(OEngine::GUI::Layout*dialog)
if (!dialog) if (!dialog)
return; return;
dialog->setVisible(false); dialog->setVisible(false);
garbageDialogs.push_back(dialog); mGarbageDialogs.push_back(dialog);
} }
void WindowManager::messageBox (const std::string& message, const std::vector<std::string>& buttons) void WindowManager::messageBox (const std::string& message, const std::vector<std::string>& buttons)
@ -484,12 +484,12 @@ void WindowManager::onFrame (float frameDuration)
mStatsWindow->onFrame(); mStatsWindow->onFrame();
hud->onFrame(frameDuration); mHud->onFrame(frameDuration);
mDialogueWindow->checkReferenceAvailable(); mDialogueWindow->checkReferenceAvailable();
mTradeWindow->checkReferenceAvailable(); mTradeWindow->checkReferenceAvailable();
mContainerWindow->checkReferenceAvailable(); mContainerWindow->checkReferenceAvailable();
console->checkReferenceAvailable(); mConsole->checkReferenceAvailable();
} }
const ESMS::ESMStore& WindowManager::getStore() const const ESMS::ESMStore& WindowManager::getStore() const
@ -513,56 +513,56 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
name = getGameSettingString("sDefaultCellname", "Wilderness"); name = getGameSettingString("sDefaultCellname", "Wilderness");
} }
map->setCellName( name ); mMap->setCellName( name );
hud->setCellName( name ); mHud->setCellName( name );
map->setCellPrefix("Cell"); mMap->setCellPrefix("Cell");
hud->setCellPrefix("Cell"); mHud->setCellPrefix("Cell");
map->setActiveCell( cell->cell->data.gridX, cell->cell->data.gridY ); mMap->setActiveCell( cell->cell->data.gridX, cell->cell->data.gridY );
hud->setActiveCell( cell->cell->data.gridX, cell->cell->data.gridY ); mHud->setActiveCell( cell->cell->data.gridX, cell->cell->data.gridY );
} }
else else
{ {
map->setCellName( cell->cell->name ); mMap->setCellName( cell->cell->name );
hud->setCellName( cell->cell->name ); mHud->setCellName( cell->cell->name );
map->setCellPrefix( cell->cell->name ); mMap->setCellPrefix( cell->cell->name );
hud->setCellPrefix( cell->cell->name ); mHud->setCellPrefix( cell->cell->name );
} }
} }
void WindowManager::setInteriorMapTexture(const int x, const int y) void WindowManager::setInteriorMapTexture(const int x, const int y)
{ {
map->setActiveCell(x,y, true); mMap->setActiveCell(x,y, true);
hud->setActiveCell(x,y, true); mHud->setActiveCell(x,y, true);
} }
void WindowManager::setPlayerPos(const float x, const float y) void WindowManager::setPlayerPos(const float x, const float y)
{ {
map->setPlayerPos(x,y); mMap->setPlayerPos(x,y);
hud->setPlayerPos(x,y); mHud->setPlayerPos(x,y);
} }
void WindowManager::setPlayerDir(const float x, const float y) void WindowManager::setPlayerDir(const float x, const float y)
{ {
map->setPlayerDir(x,y); mMap->setPlayerDir(x,y);
hud->setPlayerDir(x,y); mHud->setPlayerDir(x,y);
} }
void WindowManager::setHMSVisibility(bool visible) void WindowManager::setHMSVisibility(bool visible)
{ {
hud->setBottomLeftVisibility(visible, hud->weapBox->getVisible(), hud->spellBox->getVisible()); mHud->setBottomLeftVisibility(visible, mHud->mWeapBox->getVisible(), mHud->mSpellBox->getVisible());
} }
void WindowManager::setMinimapVisibility(bool visible) void WindowManager::setMinimapVisibility(bool visible)
{ {
hud->setBottomRightVisibility(hud->effectBox->getVisible(), visible); mHud->setBottomRightVisibility(mHud->mEffectBox->getVisible(), visible);
} }
void WindowManager::toggleFogOfWar() void WindowManager::toggleFogOfWar()
{ {
map->toggleFogOfWar(); mMap->toggleFogOfWar();
hud->toggleFogOfWar(); mHud->toggleFogOfWar();
} }
void WindowManager::setFocusObject(const MWWorld::Ptr& focus) void WindowManager::setFocusObject(const MWWorld::Ptr& focus)
@ -587,13 +587,13 @@ bool WindowManager::getFullHelp() const
void WindowManager::setWeaponVisibility(bool visible) void WindowManager::setWeaponVisibility(bool visible)
{ {
hud->setBottomLeftVisibility(hud->health->getVisible(), visible, hud->spellBox->getVisible()); mHud->setBottomLeftVisibility(mHud->health->getVisible(), visible, mHud->mSpellBox->getVisible());
} }
void WindowManager::setSpellVisibility(bool visible) void WindowManager::setSpellVisibility(bool visible)
{ {
hud->setBottomLeftVisibility(hud->health->getVisible(), hud->weapBox->getVisible(), visible); mHud->setBottomLeftVisibility(mHud->health->getVisible(), mHud->mWeapBox->getVisible(), visible);
hud->setBottomRightVisibility(visible, hud->minimapBox->getVisible()); mHud->setBottomRightVisibility(visible, mHud->mMinimapBox->getVisible());
} }
void WindowManager::setMouseVisible(bool visible) void WindowManager::setMouseVisible(bool visible)
@ -618,7 +618,7 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed) void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)
{ {
hud->setFpsLevel(Settings::Manager::getInt("fps", "HUD")); mHud->setFpsLevel(Settings::Manager::getInt("fps", "HUD"));
mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI")); mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI"));
bool changeRes = false; bool changeRes = false;
@ -637,8 +637,8 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
{ {
int x = Settings::Manager::getInt("resolution x", "Video"); int x = Settings::Manager::getInt("resolution x", "Video");
int y = Settings::Manager::getInt("resolution y", "Video"); int y = Settings::Manager::getInt("resolution y", "Video");
hud->onResChange(x, y); mHud->onResChange(x, y);
console->onResChange(x, y); mConsole->onResChange(x, y);
mSettingsWindow->center(); mSettingsWindow->center();
mAlchemyWindow->center(); mAlchemyWindow->center();
mScrollWindow->center(); mScrollWindow->center();
@ -649,7 +649,7 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
void WindowManager::pushGuiMode(GuiMode mode) void WindowManager::pushGuiMode(GuiMode mode)
{ {
if (mode==GM_Inventory && allowed==GW_None) if (mode==GM_Inventory && mAllowed==GW_None)
return; return;
mGuiModes.push_back(mode); mGuiModes.push_back(mode);
@ -690,32 +690,32 @@ void WindowManager::removeGuiMode(GuiMode mode)
void WindowManager::setSelectedSpell(const std::string& spellId, int successChancePercent) void WindowManager::setSelectedSpell(const std::string& spellId, int successChancePercent)
{ {
hud->setSelectedSpell(spellId, successChancePercent); mHud->setSelectedSpell(spellId, successChancePercent);
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
mSpellWindow->setTitle(spell->name); mSpellWindow->setTitle(spell->name);
} }
void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent) void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
{ {
hud->setSelectedEnchantItem(item, chargePercent); mHud->setSelectedEnchantItem(item, chargePercent);
mSpellWindow->setTitle(MWWorld::Class::get(item).getName(item)); mSpellWindow->setTitle(MWWorld::Class::get(item).getName(item));
} }
void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent) void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
{ {
hud->setSelectedWeapon(item, durabilityPercent); mHud->setSelectedWeapon(item, durabilityPercent);
mInventoryWindow->setTitle(MWWorld::Class::get(item).getName(item)); mInventoryWindow->setTitle(MWWorld::Class::get(item).getName(item));
} }
void WindowManager::unsetSelectedSpell() void WindowManager::unsetSelectedSpell()
{ {
hud->unsetSelectedSpell(); mHud->unsetSelectedSpell();
mSpellWindow->setTitle("#{sNone}"); mSpellWindow->setTitle("#{sNone}");
} }
void WindowManager::unsetSelectedWeapon() void WindowManager::unsetSelectedWeapon()
{ {
hud->unsetSelectedWeapon(); mHud->unsetSelectedWeapon();
mInventoryWindow->setTitle("#{sSkillHandtohand}"); mInventoryWindow->setTitle("#{sSkillHandtohand}");
} }
@ -738,5 +738,5 @@ void WindowManager::getMousePosition(float &x, float &y)
bool WindowManager::getWorldMouseOver() bool WindowManager::getWorldMouseOver()
{ {
return hud->getWorldMouseOver(); return mHud->getWorldMouseOver();
} }

View file

@ -10,10 +10,6 @@
this class. this class.
**/ **/
#include <string>
#include <vector>
#include <set>
#include "MyGUI_UString.h" #include "MyGUI_UString.h"
#include <components/esm_store/store.hpp> #include <components/esm_store/store.hpp>
@ -123,27 +119,27 @@ namespace MWGui
void toggleVisible(GuiWindow wnd) void toggleVisible(GuiWindow wnd)
{ {
shown = (shown & wnd) ? (GuiWindow) (shown & ~wnd) : (GuiWindow) (shown | wnd); mShown = (mShown & wnd) ? (GuiWindow) (mShown & ~wnd) : (GuiWindow) (mShown | wnd);
updateVisible(); updateVisible();
} }
// Disallow all inventory mode windows // Disallow all inventory mode windows
void disallowAll() void disallowAll()
{ {
allowed = GW_None; mAllowed = GW_None;
updateVisible(); updateVisible();
} }
// Allow one or more windows // Allow one or more windows
void allow(GuiWindow wnd) void allow(GuiWindow wnd)
{ {
allowed = (GuiWindow)(allowed | wnd); mAllowed = (GuiWindow)(mAllowed | wnd);
updateVisible(); updateVisible();
} }
bool isAllowed(GuiWindow wnd) const bool isAllowed(GuiWindow wnd) const
{ {
return allowed & wnd; return mAllowed & wnd;
} }
MWGui::DialogueWindow* getDialogueWindow() {return mDialogueWindow;} MWGui::DialogueWindow* getDialogueWindow() {return mDialogueWindow;}
@ -155,9 +151,9 @@ namespace MWGui
MWGui::ConfirmationDialog* getConfirmationDialog() {return mConfirmationDialog;} MWGui::ConfirmationDialog* getConfirmationDialog() {return mConfirmationDialog;}
MWGui::TradeWindow* getTradeWindow() {return mTradeWindow;} MWGui::TradeWindow* getTradeWindow() {return mTradeWindow;}
MWGui::SpellWindow* getSpellWindow() {return mSpellWindow;} MWGui::SpellWindow* getSpellWindow() {return mSpellWindow;}
MWGui::Console* getConsole() {return console;} MWGui::Console* getConsole() {return mConsole;}
MyGUI::Gui* getGui() const { return gui; } MyGUI::Gui* getGui() const { return mGui; }
void wmUpdateFps(float fps, unsigned int triangleCount, unsigned int batchCount) void wmUpdateFps(float fps, unsigned int triangleCount, unsigned int batchCount)
{ {
@ -223,10 +219,10 @@ namespace MWGui
void onFrame (float frameDuration); void onFrame (float frameDuration);
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > getPlayerSkillValues() { return playerSkillValues; } std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > getPlayerSkillValues() { return mPlayerSkillValues; }
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > getPlayerAttributeValues() { return playerAttributes; } std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > getPlayerAttributeValues() { return mPlayerAttributes; }
SkillList getPlayerMinorSkills() { return playerMinorSkills; } SkillList getPlayerMinorSkills() { return mPlayerMinorSkills; }
SkillList getPlayerMajorSkills() { return playerMajorSkills; } SkillList getPlayerMajorSkills() { return mPlayerMajorSkills; }
/** /**
* Fetches a GMST string from the store, if there is no setting with the given * Fetches a GMST string from the store, if there is no setting with the given
@ -243,13 +239,13 @@ namespace MWGui
private: private:
OEngine::GUI::MyGUIManager *mGuiManager; OEngine::GUI::MyGUIManager *mGuiManager;
HUD *hud; HUD *mHud;
MapWindow *map; MapWindow *mMap;
MainMenu *menu; MainMenu *mMenu;
ToolTips *mToolTips; ToolTips *mToolTips;
StatsWindow *mStatsWindow; StatsWindow *mStatsWindow;
MessageBoxManager *mMessageBoxManager; MessageBoxManager *mMessageBoxManager;
Console *console; Console *mConsole;
JournalWindow* mJournal; JournalWindow* mJournal;
DialogueWindow *mDialogueWindow; DialogueWindow *mDialogueWindow;
ContainerWindow *mContainerWindow; ContainerWindow *mContainerWindow;
@ -267,33 +263,33 @@ namespace MWGui
CharacterCreation* mCharGen; CharacterCreation* mCharGen;
// Various stats about player as needed by window manager // Various stats about player as needed by window manager
ESM::Class playerClass; ESM::Class mPlayerClass;
std::string playerName; std::string mPlayerName;
std::string playerRaceId; std::string mPlayerRaceId;
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > playerAttributes; std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > mPlayerAttributes;
SkillList playerMajorSkills, playerMinorSkills; SkillList mPlayerMajorSkills, mPlayerMinorSkills;
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > playerSkillValues; std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > mPlayerSkillValues;
MWMechanics::DynamicStat<int> playerHealth, playerMagicka, playerFatigue; MWMechanics::DynamicStat<int> mPlayerHealth, mPlayerMagicka, mPlayerFatigue;
MyGUI::Gui *gui; // Gui MyGUI::Gui *mGui; // Gui
std::vector<GuiMode> mGuiModes; std::vector<GuiMode> mGuiModes;
std::vector<OEngine::GUI::Layout*> garbageDialogs; std::vector<OEngine::GUI::Layout*> mGarbageDialogs;
void cleanupGarbage(); void cleanupGarbage();
GuiWindow shown; // Currently shown windows in inventory mode GuiWindow mShown; // Currently shown windows in inventory mode
/* Currently ALLOWED windows in inventory mode. This is used at /* Currently ALLOWED windows in inventory mode. This is used at
the start of the game, when windows are enabled one by one the start of the game, when windows are enabled one by one
through script commands. You can manipulate this through using through script commands. You can manipulate this through using
allow() and disableAll(). allow() and disableAll().
*/ */
GuiWindow allowed; GuiWindow mAllowed;
void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings
int showFPSLevel; int mShowFPSLevel;
float mFPS; float mFPS;
unsigned int mTriangleCount; unsigned int mTriangleCount;
unsigned int mBatchCount; unsigned int mBatchCount;

View file

@ -1,18 +1,8 @@
#ifndef _GAME_RENDER_ACTORS_H #ifndef _GAME_RENDER_ACTORS_H
#define _GAME_RENDER_ACTORS_H #define _GAME_RENDER_ACTORS_H
#include <map>
#include <list>
#include <openengine/ogre/renderer.hpp>
#include "components/nifogre/ogre_nif_loader.hpp"
#include "../mwworld/refdata.hpp"
#include "../mwworld/actiontalk.hpp"
#include "npcanimation.hpp" #include "npcanimation.hpp"
#include "creatureanimation.hpp" #include "creatureanimation.hpp"
#include <openengine/bullet/physic.hpp>
namespace MWWorld namespace MWWorld
{ {

View file

@ -6,25 +6,26 @@
#include <OgreBone.h> #include <OgreBone.h>
#include <OgreSubMesh.h> #include <OgreSubMesh.h>
namespace MWRender{ namespace MWRender
std::map<std::string, int> Animation::mUniqueIDs; {
std::map<std::string, int> Animation::sUniqueIDs;
Animation::Animation(OEngine::Render::OgreRenderer& _rend) Animation::Animation(OEngine::Render::OgreRenderer& _rend)
: insert(NULL) : mInsert(NULL)
, mRend(_rend) , mRend(_rend)
, vecRotPos() , mVecRotPos()
, time(0.0f) , mTime(0.0f)
, startTime(0.0f) , mStartTime(0.0f)
, stopTime(0.0f) , mStopTime(0.0f)
, animate(0) , mAnimate(0)
, rindexI() , mRindexI()
, tindexI() , mTindexI()
, shapeNumber(0) , mShapeNumber(0)
, shapeIndexI() , mShapeIndexI()
, shapes(NULL) , mShapes(NULL)
, transformations(NULL) , mTransformations(NULL)
, textmappings(NULL) , mTextmappings(NULL)
, base(NULL) , mBase(NULL)
{ {
} }
@ -32,178 +33,191 @@ namespace MWRender{
{ {
} }
std::string Animation::getUniqueID(std::string mesh){ std::string Animation::getUniqueID(std::string mesh)
int counter; {
std::string copy = mesh; int counter;
std::transform(copy.begin(), copy.end(), copy.begin(), ::tolower); std::string copy = mesh;
if(mUniqueIDs.find(copy) == mUniqueIDs.end()){ std::transform(copy.begin(), copy.end(), copy.begin(), ::tolower);
counter = mUniqueIDs[copy] = 0;
} if(sUniqueIDs.find(copy) == sUniqueIDs.end())
else{ {
mUniqueIDs[copy] = mUniqueIDs[copy] + 1; counter = sUniqueIDs[copy] = 0;
counter = mUniqueIDs[copy];
}
std::stringstream out;
if(counter > 99 && counter < 1000)
out << "0";
else if(counter > 9)
out << "00";
else
out << "000";
out << counter;
return out.str();
}
void Animation::startScript(std::string groupname, int mode, int loops){
//If groupname is recognized set animate to true
//Set the start time and stop time
//How many times to loop
if(groupname == "all"){
animate = loops;
time = startTime;
} }
else if(textmappings){ else
{
sUniqueIDs[copy] = sUniqueIDs[copy] + 1;
counter = sUniqueIDs[copy];
}
std::stringstream out;
if(counter > 99 && counter < 1000)
out << "0";
else if(counter > 9)
out << "00";
else
out << "000";
out << counter;
return out.str();
}
void Animation::startScript(std::string groupname, int mode, int loops)
{
//If groupname is recognized set animate to true
//Set the start time and stop time
//How many times to loop
if(groupname == "all")
{
mAnimate = loops;
mTime = mStartTime;
}
else if(mTextmappings)
{
std::string startName = groupname + ": loop start"; std::string startName = groupname + ": loop start";
std::string stopName = groupname + ": loop stop"; std::string stopName = groupname + ": loop stop";
bool first = false; bool first = false;
if(loops > 1){ if(loops > 1)
{
startName = groupname + ": loop start"; startName = groupname + ": loop start";
stopName = groupname + ": loop stop"; stopName = groupname + ": loop stop";
for(std::map<std::string, float>::iterator iter = textmappings->begin(); iter != textmappings->end(); iter++){ for(std::map<std::string, float>::iterator iter = mTextmappings->begin(); iter != mTextmappings->end(); iter++)
{
std::string current = iter->first.substr(0, startName.size()); std::string current = iter->first.substr(0, startName.size());
std::transform(current.begin(), current.end(), current.begin(), ::tolower); std::transform(current.begin(), current.end(), current.begin(), ::tolower);
std::string current2 = iter->first.substr(0, stopName.size()); std::string current2 = iter->first.substr(0, stopName.size());
std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower); std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower);
if(current == startName){ if(current == startName)
startTime = iter->second; {
animate = loops; mStartTime = iter->second;
time = startTime; mAnimate = loops;
first = true; mTime = mStartTime;
} first = true;
if(current2 == stopName){ }
stopTime = iter->second; if(current2 == stopName)
if(first) {
break; mStopTime = iter->second;
} if(first)
break;
}
} }
} }
if(!first){ if(!first)
{
startName = groupname + ": start"; startName = groupname + ": start";
stopName = groupname + ": stop"; stopName = groupname + ": stop";
for(std::map<std::string, float>::iterator iter = textmappings->begin(); iter != textmappings->end(); iter++){ for(std::map<std::string, float>::iterator iter = mTextmappings->begin(); iter != mTextmappings->end(); iter++)
{
std::string current = iter->first.substr(0, startName.size()); std::string current = iter->first.substr(0, startName.size());
std::transform(current.begin(), current.end(), current.begin(), ::tolower); std::transform(current.begin(), current.end(), current.begin(), ::tolower);
std::string current2 = iter->first.substr(0, stopName.size()); std::string current2 = iter->first.substr(0, stopName.size());
std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower); std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower);
if(current == startName){ if(current == startName)
startTime = iter->second; {
animate = loops; mStartTime = iter->second;
time = startTime; mAnimate = loops;
first = true; mTime = mStartTime;
} first = true;
if(current2 == stopName){ }
stopTime = iter->second; if(current2 == stopName)
if(first) {
break; mStopTime = iter->second;
if(first)
break;
}
} }
} }
}
} }
}
void Animation::stopScript(){
animate = 0;
} }
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){ void Animation::stopScript()
shapeNumber = 0; {
mAnimate = 0;
}
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel)
{
mShapeNumber = 0;
if (allshapes == NULL || creaturemodel == NULL || skel == NULL) if (allshapes == NULL || creaturemodel == NULL || skel == NULL)
{
return; return;
}
std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter; std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter;
for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++) for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++)
{
//std::map<unsigned short, PosAndRot> vecPosRot;
{ Nif::NiTriShapeCopy& copy = *allshapesiter;
//std::map<unsigned short, PosAndRot> vecPosRot; std::vector<Ogre::Vector3>* allvertices = &copy.vertices;
Nif::NiTriShapeCopy& copy = *allshapesiter; //std::set<unsigned int> vertices;
std::vector<Ogre::Vector3>* allvertices = &copy.vertices; //std::set<unsigned int> normals;
//std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfovector = copy.boneinfo;
//std::set<unsigned int> vertices;
//std::set<unsigned int> normals;
//std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfovector = copy.boneinfo;
std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >* verticesToChange = &copy.vertsToWeights; std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >* verticesToChange = &copy.vertsToWeights;
//std::cout << "Name " << copy.sname << "\n"; //std::cout << "Name " << copy.sname << "\n";
Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0); Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0);
Ogre::Real* pReal = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL)); Ogre::Real* pReal = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
std::vector<Ogre::Vector3> initialVertices = copy.morph.getInitialVertices(); std::vector<Ogre::Vector3> initialVertices = copy.morph.getInitialVertices();
//Each shape has multiple indices //Each shape has multiple indices
if(initialVertices.size() ) if(initialVertices.size() )
{ {
if(copy.vertices.size() == initialVertices.size())
{
//Create if it doesn't already exist
if(mShapeIndexI.size() == static_cast<std::size_t> (mShapeNumber))
{
std::vector<int> vec;
mShapeIndexI.push_back(vec);
}
if(mTime >= copy.morph.getStartTime() && mTime <= copy.morph.getStopTime())
{
float x;
for (unsigned int i = 0; i < copy.morph.getAdditionalVertices().size(); i++)
{
int j = 0;
if(mShapeIndexI[mShapeNumber].size() <= i)
mShapeIndexI[mShapeNumber].push_back(0);
if(copy.vertices.size() == initialVertices.size()) if(timeIndex(mTime,copy.morph.getRelevantTimes()[i],(mShapeIndexI[mShapeNumber])[i], j, x))
{ {
//Create if it doesn't already exist int indexI = (mShapeIndexI[mShapeNumber])[i];
if(shapeIndexI.size() == static_cast<std::size_t> (shapeNumber)) std::vector<Ogre::Vector3> relevantData = (copy.morph.getRelevantData()[i]);
{ float v1 = relevantData[indexI].x;
std::vector<int> vec; float v2 = relevantData[j].x;
shapeIndexI.push_back(vec); float t = v1 + (v2 - v1) * x;
}
if(time >= copy.morph.getStartTime() && time <= copy.morph.getStopTime()){ if ( t < 0 )
float x; t = 0;
for (unsigned int i = 0; i < copy.morph.getAdditionalVertices().size(); i++){ if ( t > 1 )
int j = 0; t = 1;
if(shapeIndexI[shapeNumber].size() <= i) if( t != 0 && initialVertices.size() == copy.morph.getAdditionalVertices()[i].size())
shapeIndexI[shapeNumber].push_back(0); for (unsigned int v = 0; v < initialVertices.size(); v++)
initialVertices[v] += ((copy.morph.getAdditionalVertices()[i])[v]) * t;
}
if(timeIndex(time,copy.morph.getRelevantTimes()[i],(shapeIndexI[shapeNumber])[i], j, x)){
int indexI = (shapeIndexI[shapeNumber])[i];
std::vector<Ogre::Vector3> relevantData = (copy.morph.getRelevantData()[i]);
float v1 = relevantData[indexI].x;
float v2 = relevantData[j].x;
float t = v1 + (v2 - v1) * x;
if ( t < 0 ) t = 0;
if ( t > 1 ) t = 1;
if( t != 0 && initialVertices.size() == copy.morph.getAdditionalVertices()[i].size())
{
for (unsigned int v = 0; v < initialVertices.size(); v++){
initialVertices[v] += ((copy.morph.getAdditionalVertices()[i])[v]) * t;
}
}
}
}
allvertices = &initialVertices;
} }
shapeNumber++;
} allvertices = &initialVertices;
} }
mShapeNumber++;
}
}
if(verticesToChange->size() > 0){ if(verticesToChange->size() > 0)
{
for(std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >::iterator iter = verticesToChange->begin(); for(std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >::iterator iter = verticesToChange->begin();
iter != verticesToChange->end(); iter++) iter != verticesToChange->end(); iter++)
@ -214,26 +228,25 @@ namespace MWRender{
Nif::NiSkinData::BoneInfoCopy* boneinfocopy = &(allshapesiter->boneinfo[inds[0].boneinfocopyindex]); Nif::NiSkinData::BoneInfoCopy* boneinfocopy = &(allshapesiter->boneinfo[inds[0].boneinfocopyindex]);
Ogre::Bone *bonePtr = 0; Ogre::Bone *bonePtr = 0;
Ogre::Vector3 vecPos; Ogre::Vector3 vecPos;
Ogre::Quaternion vecRot; Ogre::Quaternion vecRot;
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot>::iterator result = vecRotPos.find(boneinfocopy); std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot>::iterator result = mVecRotPos.find(boneinfocopy);
if(result == vecRotPos.end()){ if(result == mVecRotPos.end())
{
bonePtr = skel->getBone(boneinfocopy->bonename); bonePtr = skel->getBone(boneinfocopy->bonename);
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans; vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation; vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
PosAndRot both;
PosAndRot both; both.vecPos = vecPos;
both.vecPos = vecPos; both.vecRot = vecRot;
both.vecRot = vecRot; mVecRotPos[boneinfocopy] = both;
vecRotPos[boneinfocopy] = both;
} }
else{ else
{
PosAndRot both = result->second; PosAndRot both = result->second;
vecPos = both.vecPos; vecPos = both.vecPos;
vecRot = both.vecRot; vecRot = both.vecRot;
@ -241,263 +254,249 @@ namespace MWRender{
Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight; Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight;
for(std::size_t i = 1; i < inds.size(); i++)
{
for(std::size_t i = 1; i < inds.size(); i++){
boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]); boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]);
result = vecRotPos.find(boneinfocopy); result = mVecRotPos.find(boneinfocopy);
if(result == mVecRotPos.end())
if(result == vecRotPos.end()){ {
bonePtr = skel->getBone(boneinfocopy->bonename); bonePtr = skel->getBone(boneinfocopy->bonename);
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans; vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation; vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
PosAndRot both; PosAndRot both;
both.vecPos = vecPos; both.vecPos = vecPos;
both.vecRot = vecRot; both.vecRot = vecRot;
vecRotPos[boneinfocopy] = both; mVecRotPos[boneinfocopy] = both;
} }
else{ else
PosAndRot both = result->second; {
vecPos = both.vecPos; PosAndRot both = result->second;
vecRot = both.vecRot; vecPos = both.vecPos;
vecRot = both.vecRot;
} }
absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight; absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight;
}
Ogre::Real* addr = (pReal + 3 * verIndex);
*addr = absVertPos.x;
*(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z;
}
}
else
{
//Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(copy.bonename);
Ogre::Quaternion shaperot = copy.trafo.rotation;
Ogre::Vector3 shapetrans = copy.trafo.trans;
float shapescale = copy.trafo.scale;
std::vector<std::string> boneSequence = copy.boneSequence;
Ogre::Vector3 transmult;
Ogre::Quaternion rotmult;
float scale;
if(boneSequence.size() > 0)
{
std::vector<std::string>::iterator boneSequenceIter = boneSequence.begin();
if(skel->hasBone(*boneSequenceIter))
{
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
transmult = bonePtr->getPosition();
rotmult = bonePtr->getOrientation();
scale = bonePtr->getScale().x;
boneSequenceIter++;
for(; boneSequenceIter != boneSequence.end(); boneSequenceIter++)
{
if(skel->hasBone(*boneSequenceIter))
{
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
// Computes C = B + AxC*scale
transmult = transmult + rotmult * bonePtr->getPosition();
rotmult = rotmult * bonePtr->getOrientation();
scale = scale * bonePtr->getScale().x;
}
//std::cout << "Bone:" << *boneSequenceIter << " ";
}
transmult = transmult + rotmult * shapetrans;
rotmult = rotmult * shaperot;
scale = shapescale * scale;
//std::cout << "Position: " << transmult << "Rotation: " << rotmult << "\n";
}
}
else
{
transmult = shapetrans;
rotmult = shaperot;
scale = shapescale;
}
// Computes C = B + AxC*scale
// final_vector = old_vector + old_rotation*new_vector*old_scale/
for(unsigned int i = 0; i < allvertices->size(); i++)
{
Ogre::Vector3 current = transmult + rotmult * (*allvertices)[i];
Ogre::Real* addr = pReal + i * 3;
*addr = current.x;
*(addr+1) = current.y;
*(addr + 2) = current.z;
}/*
for(int i = 0; i < allnormals.size(); i++){
Ogre::Vector3 current =rotmult * allnormals[i];
Ogre::Real* addr = pRealNormal + i * 3;
*addr = current.x;
*(addr+1) = current.y;
*(addr + 2) = current.z;
}*/
}
vbuf->unlock();
}
}
bool Animation::timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x )
{
int count;
if ( (count = times.size()) > 0 )
{
if ( time <= times[0] )
{
i = j = 0;
x = 0.0;
return true;
}
if ( time >= times[count - 1] )
{
i = j = count - 1;
x = 0.0;
return true;
}
if ( i < 0 || i >= count )
i = 0;
float tI = times[i];
if ( time > tI )
{
j = i + 1;
float tJ;
while ( time >= ( tJ = times[j]) )
{
i = j++;
tI = tJ;
}
x = ( time - tI ) / ( tJ - tI );
return true;
}
else if ( time < tI )
{
j = i - 1;
float tJ;
while ( time <= ( tJ = times[j] ) )
{
i = j--;
tI = tJ;
}
x = ( time - tI ) / ( tJ - tI );
return true;
}
else
{
j = i;
x = 0.0;
return true;
}
}
else
return false;
}
void Animation::handleAnimationTransforms()
{
Ogre::SkeletonInstance* skel = mBase->getSkeleton();
Ogre::Bone* b = skel->getRootBone();
b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3)); //This is a trick
skel->_updateTransforms();
//skel->_notifyManualBonesDirty();
mBase->getAllAnimationStates()->_notifyDirty();
//mBase->_updateAnimation();
//mBase->_notifyMoved();
std::vector<Nif::NiKeyframeData>::iterator iter;
int slot = 0;
if(mTransformations)
{
for(iter = mTransformations->begin(); iter != mTransformations->end(); iter++)
{
if(mTime < iter->getStartTime() || mTime < mStartTime || mTime > iter->getStopTime())
{
slot++;
continue;
}
float x;
float x2;
const std::vector<Ogre::Quaternion> & quats = iter->getQuat();
const std::vector<float> & ttime = iter->gettTime();
const std::vector<float> & rtime = iter->getrTime();
int rindexJ = mRindexI[slot];
timeIndex(mTime, rtime, mRindexI[slot], rindexJ, x2);
int tindexJ = mTindexI[slot];
const std::vector<Ogre::Vector3> & translist1 = iter->getTranslist1();
timeIndex(mTime, ttime, mTindexI[slot], tindexJ, x);
Ogre::Vector3 t;
Ogre::Quaternion r;
bool bTrans = translist1.size() > 0;
bool bQuats = quats.size() > 0;
if(skel->hasBone(iter->getBonename()))
{
Ogre::Bone* bone = skel->getBone(iter->getBonename());
if(bTrans)
{
Ogre::Vector3 v1 = translist1[mTindexI[slot]];
Ogre::Vector3 v2 = translist1[tindexJ];
t = (v1 + (v2 - v1) * x);
bone->setPosition(t);
} }
Ogre::Real* addr = (pReal + 3 * verIndex);
*addr = absVertPos.x; if(bQuats)
*(addr+1) = absVertPos.y; {
*(addr+2) = absVertPos.z; r = Ogre::Quaternion::Slerp(x2, quats[mRindexI[slot]], quats[rindexJ], true);
bone->setOrientation(r);
}
} }
slot++;
}
skel->_updateTransforms();
} mBase->getAllAnimationStates()->_notifyDirty();
else }
{
//Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(copy.bonename);
Ogre::Quaternion shaperot = copy.trafo.rotation;
Ogre::Vector3 shapetrans = copy.trafo.trans;
float shapescale = copy.trafo.scale;
std::vector<std::string> boneSequence = copy.boneSequence;
Ogre::Vector3 transmult;
Ogre::Quaternion rotmult;
float scale;
if(boneSequence.size() > 0){
std::vector<std::string>::iterator boneSequenceIter = boneSequence.begin();
if(skel->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
transmult = bonePtr->getPosition();
rotmult = bonePtr->getOrientation();
scale = bonePtr->getScale().x;
boneSequenceIter++;
for(; boneSequenceIter != boneSequence.end(); boneSequenceIter++)
{
if(skel->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
// Computes C = B + AxC*scale
transmult = transmult + rotmult * bonePtr->getPosition();
rotmult = rotmult * bonePtr->getOrientation();
scale = scale * bonePtr->getScale().x;
}
//std::cout << "Bone:" << *boneSequenceIter << " ";
}
transmult = transmult + rotmult * shapetrans;
rotmult = rotmult * shaperot;
scale = shapescale * scale;
//std::cout << "Position: " << transmult << "Rotation: " << rotmult << "\n";
}
}
else
{
transmult = shapetrans;
rotmult = shaperot;
scale = shapescale;
}
// Computes C = B + AxC*scale
// final_vector = old_vector + old_rotation*new_vector*old_scale/
for(unsigned int i = 0; i < allvertices->size(); i++){
Ogre::Vector3 current = transmult + rotmult * (*allvertices)[i];
Ogre::Real* addr = pReal + i * 3;
*addr = current.x;
*(addr+1) = current.y;
*(addr + 2) = current.z;
}/*
for(int i = 0; i < allnormals.size(); i++){
Ogre::Vector3 current =rotmult * allnormals[i];
Ogre::Real* addr = pRealNormal + i * 3;
*addr = current.x;
*(addr+1) = current.y;
*(addr + 2) = current.z;
}*/
}
vbuf->unlock();
}
} }
bool Animation::timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x ){
int count;
if ( (count = times.size()) > 0 )
{
if ( time <= times[0] )
{
i = j = 0;
x = 0.0;
return true;
}
if ( time >= times[count - 1] )
{
i = j = count - 1;
x = 0.0;
return true;
}
if ( i < 0 || i >= count )
i = 0;
float tI = times[i];
if ( time > tI )
{
j = i + 1;
float tJ;
while ( time >= ( tJ = times[j]) )
{
i = j++;
tI = tJ;
}
x = ( time - tI ) / ( tJ - tI );
return true;
}
else if ( time < tI )
{
j = i - 1;
float tJ;
while ( time <= ( tJ = times[j] ) )
{
i = j--;
tI = tJ;
}
x = ( time - tI ) / ( tJ - tI );
return true;
}
else
{
j = i;
x = 0.0;
return true;
}
}
else
return false;
}
void Animation::handleAnimationTransforms(){
Ogre::SkeletonInstance* skel = base->getSkeleton();
Ogre::Bone* b = skel->getRootBone();
b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3)); //This is a trick
skel->_updateTransforms();
//skel->_notifyManualBonesDirty();
base->getAllAnimationStates()->_notifyDirty();
//base->_updateAnimation();
//base->_notifyMoved();
std::vector<Nif::NiKeyframeData>::iterator iter;
int slot = 0;
if(transformations){
for(iter = transformations->begin(); iter != transformations->end(); iter++){
if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime())
{
slot++;
continue;
}
float x;
float x2;
const std::vector<Ogre::Quaternion> & quats = iter->getQuat();
const std::vector<float> & ttime = iter->gettTime();
const std::vector<float> & rtime = iter->getrTime();
int rindexJ = rindexI[slot];
timeIndex(time, rtime, rindexI[slot], rindexJ, x2);
int tindexJ = tindexI[slot];
const std::vector<Ogre::Vector3> & translist1 = iter->getTranslist1();
timeIndex(time, ttime, tindexI[slot], tindexJ, x);
Ogre::Vector3 t;
Ogre::Quaternion r;
bool bTrans = translist1.size() > 0;
bool bQuats = quats.size() > 0;
if(skel->hasBone(iter->getBonename())){
Ogre::Bone* bone = skel->getBone(iter->getBonename());
if(bTrans){
Ogre::Vector3 v1 = translist1[tindexI[slot]];
Ogre::Vector3 v2 = translist1[tindexJ];
t = (v1 + (v2 - v1) * x);
bone->setPosition(t);
}
if(bQuats){
r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true);
bone->setOrientation(r);
}
}
slot++;
}
skel->_updateTransforms();
base->getAllAnimationStates()->_notifyDirty();
}
}
} }

View file

@ -1,17 +1,13 @@
#ifndef _GAME_RENDER_ANIMATION_H #ifndef _GAME_RENDER_ANIMATION_H
#define _GAME_RENDER_ANIMATION_H #define _GAME_RENDER_ANIMATION_H
#include <components/nif/data.hpp>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include "../mwworld/refdata.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp" #include "../mwworld/actiontalk.hpp"
#include <components/nif/node.hpp> #include <components/nif/node.hpp>
#include <map>
#include <openengine/bullet/physic.hpp> #include <openengine/bullet/physic.hpp>
namespace MWRender{ namespace MWRender{
struct PosAndRot{ struct PosAndRot{
@ -22,36 +18,30 @@ struct PosAndRot{
class Animation{ class Animation{
protected: protected:
Ogre::SceneNode* insert; Ogre::SceneNode* mInsert;
OEngine::Render::OgreRenderer &mRend; OEngine::Render::OgreRenderer &mRend;
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot> vecRotPos; std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot> mVecRotPos;
static std::map<std::string, int> mUniqueIDs; static std::map<std::string, int> sUniqueIDs;
float mTime;
float mStartTime;
float mStopTime;
int mAnimate;
float time; //Represents a rotation index for each bone
float startTime; std::vector<int>mRindexI;
float stopTime;
int animate;
//Represents a rotation index for each bone
std::vector<int>rindexI;
//Represents a translation index for each bone //Represents a translation index for each bone
std::vector<int>tindexI; std::vector<int>mTindexI;
//Only shapes with morphing data will use a shape number //Only shapes with morphing data will use a shape number
int shapeNumber; int mShapeNumber;
std::vector<std::vector<int> > shapeIndexI; std::vector<std::vector<int> > mShapeIndexI;
//Ogre::SkeletonInstance* skel; //Ogre::SkeletonInstance* skel;
std::vector<Nif::NiTriShapeCopy>* shapes; //All the NiTriShapeData for a creature std::vector<Nif::NiTriShapeCopy>* mShapes; //All the NiTriShapeData for a creature
std::vector<Nif::NiKeyframeData>* mTransformations;
std::map<std::string,float>* mTextmappings;
std::vector<Nif::NiKeyframeData>* transformations; Ogre::Entity* mBase;
std::map<std::string,float>* textmappings;
Ogre::Entity* base;
void handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel); void handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel);
void handleAnimationTransforms(); void handleAnimationTransforms();
bool timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x ); bool timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x );
@ -63,7 +53,6 @@ class Animation{
void startScript(std::string groupname, int mode, int loops); void startScript(std::string groupname, int mode, int loops);
void stopScript(); void stopScript();
virtual ~Animation(); virtual ~Animation();
}; };

View file

@ -12,26 +12,28 @@ using namespace Ogre;
using namespace NifOgre; using namespace NifOgre;
namespace MWRender{ namespace MWRender{
CreatureAnimation::~CreatureAnimation(){ CreatureAnimation::~CreatureAnimation()
{
}
} CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend): Animation(_rend)
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend): Animation(_rend){ {
insert = ptr.getRefData().getBaseNode(); mInsert = ptr.getRefData().getBaseNode();
MWWorld::LiveCellRef<ESM::Creature> *ref = MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
ptr.get<ESM::Creature>();
assert (ref->base != NULL); assert (ref->base != NULL);
if(!ref->base->model.empty()){ if(!ref->base->model.empty())
{
const std::string &mesh = "meshes\\" + ref->base->model; const std::string &mesh = "meshes\\" + ref->base->model;
std::string meshNumbered = mesh + getUniqueID(mesh) + ">|"; std::string meshNumbered = mesh + getUniqueID(mesh) + ">|";
NifOgre::NIFLoader::load(meshNumbered); NifOgre::NIFLoader::load(meshNumbered);
base = mRend.getScene()->createEntity(meshNumbered); mBase = mRend.getScene()->createEntity(meshNumbered);
base->setVisibilityFlags(RV_Actors); mBase->setVisibilityFlags(RV_Actors);
bool transparent = false; bool transparent = false;
for (unsigned int i=0; i<base->getNumSubEntities(); ++i) for (unsigned int i=0; i < mBase->getNumSubEntities(); ++i)
{ {
Ogre::MaterialPtr mat = base->getSubEntity(i)->getMaterial(); Ogre::MaterialPtr mat = mBase->getSubEntity(i)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements()) while (techIt.hasMoreElements())
{ {
@ -46,46 +48,51 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::O
} }
} }
} }
base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); mBase->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
std::string meshZero = mesh + "0000>|"; std::string meshZero = mesh + "0000>|";
if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){ if((mTransformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero)))
{
for(std::size_t init = 0; init < transformations->size(); init++){ for(std::size_t init = 0; init < mTransformations->size(); init++)
rindexI.push_back(0); {
tindexI.push_back(0); mRindexI.push_back(0);
} mTindexI.push_back(0);
stopTime = transformations->begin()->getStopTime(); }
startTime = transformations->begin()->getStartTime(); mStopTime = mTransformations->begin()->getStopTime();
shapes = (NIFLoader::getSingletonPtr())->getShapes(meshZero); mStartTime = mTransformations->begin()->getStartTime();
mShapes = (NIFLoader::getSingletonPtr())->getShapes(meshZero);
} }
textmappings = NIFLoader::getSingletonPtr()->getTextIndices(meshZero); mTextmappings = NIFLoader::getSingletonPtr()->getTextIndices(meshZero);
insert->attachObject(base); mInsert->attachObject(mBase);
} }
} }
void CreatureAnimation::runAnimation(float timepassed){ void CreatureAnimation::runAnimation(float timepassed)
vecRotPos.clear(); {
if(animate > 0){ mVecRotPos.clear();
//Add the amount of time passed to time if(mAnimate > 0)
{
//Add the amount of time passed to time
//Handle the animation transforms dependent on time //Handle the animation transforms dependent on time
//Handle the shapes dependent on animation transforms //Handle the shapes dependent on animation transforms
time += timepassed; mTime += timepassed;
if(time >= stopTime){ if(mTime >= mStopTime)
animate--; {
mAnimate--;
//std::cout << "Stopping the animation\n"; //std::cout << "Stopping the animation\n";
if(animate == 0) if(mAnimate == 0)
time = stopTime; mTime = mStopTime;
else else
time = startTime + (time - stopTime); mTime = mStartTime + (mTime - mStopTime);
} }
handleAnimationTransforms(); handleAnimationTransforms();
handleShapes(shapes, base, base->getSkeleton()); handleShapes(mShapes, mBase, mBase->getSkeleton());
} }
} }
} }

View file

@ -2,11 +2,7 @@
#define _GAME_RENDER_CREATUREANIMATION_H #define _GAME_RENDER_CREATUREANIMATION_H
#include "animation.hpp" #include "animation.hpp"
#include <components/nif/node.hpp>
#include "../mwworld/refdata.hpp"
#include "../mwworld/ptr.hpp"
#include "components/nifogre/ogre_nif_loader.hpp" #include "components/nifogre/ogre_nif_loader.hpp"
@ -17,8 +13,7 @@ class CreatureAnimation: public Animation{
public: public:
virtual ~CreatureAnimation(); virtual ~CreatureAnimation();
CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend); CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend);
virtual void runAnimation(float timepassed); virtual void runAnimation(float timepassed);
}; };
} }

File diff suppressed because it is too large Load diff

View file

@ -1,73 +1,63 @@
#ifndef _GAME_RENDER_NPCANIMATION_H #ifndef _GAME_RENDER_NPCANIMATION_H
#define _GAME_RENDER_NPCANIMATION_H #define _GAME_RENDER_NPCANIMATION_H
#include "animation.hpp"
#include <components/nif/data.hpp>
#include <components/nif/node.hpp>
#include <components/nif/property.hpp>
#include <components/nif/controller.hpp>
#include <components/nif/extra.hpp>
#include <utility>
#include "../mwworld/refdata.hpp" #include "animation.hpp"
#include "../mwworld/ptr.hpp"
#include "components/nifogre/ogre_nif_loader.hpp" #include "components/nifogre/ogre_nif_loader.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwclass/npc.hpp" #include "../mwclass/npc.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "components/esm/loadarmo.hpp"
namespace MWRender{ namespace MWRender{
class NpcAnimation: public Animation{ class NpcAnimation: public Animation{
private: private:
MWWorld::InventoryStore& inv; MWWorld::InventoryStore& mInv;
int mStateID; int mStateID;
//Free Parts //Free Parts
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> chest; std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mChest;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> skirt; std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mSkirt;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> lhand; std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mLhand;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> rhand; std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mRhand;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> tail; std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mTail;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> lFreeFoot; std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mLFreeFoot;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> rFreeFoot; std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mRFreeFoot;
int partslots[27]; //Each part slot is taken by clothing, armor, or is empty int mPartslots[27]; //Each part slot is taken by clothing, armor, or is empty
int partpriorities[27]; int mPartPriorities[27];
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> zero; std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mZero;
//Bounded Parts
Ogre::Entity* lclavicle;
Ogre::Entity* rclavicle;
Ogre::Entity* rupperArm;
Ogre::Entity* lupperArm;
Ogre::Entity* rUpperLeg;
Ogre::Entity* lUpperLeg;
Ogre::Entity* lForearm;
Ogre::Entity* rForearm;
Ogre::Entity* lWrist;
Ogre::Entity* rWrist;
Ogre::Entity* rKnee;
Ogre::Entity* lKnee;
Ogre::Entity* neck;
Ogre::Entity* rAnkle;
Ogre::Entity* lAnkle;
Ogre::Entity* groin;
Ogre::Entity* lfoot;
Ogre::Entity* rfoot;
Ogre::Entity* hair;
Ogre::Entity* head;
Ogre::SceneNode* insert;
//Bounded Parts
Ogre::Entity* lclavicle;
Ogre::Entity* rclavicle;
Ogre::Entity* rupperArm;
Ogre::Entity* lupperArm;
Ogre::Entity* rUpperLeg;
Ogre::Entity* lUpperLeg;
Ogre::Entity* lForearm;
Ogre::Entity* rForearm;
Ogre::Entity* lWrist;
Ogre::Entity* rWrist;
Ogre::Entity* rKnee;
Ogre::Entity* lKnee;
Ogre::Entity* neck;
Ogre::Entity* rAnkle;
Ogre::Entity* lAnkle;
Ogre::Entity* groin;
Ogre::Entity* lfoot;
Ogre::Entity* rfoot;
Ogre::Entity* hair;
Ogre::Entity* head;
Ogre::SceneNode* insert;
bool isBeast; bool isBeast;
bool isFemale; bool isFemale;
std::string headModel; std::string headModel;
std::string hairModel; std::string hairModel;
std::string npcName; std::string npcName;
std::string bodyRaceID; std::string bodyRaceID;
float timeToChange; float timeToChange;
MWWorld::ContainerStoreIterator robe; MWWorld::ContainerStoreIterator robe;
MWWorld::ContainerStoreIterator helmet; MWWorld::ContainerStoreIterator helmet;
MWWorld::ContainerStoreIterator shirt; MWWorld::ContainerStoreIterator shirt;
MWWorld::ContainerStoreIterator cuirass; MWWorld::ContainerStoreIterator cuirass;
@ -80,22 +70,21 @@ private:
MWWorld::ContainerStoreIterator rightglove; MWWorld::ContainerStoreIterator rightglove;
MWWorld::ContainerStoreIterator skirtiter; MWWorld::ContainerStoreIterator skirtiter;
public: public:
NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv);
virtual ~NpcAnimation(); virtual ~NpcAnimation();
Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename);
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> insertFreePart(const std::string &mesh, const std::string& suffix); std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> insertFreePart(const std::string &mesh, const std::string& suffix);
void insertFootPart(int type, const std::string &mesh); void insertFootPart(int type, const std::string &mesh);
virtual void runAnimation(float timepassed); virtual void runAnimation(float timepassed);
void updateParts(); void updateParts();
void removeIndividualPart(int type); void removeIndividualPart(int type);
void reserveIndividualPart(int type, int group, int priority); void reserveIndividualPart(int type, int group, int priority);
bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh);
void removePartGroup(int group); void removePartGroup(int group);
void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts); void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts);
}; };
} }
#endif #endif

View file

@ -1,25 +1,14 @@
#ifndef _GAME_RENDERING_MANAGER_H #ifndef _GAME_RENDERING_MANAGER_H
#define _GAME_RENDERING_MANAGER_H #define _GAME_RENDERING_MANAGER_H
#include "sky.hpp" #include "sky.hpp"
#include "terrain.hpp" #include "terrain.hpp"
#include "debugging.hpp" #include "debugging.hpp"
#include "../mwworld/class.hpp"
#include <OgreWindowEventUtilities.h>
#include <utility>
#include <openengine/ogre/renderer.hpp>
#include <openengine/ogre/fader.hpp> #include <openengine/ogre/fader.hpp>
#include <openengine/bullet/physic.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <vector>
#include <string>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "renderinginterface.hpp" #include "renderinginterface.hpp"
@ -45,7 +34,6 @@ namespace MWWorld
namespace MWRender namespace MWRender
{ {
class Shadows; class Shadows;
class ShaderHelper; class ShaderHelper;
class LocalMap; class LocalMap;

View file

@ -165,4 +165,9 @@ op 0x2000160: SetFlee
op 0x2000161: SetFlee, explicit reference op 0x2000161: SetFlee, explicit reference
op 0x2000162: SetAlarm op 0x2000162: SetAlarm
op 0x2000163: SetAlarm, explicit reference op 0x2000163: SetAlarm, explicit reference
opcodes 0x2000164-0x3ffffff unused op 0x2000164: SetScale
op 0x2000165: SetScale, explicit reference
op 0x2000166: SetAngle
op 0x2000167: SetAngle, explicit reference
opcodes 0x2000168-0x3ffffff unused

View file

@ -15,6 +15,7 @@
#include "controlextensions.hpp" #include "controlextensions.hpp"
#include "dialogueextensions.hpp" #include "dialogueextensions.hpp"
#include "animationextensions.hpp" #include "animationextensions.hpp"
#include "transformationextensions.hpp"
namespace MWScript namespace MWScript
{ {
@ -31,6 +32,7 @@ namespace MWScript
Control::registerExtensions (extensions); Control::registerExtensions (extensions);
Dialogue::registerExtensions (extensions); Dialogue::registerExtensions (extensions);
Animation::registerExtensions (extensions); Animation::registerExtensions (extensions);
Transformation::registerExtensions (extensions);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -47,5 +49,6 @@ namespace MWScript
Control::installOpcodes (interpreter); Control::installOpcodes (interpreter);
Dialogue::installOpcodes (interpreter); Dialogue::installOpcodes (interpreter);
Animation::installOpcodes (interpreter); Animation::installOpcodes (interpreter);
Transformation::installOpcodes (interpreter);
} }
} }

View file

@ -2,7 +2,6 @@
#define GAME_SCRIPT_SCRIPTMANAGER_H #define GAME_SCRIPT_SCRIPTMANAGER_H
#include <map> #include <map>
#include <vector>
#include <string> #include <string>
#include <components/compiler/streamerrorhandler.hpp> #include <components/compiler/streamerrorhandler.hpp>

View file

@ -536,6 +536,7 @@ namespace MWScript
} }
}; };
const int numberOfAttributes = 8; const int numberOfAttributes = 8;
const int opcodeGetAttribute = 0x2000027; const int opcodeGetAttribute = 0x2000027;

View file

@ -0,0 +1,140 @@
#include <boost/algorithm/string.hpp>
#include <components/esm_store/store.hpp>
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/class.hpp"
#include "interpretercontext.hpp"
#include "ref.hpp"
#include "OgreSceneNode.h"
namespace MWScript
{
namespace Transformation
{
template<class R>
class OpSetScale : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Float scale = runtime[0].mFloat;
runtime.pop();
MWBase::Environment::get().getWorld()->scaleObject(ptr,scale);
}
};
template<class R>
class OpGetScale : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push(ptr.getCellRef().scale);
}
};
template<class R>
class OpSetAngle : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Float angle = runtime[0].mFloat;
runtime.pop();
float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees();
float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees();
float az = Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees();
if(axis == "X")
{
MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az);
}
if(axis == "Y")
{
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az);
}
if(axis == "Z")
{
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle);
}
}
};
template<class R>
class OpGetAngle : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
if(axis == "X")
{
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees());
}
if(axis == "Y")
{
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees());
}
if(axis == "Z")
{
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees());
}
}
};
const int opcodeSetScale = 0x2000164;
const int opcodeSetScaleExplicit = 0x2000165;
const int opcodeSetAngle = 0x2000166;
const int opcodeSetAngleExplicit = 0x2000167;
const int opcodeGetScale = 0x2000168;
const int opcodeGetScaleExplicit = 0x2000169;
const int opcodeGetAngle = 0x200016a;
const int opcodeGetAngleExplicit = 0x200016b;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction("setscale","f",opcodeSetScale,opcodeSetScaleExplicit);
extensions.registerFunction("getscale",'f',"",opcodeGetScale,opcodeGetScaleExplicit);
extensions.registerInstruction("setangle","Sf",opcodeSetAngle,opcodeSetAngleExplicit);
extensions.registerFunction("getangle",'f',"S",opcodeGetAngle,opcodeGetAngleExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5(opcodeSetScale,new OpSetScale<ImplicitRef>);
interpreter.installSegment5(opcodeSetScaleExplicit,new OpSetScale<ExplicitRef>);
interpreter.installSegment5(opcodeSetAngle,new OpSetAngle<ImplicitRef>);
interpreter.installSegment5(opcodeSetAngleExplicit,new OpSetAngle<ExplicitRef>);
interpreter.installSegment5(opcodeGetScale,new OpGetScale<ImplicitRef>);
interpreter.installSegment5(opcodeGetScaleExplicit,new OpGetScale<ExplicitRef>);
interpreter.installSegment5(opcodeGetAngle,new OpGetAngle<ImplicitRef>);
interpreter.installSegment5(opcodeGetAngleExplicit,new OpGetAngle<ExplicitRef>);
}
}
}

View file

@ -0,0 +1,25 @@
#ifndef GAME_SCRIPT_TRANSFORMATIONEXTENSIONS_H
#define GAME_SCRIPT_TRANSFORMATIONEXTENSIONS_H
namespace Compiler
{
class Extensions;
}
namespace Interpreter
{
class Interpreter;
}
namespace MWScript
{
/// \brief stats-related script functionality (creatures and NPCs)
namespace Transformation
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
}
}
#endif

View file

@ -3,6 +3,8 @@
#include <OgreVector3.h> #include <OgreVector3.h>
#include "soundmanager.hpp"
namespace MWSound namespace MWSound
{ {
class Sound class Sound

View file

@ -5,6 +5,8 @@
#include <utility> #include <utility>
#include <map> #include <map>
#include <boost/shared_ptr.hpp>
#include <OgreResourceGroupManager.h> #include <OgreResourceGroupManager.h>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>

View file

@ -1,9 +1,5 @@
#include "cells.hpp" #include "cells.hpp"
#include <cctype>
#include <algorithm>
#include <components/esm_store/store.hpp> #include <components/esm_store/store.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"

View file

@ -4,9 +4,6 @@
#include <components/esm/records.hpp> #include <components/esm/records.hpp>
#include <list> #include <list>
#include <string>
#include <vector>
#include <stdexcept>
#include <algorithm> #include <algorithm>
#include "refdata.hpp" #include "refdata.hpp"

View file

@ -204,4 +204,12 @@ namespace MWWorld
{ {
return ""; return "";
} }
void Class::adjustScale(const MWWorld::Ptr& ptr,float& scale) const
{
}
void Class::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const
{
}
} }

View file

@ -200,6 +200,10 @@ namespace MWWorld
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
/// (default implementation: return empty string) /// (default implementation: return empty string)
virtual void adjustScale(const MWWorld::Ptr& ptr,float& scale) const;
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
}; };
} }

View file

@ -3,8 +3,6 @@
#include <iterator> #include <iterator>
#include "cellstore.hpp"
#include "refdata.hpp"
#include "ptr.hpp" #include "ptr.hpp"
namespace ESM namespace ESM

View file

@ -165,9 +165,6 @@ namespace MWWorld
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin()); for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
iter!=actors.end(); ++iter) iter!=actors.end(); ++iter)
{ {
OEngine::Physic::PhysicActor* act = mEngine->getCharacter(iter->first);
//if(iter->first == "player")
// std::cout << "This is player\n";
//dirty stuff to get the camera orientation. Must be changed! //dirty stuff to get the camera orientation. Must be changed!
Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first); Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first);
@ -177,46 +174,28 @@ namespace MWWorld
Ogre::Quaternion yawQuat = yawNode->getOrientation(); Ogre::Quaternion yawQuat = yawNode->getOrientation();
Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
// unused
//Ogre::Quaternion both = yawQuat * pitchQuat;
playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
playerphysics->ps.viewangles.z = 0;
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90; playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
if(mFreeFly)
{
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
pm_ref.rightmove = -dir1.x;
pm_ref.forwardmove = dir1.z;
pm_ref.upmove = dir1.y;
//std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n";
//playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
//std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n";
dir = 0.07*(yawQuat*pitchQuat*dir1);
}
else
{
Ogre::Quaternion quat = yawNode->getOrientation(); Ogre::Quaternion quat = yawNode->getOrientation();
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
pm_ref.rightmove = -dir1.x; pm_ref.rightmove = -iter->second.x;
pm_ref.forwardmove = dir1.z; pm_ref.forwardmove = -iter->second.y;
pm_ref.upmove = dir1.y; pm_ref.upmove = iter->second.z;
dir = 0.025*(quat*dir1);
} }
//set the walk direction
act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
}
mEngine->stepSimulation(dt); mEngine->stepSimulation(dt);
} }
@ -234,10 +213,6 @@ namespace MWWorld
if(it->first == "player"){ if(it->first == "player"){
coord = playerphysics->ps.origin; coord = playerphysics->ps.origin;
//std::cout << "ZCoord: " << coord.z << "\n";
//std::cout << "Coord" << coord << "\n";
//coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y
} }
@ -262,6 +237,7 @@ namespace MWWorld
void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh, void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position) const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
{ {
handleToMesh[handle] = mesh;
OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale); OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale);
mEngine->addRigidBody(body); mEngine->addRigidBody(body);
btTransform tr; btTransform tr;
@ -314,17 +290,27 @@ namespace MWWorld
void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation) void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation)
{ {
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
{ {
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
// start positions others than 0, 0, 0
act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
} }
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
{
body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
}
} }
void PhysicsSystem::scaleObject (const std::string& handle, float scale) void PhysicsSystem::scaleObject (const std::string& handle, float scale)
{ {
if(handleToMesh.find(handle) != handleToMesh.end())
{
btTransform transform = mEngine->getRigidBody(handle)->getWorldTransform();
removeObject(handle);
Ogre::Quaternion quat = Ogre::Quaternion(transform.getRotation().getW(), transform.getRotation().getX(), transform.getRotation().getY(), transform.getRotation().getZ());
Ogre::Vector3 vec = Ogre::Vector3(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ());
addObject(handle, handleToMesh[handle], quat, scale, vec);
}
} }
bool PhysicsSystem::toggleCollisionMode() bool PhysicsSystem::toggleCollisionMode()

View file

@ -1,9 +1,7 @@
#ifndef GAME_MWWORLD_PHYSICSSYSTEM_H #ifndef GAME_MWWORLD_PHYSICSSYSTEM_H
#define GAME_MWWORLD_PHYSICSSYSTEM_H #define GAME_MWWORLD_PHYSICSSYSTEM_H
#include <vector>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include <openengine/bullet/physic.hpp>
#include "ptr.hpp" #include "ptr.hpp"
#include <openengine/bullet/pmove.h> #include <openengine/bullet/pmove.h>
@ -72,6 +70,7 @@ namespace MWWorld
OEngine::Physic::PhysicEngine* mEngine; OEngine::Physic::PhysicEngine* mEngine;
bool mFreeFly; bool mFreeFly;
playerMove* playerphysics; playerMove* playerphysics;
std::map<std::string, std::string> handleToMesh;
PhysicsSystem (const PhysicsSystem&); PhysicsSystem (const PhysicsSystem&);
PhysicsSystem& operator= (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&);

View file

@ -1,12 +1,8 @@
#ifndef GAME_MWWORLD_PTR_H #ifndef GAME_MWWORLD_PTR_H
#define GAME_MWWORLD_PTR_H #define GAME_MWWORLD_PTR_H
#include <cassert>
#include <boost/any.hpp> #include <boost/any.hpp>
#include <components/esm/loadcell.hpp>
#include "cellstore.hpp" #include "cellstore.hpp"
namespace MWWorld namespace MWWorld

View file

@ -1,8 +1,6 @@
#ifndef GAME_MWWORLD_REFDATA_H #ifndef GAME_MWWORLD_REFDATA_H
#define GAME_MWWORLD_REFDATA_H #define GAME_MWWORLD_REFDATA_H
#include <string>
#include <components/esm/defs.hpp> #include <components/esm/defs.hpp>
#include "../mwscript/locals.hpp" #include "../mwscript/locals.hpp"

View file

@ -11,9 +11,7 @@
#include "../mwworld/manualref.hpp" /// FIXME #include "../mwworld/manualref.hpp" /// FIXME
#include "ptr.hpp"
#include "player.hpp" #include "player.hpp"
#include "class.hpp"
#include "localscripts.hpp" #include "localscripts.hpp"
#include "cellfunctors.hpp" #include "cellfunctors.hpp"

View file

@ -1,15 +1,7 @@
#ifndef GAME_MWWORLD_SCENE_H #ifndef GAME_MWWORLD_SCENE_H
#define GAME_MWWORLD_SCENE_H #define GAME_MWWORLD_SCENE_H
#include <vector>
#include <map>
#include <boost/filesystem.hpp>
#include <openengine/bullet/physic.hpp>
#include "../mwrender/renderingmanager.hpp" #include "../mwrender/renderingmanager.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "physicssystem.hpp" #include "physicssystem.hpp"
#include "globals.hpp" #include "globals.hpp"

View file

@ -1,8 +1,5 @@
#include "worldimp.hpp" #include "worldimp.hpp"
#include <cmath>
#include <iostream>
#include <components/bsa/bsa_archive.hpp> #include <components/bsa/bsa_archive.hpp>
#include <components/files/collections.hpp> #include <components/files/collections.hpp>
@ -17,16 +14,10 @@
#include "../mwgui/window_manager.hpp" #include "../mwgui/window_manager.hpp"
#include "ptr.hpp"
#include "class.hpp"
#include "player.hpp" #include "player.hpp"
#include "weather.hpp"
#include "manualref.hpp" #include "manualref.hpp"
#include "refdata.hpp"
#include "globals.hpp"
#include "cellfunctors.hpp" #include "cellfunctors.hpp"
#include <OgreVector3.h>
using namespace Ogre; using namespace Ogre;
namespace namespace
@ -597,6 +588,31 @@ namespace MWWorld
mPhysics->moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z)); mPhysics->moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z));
} }
void World::scaleObject (const Ptr& ptr, float scale)
{
MWWorld::Class::get(ptr).adjustScale(ptr,scale);
ptr.getCellRef().scale = scale;
//scale = scale/ptr.getRefData().getBaseNode()->getScale().x;
ptr.getRefData().getBaseNode()->setScale(scale,scale,scale);
mPhysics->scaleObject( ptr.getRefData().getHandle(), scale );
}
void World::rotateObject (const Ptr& ptr,float x,float y,float z)
{
MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z);
ptr.getRefData().getPosition().rot[0] = Ogre::Degree(x).valueRadians();
ptr.getRefData().getPosition().rot[1] = Ogre::Degree(y).valueRadians();
ptr.getRefData().getPosition().rot[2] = Ogre::Degree(z).valueRadians();
Ogre::Quaternion rotx(Ogre::Degree(x),Ogre::Vector3::UNIT_X);
Ogre::Quaternion roty(Ogre::Degree(y),Ogre::Vector3::UNIT_Y);
Ogre::Quaternion rotz(Ogre::Degree(z),Ogre::Vector3::UNIT_Z);
ptr.getRefData().getBaseNode()->setOrientation(rotz*roty*rotx);
mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation());
}
void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const
{ {
const int cellSize = 8192; const int cellSize = 8192;

View file

@ -1,32 +1,17 @@
#ifndef GAME_MWWORLD_WORLDIMP_H #ifndef GAME_MWWORLD_WORLDIMP_H
#define GAME_MWWORLD_WORLDIMP_H #define GAME_MWWORLD_WORLDIMP_H
#include <vector>
#include <map>
#include <boost/filesystem.hpp>
#include <components/esm_store/store.hpp> #include <components/esm_store/store.hpp>
#include <components/settings/settings.hpp>
#include "../mwrender/debugging.hpp" #include "../mwrender/debugging.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "refdata.hpp"
#include "ptr.hpp" #include "ptr.hpp"
#include "globals.hpp"
#include "scene.hpp" #include "scene.hpp"
#include "physicssystem.hpp" #include "physicssystem.hpp"
#include "cells.hpp" #include "cells.hpp"
#include "localscripts.hpp" #include "localscripts.hpp"
#include "timestamp.hpp" #include "timestamp.hpp"
#include <openengine/bullet/physic.hpp>
#include <openengine/ogre/fader.hpp>
#include <OgreTimer.h>
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
namespace Ogre namespace Ogre
@ -219,6 +204,10 @@ namespace MWWorld
virtual void moveObject (const Ptr& ptr, float x, float y, float z); virtual void moveObject (const Ptr& ptr, float x, float y, float z);
virtual void scaleObject (const Ptr& ptr, float scale);
virtual void rotateObject (const Ptr& ptr,float x,float y,float z);
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
const; const;
///< Convert cell numbers to position. ///< Convert cell numbers to position.

View file

@ -72,5 +72,11 @@ add_library(components STATIC ${COMPONENT_FILES})
target_link_libraries(components ${Boost_LIBRARIES} ${OGRE_LIBRARIES}) target_link_libraries(components ${Boost_LIBRARIES} ${OGRE_LIBRARIES})
# Fix for not visible pthreads functions for linker with glibc 2.15
if (UNIX AND NOT APPLE)
target_link_libraries(components ${CMAKE_THREAD_LIBS_INIT})
endif()
# Make the variable accessible for other subdirectories # Make the variable accessible for other subdirectories
set(COMPONENT_FILES ${COMPONENT_FILES} PARENT_SCOPE) set(COMPONENT_FILES ${COMPONENT_FILES} PARENT_SCOPE)

View file

@ -28,13 +28,11 @@
#include <OgreArchiveFactory.h> #include <OgreArchiveFactory.h>
#include <OgreArchiveManager.h> #include <OgreArchiveManager.h>
#include "bsa_file.hpp" #include "bsa_file.hpp"
#include <libs/mangle/stream/clients/ogre_datastream.hpp>
namespace namespace
{ {
using namespace Ogre; using namespace Ogre;
using namespace Mangle::Stream;
using namespace Bsa; using namespace Bsa;
struct ciLessBoost : std::binary_function<std::string, std::string, bool> struct ciLessBoost : std::binary_function<std::string, std::string, bool>
@ -73,14 +71,16 @@ class DirArchive: public Ogre::FileSystemArchive
{ {
{ {
String passed = filename; String passed = filename;
if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<' if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':' || filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|') || filename.at(filename.length() - 1) == '|')
{
passed = filename.substr(0, filename.length() - 2); passed = filename.substr(0, filename.length() - 2);
}
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
copy = passed; copy = passed;
} }
@ -226,19 +226,18 @@ public:
BSAFile *narc = (BSAFile*)&arc; BSAFile *narc = (BSAFile*)&arc;
String passed = filename; String passed = filename;
if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<' if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':' || filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|') || filename.at(filename.length() - 1) == '|')
{
passed = filename.substr(0, filename.length() - 2); passed = filename.substr(0, filename.length() - 2);
}
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
// Open the file // Open the file
StreamPtr strm = narc->getFile(passed.c_str()); return narc->getFile(passed.c_str());
// Wrap it into an Ogre::DataStream.
return DataStreamPtr(new Mangle2OgreStream(strm));
} }
bool exists(const String& filename) { bool exists(const String& filename) {
@ -248,14 +247,16 @@ bool exists(const String& filename) {
// Check if the file exists. // Check if the file exists.
bool cexists(const String& filename) const { bool cexists(const String& filename) const {
String passed = filename; String passed = filename;
if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<' if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':' || filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|') || filename.at(filename.length() - 1) == '|')
{
passed = filename.substr(0, filename.length() - 2); passed = filename.substr(0, filename.length() - 2);
}
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
return arc.exists(passed.c_str()); return arc.exists(passed.c_str());
} }

View file

@ -23,171 +23,235 @@
#include "bsa_file.hpp" #include "bsa_file.hpp"
#include <libs/mangle/stream/servers/file_stream.hpp>
#include <libs/mangle/stream/filters/slice_stream.hpp>
#include <stdexcept> #include <stdexcept>
#include <stdlib.h> #include <cstdlib>
#include <assert.h> #include <cassert>
#include <OgreDataStream.h>
using namespace std; using namespace std;
using namespace Mangle::Stream;
using namespace Bsa; using namespace Bsa;
class ConstrainedDataStream : public Ogre::DataStream {
std::ifstream mStream;
const size_t mStart;
size_t mPos;
bool mIsEOF;
public:
ConstrainedDataStream(const Ogre::String &fname, size_t start, size_t length)
: mStream(fname.c_str(), std::ios_base::binary), mStart(start), mPos(0), mIsEOF(false)
{
mSize = length;
if(!mStream.seekg(mStart, std::ios_base::beg))
throw std::runtime_error("Error seeking to start of BSA entry");
}
ConstrainedDataStream(const Ogre::String &name, const Ogre::String &fname,
size_t start, size_t length)
: Ogre::DataStream(name), mStream(fname.c_str(), std::ios_base::binary),
mStart(start), mPos(0), mIsEOF(false)
{
mSize = length;
if(!mStream.seekg(mStart, std::ios_base::beg))
throw std::runtime_error("Error seeking to start of BSA entry");
}
virtual size_t read(void *buf, size_t count)
{
mStream.clear();
if(count > mSize-mPos)
{
count = mSize-mPos;
mIsEOF = true;
}
mStream.read(reinterpret_cast<char*>(buf), count);
count = mStream.gcount();
mPos += count;
return count;
}
virtual void skip(long count)
{
if((count >= 0 && (size_t)count <= mSize-mPos) ||
(count < 0 && (size_t)-count <= mPos))
{
mStream.clear();
if(mStream.seekg(count, std::ios_base::cur))
{
mPos += count;
mIsEOF = false;
}
}
}
virtual void seek(size_t pos)
{
if(pos < mSize)
{
mStream.clear();
if(mStream.seekg(pos+mStart, std::ios_base::beg))
{
mPos = pos;
mIsEOF = false;
}
}
}
virtual size_t tell() const
{ return mPos; }
virtual bool eof() const
{ return mIsEOF; }
virtual void close()
{ mStream.close(); }
};
/// Error handling /// Error handling
void BSAFile::fail(const string &msg) void BSAFile::fail(const string &msg)
{ {
throw std::runtime_error("BSA Error: " + msg + "\nArchive: " + filename); throw std::runtime_error("BSA Error: " + msg + "\nArchive: " + filename);
} }
/// Read header information from the input source /// Read header information from the input source
void BSAFile::readHeader() void BSAFile::readHeader()
{ {
/* /*
* The layout of a BSA archive is as follows: * The layout of a BSA archive is as follows:
* *
* - 12 bytes header, contains 3 ints: * - 12 bytes header, contains 3 ints:
* id number - equal to 0x100 * id number - equal to 0x100
* dirsize - size of the directory block (see below) * dirsize - size of the directory block (see below)
* numfiles - number of files * numfiles - number of files
* *
* ---------- start of directory block ----------- * ---------- start of directory block -----------
* *
* - 8 bytes*numfiles, each record contains: * - 8 bytes*numfiles, each record contains:
* fileSize * fileSize
* offset into data buffer (see below) * offset into data buffer (see below)
* *
* - 4 bytes*numfiles, each record is an offset into the following name buffer * - 4 bytes*numfiles, each record is an offset into the following name buffer
* *
* - name buffer, indexed by the previous table, each string is * - name buffer, indexed by the previous table, each string is
* null-terminated. Size is (dirsize - 12*numfiles). * null-terminated. Size is (dirsize - 12*numfiles).
* *
* ---------- end of directory block ------------- * ---------- end of directory block -------------
* *
* - 8*filenum - hash table block, we currently ignore this * - 8*filenum - hash table block, we currently ignore this
* *
* ----------- start of data buffer -------------- * ----------- start of data buffer --------------
* *
* - The rest of the archive is file data, indexed by the * - The rest of the archive is file data, indexed by the
* offsets in the directory block. The offsets start at 0 at * offsets in the directory block. The offsets start at 0 at
* the beginning of this buffer. * the beginning of this buffer.
* *
*/ */
assert(!isLoaded); assert(!isLoaded);
assert(input);
assert(input->hasSize);
assert(input->hasPosition);
assert(input->isSeekable);
// Total archive size std::ifstream input(filename.c_str(), std::ios_base::binary);
size_t fsize = input->size();
if( fsize < 12 ) // Total archive size
fail("File too small to be a valid BSA archive"); size_t fsize = 0;
if(input.seekg(0, std::ios_base::end))
// Get essential header numbers
size_t dirsize, filenum;
{
// First 12 bytes
uint32_t head[3];
input->read(head, 12);
if(head[0] != 0x100)
fail("Unrecognized BSA header");
// Total number of bytes used in size/offset-table + filename
// sections.
dirsize = head[1];
// Number of files
filenum = head[2];
}
// Each file must take up at least 21 bytes of data in the bsa. So
// if files*21 overflows the file size then we are guaranteed that
// the archive is corrupt.
if( (filenum*21 > fsize -12) ||
(dirsize+8*filenum > fsize -12) )
fail("Directory information larger than entire archive");
// Read the offset info into a temporary buffer
vector<uint32_t> offsets(3*filenum);
input->read(&offsets[0], 12*filenum);
// Read the string table
stringBuf.resize(dirsize-12*filenum);
input->read(&stringBuf[0], stringBuf.size());
// Check our position
assert(input->tell() == 12+dirsize);
// Calculate the offset of the data buffer. All file offsets are
// relative to this. 12 header bytes + directory + hash table
// (skipped)
size_t fileDataOffset = 12 + dirsize + 8*filenum;
// Set up the the FileStruct table
files.resize(filenum);
for(size_t i=0;i<filenum;i++)
{ {
FileStruct &fs = files[i]; fsize = input.tellg();
fs.fileSize = offsets[i*2]; input.seekg(0);
fs.offset = offsets[i*2+1] + fileDataOffset;
fs.name = &stringBuf[offsets[2*filenum+i]];
if(fs.offset + fs.fileSize > fsize)
fail("Archive contains offsets outside itself");
// Add the file name to the lookup
lookup[fs.name] = i;
} }
isLoaded = true; if(fsize < 12)
fail("File too small to be a valid BSA archive");
// Get essential header numbers
size_t dirsize, filenum;
{
// First 12 bytes
uint32_t head[3];
input.read(reinterpret_cast<char*>(head), 12);
if(head[0] != 0x100)
fail("Unrecognized BSA header");
// Total number of bytes used in size/offset-table + filename
// sections.
dirsize = head[1];
// Number of files
filenum = head[2];
}
// Each file must take up at least 21 bytes of data in the bsa. So
// if files*21 overflows the file size then we are guaranteed that
// the archive is corrupt.
if((filenum*21 > fsize -12) || (dirsize+8*filenum > fsize -12) )
fail("Directory information larger than entire archive");
// Read the offset info into a temporary buffer
vector<uint32_t> offsets(3*filenum);
input.read(reinterpret_cast<char*>(&offsets[0]), 12*filenum);
// Read the string table
stringBuf.resize(dirsize-12*filenum);
input.read(&stringBuf[0], stringBuf.size());
// Check our position
assert(input.tellg() == static_cast<int> (12+dirsize));
// Calculate the offset of the data buffer. All file offsets are
// relative to this. 12 header bytes + directory + hash table
// (skipped)
size_t fileDataOffset = 12 + dirsize + 8*filenum;
// Set up the the FileStruct table
files.resize(filenum);
for(size_t i=0;i<filenum;i++)
{
FileStruct &fs = files[i];
fs.fileSize = offsets[i*2];
fs.offset = offsets[i*2+1] + fileDataOffset;
fs.name = &stringBuf[offsets[2*filenum+i]];
if(fs.offset + fs.fileSize > fsize)
fail("Archive contains offsets outside itself");
// Add the file name to the lookup
lookup[fs.name] = i;
}
isLoaded = true;
} }
/// Get the index of a given file name, or -1 if not found /// Get the index of a given file name, or -1 if not found
int BSAFile::getIndex(const char *str) const int BSAFile::getIndex(const char *str) const
{ {
Lookup::const_iterator it; Lookup::const_iterator it = lookup.find(str);
it = lookup.find(str); if(it == lookup.end())
return -1;
if(it == lookup.end()) return -1; int res = it->second;
else assert(res >= 0 && (size_t)res < files.size());
{ return res;
int res = it->second;
assert(res >= 0 && res < static_cast<int> (files.size()));
return res;
}
} }
/// Open an archive file. /// Open an archive file.
void BSAFile::open(const string &file) void BSAFile::open(const string &file)
{ {
filename = file; filename = file;
input = StreamPtr(new FileStream(file)); readHeader();
readHeader();
} }
/** Open an archive from a generic stream. The 'name' parameter is Ogre::DataStreamPtr BSAFile::getFile(const char *file)
used for error messages.
*/
void BSAFile::open(StreamPtr inp, const string &name)
{ {
filename = name; assert(file);
input = inp; int i = getIndex(file);
readHeader(); if(i == -1)
} fail("File not found: " + string(file));
StreamPtr BSAFile::getFile(const char *file) const FileStruct &fs = files[i];
{ return Ogre::DataStreamPtr(new ConstrainedDataStream(filename, fs.offset, fs.fileSize));
assert(file);
int i = getIndex(file);
if(i == -1)
fail("File not found: " + string(file));
FileStruct &fs = files[i];
return StreamPtr(new SliceStream(input, fs.offset, fs.fileSize));
} }

View file

@ -24,13 +24,15 @@
#ifndef BSA_BSA_FILE_H #ifndef BSA_BSA_FILE_H
#define BSA_BSA_FILE_H #define BSA_BSA_FILE_H
#include <libs/mangle/stream/stream.hpp>
#include <libs/platform/stdint.h> #include <libs/platform/stdint.h>
#include <libs/platform/strings.h> #include <libs/platform/strings.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include <OgreDataStream.h>
namespace Bsa namespace Bsa
{ {
@ -39,98 +41,85 @@ namespace Bsa
*/ */
class BSAFile class BSAFile
{ {
public: public:
/// Represents one file entry in the archive
struct FileStruct
{
// File size and offset in file. We store the offset from the
// beginning of the file, not the offset into the data buffer
// (which is what is stored in the archive.)
uint32_t fileSize, offset;
/// Represents one file entry in the archive // Zero-terminated file name
struct FileStruct const char *name;
{ };
// File size and offset in file. We store the offset from the typedef std::vector<FileStruct> FileList;
// beginning of the file, not the offset into the data buffer
// (which is what is stored in the archive.)
uint32_t fileSize, offset;
// Zero-terminated file name private:
char* name; /// Table of files in this archive
}; FileList files;
typedef std::vector<FileStruct> FileList; /// Filename string buffer
std::vector<char> stringBuf;
private: /// True when an archive has been loaded
bool isLoaded;
/// The archive source /// Used for error messages
Mangle::Stream::StreamPtr input; std::string filename;
/// Table of files in this archive /// Case insensitive string comparison
FileList files; struct iltstr
{
bool operator()(const char *s1, const char *s2) const
{ return strcasecmp(s1,s2) < 0; }
};
/// Filename string buffer /** A map used for fast file name lookup. The value is the index into
std::vector<char> stringBuf; the files[] vector above. The iltstr ensures that file name
checks are case insensitive.
*/
typedef std::map<const char*, int, iltstr> Lookup;
Lookup lookup;
/// True when an archive has been loaded /// Error handling
bool isLoaded; void fail(const std::string &msg);
/// Used for error messages /// Read header information from the input source
std::string filename; void readHeader();
/// Case insensitive string comparison /// Get the index of a given file name, or -1 if not found
struct iltstr int getIndex(const char *str) const;
{
bool operator()(const char *s1, const char *s2) const
{ return strcasecmp(s1,s2) < 0; }
};
/** A map used for fast file name lookup. The value is the index into public:
the files[] vector above. The iltstr ensures that file name /* -----------------------------------
checks are case insensitive. * BSA management methods
*/ * -----------------------------------
typedef std::map<const char*, int, iltstr> Lookup; */
Lookup lookup;
/// Error handling BSAFile()
void fail(const std::string &msg); : isLoaded(false)
{ }
/// Read header information from the input source /// Open an archive file.
void readHeader(); void open(const std::string &file);
/// Get the index of a given file name, or -1 if not found /* -----------------------------------
int getIndex(const char *str) const; * Archive file routines
* -----------------------------------
*/
public: /// Check if a file exists
bool exists(const char *file) const
{ return getIndex(file) != -1; }
/* ----------------------------------- /** Open a file contained in the archive. Throws an exception if the
* BSA management methods file doesn't exist.
* ----------------------------------- */
*/ Ogre::DataStreamPtr getFile(const char *file);
BSAFile() /// Get a list of all files
: input(), isLoaded(false) {} const FileList &getList() const
/// Open an archive file.
void open(const std::string &file);
/** Open an archive from a generic stream. The 'name' parameter is
used for error messages.
*/
void open(Mangle::Stream::StreamPtr inp, const std::string &name);
/* -----------------------------------
* Archive file routines
* -----------------------------------
*/
/// Check if a file exists
bool exists(const char *file) const { return getIndex(file) != -1; }
/** Open a file contained in the archive. Throws an exception if the
file doesn't exist.
NOTE: All files opened from one archive will share a common file
handle. This is NOT thread safe.
*/
Mangle::Stream::StreamPtr getFile(const char *file);
/// Get a list of all files
const FileList &getList() const
{ return files; } { return files; }
}; };

View file

@ -13,8 +13,8 @@
#include "config.h" #include "config.h"
#endif #endif
#include <stdio.h> #include <cstdio>
#include <stdlib.h> #include <cstdlib>
#include <string.h> #include <string.h>
#ifndef FIX_UNUSED #ifndef FIX_UNUSED

View file

@ -13,7 +13,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <stdio.h> /* for FILE */ #include <cstdio> /* for FILE */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View file

@ -35,4 +35,5 @@ namespace Compiler
<< " " << message << std::endl; << " " << message << std::endl;
} }
StreamErrorHandler::StreamErrorHandler (std::ostream& ErrorStream) : mStream (ErrorStream) {}} StreamErrorHandler::StreamErrorHandler (std::ostream& ErrorStream) : mStream (ErrorStream) {}
}

View file

@ -27,7 +27,7 @@ void ESMReader::restoreContext(const ESM_Context &rc)
void ESMReader::close() void ESMReader::close()
{ {
mEsm.reset(); mEsm.setNull();
mCtx.filename.clear(); mCtx.filename.clear();
mCtx.leftFile = 0; mCtx.leftFile = 0;
mCtx.leftRec = 0; mCtx.leftRec = 0;
@ -37,7 +37,7 @@ void ESMReader::close()
mCtx.subName.val = 0; mCtx.subName.val = 0;
} }
void ESMReader::openRaw(Mangle::Stream::StreamPtr _esm, const std::string &name) void ESMReader::openRaw(Ogre::DataStreamPtr _esm, const std::string &name)
{ {
close(); close();
mEsm = _esm; mEsm = _esm;
@ -57,7 +57,7 @@ void ESMReader::openRaw(Mangle::Stream::StreamPtr _esm, const std::string &name)
mSpf = SF_Other; mSpf = SF_Other;
} }
void ESMReader::open(Mangle::Stream::StreamPtr _esm, const std::string &name) void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name)
{ {
openRaw(_esm, name); openRaw(_esm, name);
@ -107,14 +107,16 @@ void ESMReader::open(Mangle::Stream::StreamPtr _esm, const std::string &name)
void ESMReader::open(const std::string &file) void ESMReader::open(const std::string &file)
{ {
using namespace Mangle::Stream; std::ifstream *stream = OGRE_NEW_T(std::ifstream, Ogre::MEMCATEGORY_GENERAL)(file.c_str(), std::ios_base::binary);
open(StreamPtr(new FileStream(file)), file); // Ogre will delete the stream for us
open(Ogre::DataStreamPtr(new Ogre::FileStreamDataStream(stream)), file);
} }
void ESMReader::openRaw(const std::string &file) void ESMReader::openRaw(const std::string &file)
{ {
using namespace Mangle::Stream; std::ifstream *stream = OGRE_NEW_T(std::ifstream, Ogre::MEMCATEGORY_GENERAL)(file.c_str(), std::ios_base::binary);
openRaw(StreamPtr(new FileStream(file)), file); // Ogre will delete the stream for us
openRaw(Ogre::DataStreamPtr(new Ogre::FileStreamDataStream(stream)), file);
} }
int64_t ESMReader::getHNLong(const char *name) int64_t ESMReader::getHNLong(const char *name)
@ -339,7 +341,7 @@ void ESMReader::fail(const std::string &msg)
ss << "\n File: " << mCtx.filename; ss << "\n File: " << mCtx.filename;
ss << "\n Record: " << mCtx.recName.toString(); ss << "\n Record: " << mCtx.recName.toString();
ss << "\n Subrecord: " << mCtx.subName.toString(); ss << "\n Subrecord: " << mCtx.subName.toString();
if (mEsm != NULL) if (!mEsm.isNull())
ss << "\n Offset: 0x" << hex << mEsm->tell(); ss << "\n Offset: 0x" << hex << mEsm->tell();
throw std::runtime_error(ss.str()); throw std::runtime_error(ss.str());
} }

View file

@ -1,18 +1,14 @@
#ifndef _ESM_READER_H #ifndef _ESM_READER_H
#define _ESM_READER_H #define _ESM_READER_H
#include <string.h>
#include <string>
#include <libs/platform/stdint.h> #include <libs/platform/stdint.h>
#include <libs/platform/string.h> #include <libs/platform/string.h>
#include <assert.h> #include <cassert>
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include <stdexcept>
#include <libs/mangle/stream/stream.hpp> #include <OgreDataStream.h>
#include <libs/mangle/stream/servers/file_stream.hpp>
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
@ -183,11 +179,11 @@ public:
/// Raw opening. Opens the file and sets everything up but doesn't /// Raw opening. Opens the file and sets everything up but doesn't
/// parse the header. /// parse the header.
void openRaw(Mangle::Stream::StreamPtr _esm, const std::string &name); void openRaw(Ogre::DataStreamPtr _esm, const std::string &name);
/// Load ES file from a new stream, parses the header. Closes the /// Load ES file from a new stream, parses the header. Closes the
/// currently open file first, if any. /// currently open file first, if any.
void open(Mangle::Stream::StreamPtr _esm, const std::string &name); void open(Ogre::DataStreamPtr _esm, const std::string &name);
void open(const std::string &file); void open(const std::string &file);
@ -354,7 +350,7 @@ public:
void setEncoding(const std::string& encoding); void setEncoding(const std::string& encoding);
private: private:
Mangle::Stream::StreamPtr mEsm; Ogre::DataStreamPtr mEsm;
ESM_Context mCtx; ESM_Context mCtx;

View file

@ -7,7 +7,7 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <assert.h> #include <cassert>
#include <stdexcept> #include <stdexcept>
#include <iterator> #include <iterator>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>

View file

@ -1,8 +1,6 @@
#ifndef COMPONENTS_FILES_COLLECTION_HPP #ifndef COMPONENTS_FILES_COLLECTION_HPP
#define COMPONENTS_FILES_COLLECTION_HPP #define COMPONENTS_FILES_COLLECTION_HPP
#include <string>
#include <map>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "multidircollection.hpp" #include "multidircollection.hpp"

View file

@ -8,7 +8,6 @@
#endif #endif
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <components/files/fixedpath.hpp> #include <components/files/fixedpath.hpp>
#include <components/files/collections.hpp> #include <components/files/collections.hpp>

View file

@ -2,8 +2,6 @@
using namespace std; using namespace std;
#include <assert.h>
#include "../slice_array.hpp" #include "../slice_array.hpp"
int main() int main()

View file

@ -1,4 +1,4 @@
#include <assert.h> #include <cassert>
#include "../stringops.hpp" #include "../stringops.hpp"

View file

@ -25,6 +25,7 @@
#define _NIF_CONTROLLED_H_ #define _NIF_CONTROLLED_H_
#include "extra.hpp" #include "extra.hpp"
#include "controller.hpp"
namespace Nif namespace Nif
{ {
@ -33,92 +34,104 @@ namespace Nif
class Controlled : public Extra class Controlled : public Extra
{ {
public: public:
ControllerPtr controller; ControllerPtr controller;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Extra::read(nif); Extra::read(nif);
controller.read(nif); controller.read(nif);
} }
void post(NIFFile *nif)
{
Extra::post(nif);
controller.post(nif);
}
}; };
/// Has name, extra-data and controller /// Has name, extra-data and controller
class Named : public Controlled class Named : public Controlled
{ {
public: public:
Misc::SString name; std::string name;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
name = nif->getString(); name = nif->getString();
Controlled::read(nif); Controlled::read(nif);
} }
}; };
typedef Named NiSequenceStreamHelper; typedef Named NiSequenceStreamHelper;
class NiParticleGrowFade : public Controlled class NiParticleGrowFade : public Controlled
{ {
public: public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
// Two floats. // Two floats.
nif->skip(8); nif->skip(8);
} }
}; };
class NiParticleColorModifier : public Controlled class NiParticleColorModifier : public Controlled
{ {
public: public:
NiColorDataPtr data; NiColorDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controlled::post(nif);
data.post(nif);
}
}; };
class NiGravity : public Controlled class NiGravity : public Controlled
{ {
public: public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
// two floats, one int, six floats // two floats, one int, six floats
nif->skip(9*4); nif->skip(9*4);
} }
}; };
// NiPinaColada // NiPinaColada
class NiPlanarCollider : public Controlled class NiPlanarCollider : public Controlled
{ {
public: public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
// (I think) 4 floats + 4 vectors // (I think) 4 floats + 4 vectors
nif->skip(4*16); nif->skip(4*16);
} }
}; };
class NiParticleRotation : public Controlled class NiParticleRotation : public Controlled
{ {
public: public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
/* /*
byte (0 or 1) byte (0 or 1)
float (1) float (1)
float*3 float*3
*/ */
nif->skip(17); nif->skip(17);
} }
}; };
} // Namespace } // Namespace

View file

@ -34,136 +34,187 @@ namespace Nif
class Controller : public Record class Controller : public Record
{ {
public: public:
ControllerPtr next; ControllerPtr next;
int flags; int flags;
float frequency, phase; float frequency, phase;
float timeStart, timeStop; float timeStart, timeStop;
ControlledPtr target; ControlledPtr target;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
next.read(nif); next.read(nif);
flags = nif->getShort(); flags = nif->getUShort();
frequency = nif->getFloat(); frequency = nif->getFloat();
phase = nif->getFloat(); phase = nif->getFloat();
timeStart = nif->getFloat(); timeStart = nif->getFloat();
timeStop = nif->getFloat(); timeStop = nif->getFloat();
target.read(nif); target.read(nif);
} }
void post(NIFFile *nif)
{
Record::post(nif);
next.post(nif);
target.post(nif);
}
}; };
class NiBSPArrayController : public Controller class NiBSPArrayController : public Controller
{ {
public: public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controller::read(nif); Controller::read(nif);
// At the moment, just skip it all // At the moment, just skip it all
nif->skip(111); nif->skip(111);
int s = nif->getShort(); int s = nif->getUShort();
nif->skip(15 + s*40); nif->skip(15 + s*40);
} }
}; };
typedef NiBSPArrayController NiParticleSystemController; typedef NiBSPArrayController NiParticleSystemController;
class NiMaterialColorController : public Controller class NiMaterialColorController : public Controller
{ {
public: public:
NiPosDataPtr data; NiPosDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiPathController : public Controller class NiPathController : public Controller
{ {
public: public:
NiPosDataPtr posData; NiPosDataPtr posData;
NiFloatDataPtr floatData; NiFloatDataPtr floatData;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controller::read(nif); Controller::read(nif);
/* /*
int = 1 int = 1
2xfloat 2xfloat
short = 0 or 1 short = 0 or 1
*/ */
nif->skip(14); nif->skip(14);
posData.read(nif); posData.read(nif);
floatData.read(nif); floatData.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
posData.post(nif);
floatData.post(nif);
}
}; };
class NiUVController : public Controller class NiUVController : public Controller
{ {
public: public:
NiUVDataPtr data; NiUVDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controller::read(nif); Controller::read(nif);
nif->getShort(); // always 0 nif->getUShort(); // always 0
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiKeyframeController : public Controller class NiKeyframeController : public Controller
{ {
public: public:
NiKeyframeDataPtr data; NiKeyframeDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiAlphaController : public Controller class NiAlphaController : public Controller
{ {
public: public:
NiFloatDataPtr data; NiFloatDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiGeomMorpherController : public Controller class NiGeomMorpherController : public Controller
{ {
public: public:
NiMorphDataPtr data; NiMorphDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
nif->getByte(); // always 0 nif->getChar(); // always 0
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiVisController : public Controller class NiVisController : public Controller
{ {
public: public:
NiVisDataPtr data; NiVisDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
} // Namespace } // Namespace

File diff suppressed because it is too large Load diff

View file

@ -35,57 +35,70 @@ typedef Node Effect;
// NiPointLight and NiSpotLight? // NiPointLight and NiSpotLight?
struct NiLight : Effect struct NiLight : Effect
{ {
struct SLight struct SLight
{ {
float dimmer; float dimmer;
Vector ambient; Ogre::Vector3 ambient;
Vector diffuse; Ogre::Vector3 diffuse;
Vector specular; Ogre::Vector3 specular;
};
const SLight *light; void read(NIFFile *nif)
{
dimmer = nif->getFloat();
ambient = nif->getVector3();
diffuse = nif->getVector3();
specular = nif->getVector3();
}
};
SLight light;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Effect::read(nif); Effect::read(nif);
nif->getInt(); // 1 nif->getInt(); // 1
nif->getInt(); // 1? nif->getInt(); // 1?
light = nif->getPtr<SLight>(); light.read(nif);
} }
}; };
struct NiTextureEffect : Effect struct NiTextureEffect : Effect
{ {
NiSourceTexturePtr texture; NiSourceTexturePtr texture;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Effect::read(nif); Effect::read(nif);
int tmp = nif->getInt(); int tmp = nif->getInt();
if(tmp) nif->getInt(); // always 1? if(tmp) nif->getInt(); // always 1?
/* /*
3 x Vector4 = [1,0,0,0] 3 x Vector4 = [1,0,0,0]
int = 2 int = 2
int = 0 or 3 int = 0 or 3
int = 2 int = 2
int = 2 int = 2
*/ */
nif->skip(16*4); nif->skip(16*4);
texture.read(nif); texture.read(nif);
/* /*
byte = 0 byte = 0
vector4 = [1,0,0,0] vector4 = [1,0,0,0]
short = 0 short = 0
short = -75 short = -75
short = 0 short = 0
*/ */
nif->skip(23); nif->skip(23);
} }
void post(NIFFile *nif)
{
Effect::post(nif);
texture.post(nif);
}
}; };
} // Namespace } // Namespace

View file

@ -38,70 +38,70 @@ namespace Nif
class Extra : public Record class Extra : public Record
{ {
public: public:
ExtraPtr extra; ExtraPtr extra;
void read(NIFFile *nif) { extra.read(nif); } void read(NIFFile *nif) { extra.read(nif); }
void post(NIFFile *nif) { extra.post(nif); }
}; };
class NiVertWeightsExtraData : public Extra class NiVertWeightsExtraData : public Extra
{ {
public: public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Extra::read(nif); Extra::read(nif);
// We should have s*4+2 == i, for some reason. Might simply be the // We should have s*4+2 == i, for some reason. Might simply be the
// size of the rest of the record, unhelpful as that may be. // size of the rest of the record, unhelpful as that may be.
/*int i =*/ nif->getInt(); /*int i =*/ nif->getInt();
int s = nif->getShort(); // number of vertices int s = nif->getUShort();
nif->getFloatLen(s); // vertex weights I guess nif->skip(s * sizeof(float)); // vertex weights I guess
} }
}; };
class NiTextKeyExtraData : public Extra class NiTextKeyExtraData : public Extra
{ {
public: public:
struct TextKey struct TextKey
{ {
float time; float time;
Misc::SString text; std::string text;
}; };
std::vector<TextKey> list;
std::vector<TextKey> list; void read(NIFFile *nif)
{
Extra::read(nif);
void read(NIFFile *nif) nif->getInt(); // 0
{
Extra::read(nif);
nif->getInt(); // 0 int keynum = nif->getInt();
list.resize(keynum);
int keynum = nif->getInt(); for(int i=0; i<keynum; i++)
list.resize(keynum); {
for(int i=0; i<keynum; i++) list[i].time = nif->getFloat();
{ list[i].text = nif->getString();
list[i].time = nif->getFloat(); }
list[i].text = nif->getString(); }
}
}
}; };
class NiStringExtraData : public Extra class NiStringExtraData : public Extra
{ {
public: public:
/* Two known meanings: /* Two known meanings:
"MRK" - marker, only visible in the editor, not rendered in-game "MRK" - marker, only visible in the editor, not rendered in-game
"NCO" - no collision "NCO" - no collision
*/ */
Misc::SString string; std::string string;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Extra::read(nif); Extra::read(nif);
nif->getInt(); // size of string + 4. Really useful... nif->getInt(); // size of string + 4. Really useful...
string = nif->getString(); string = nif->getString();
} }
}; };
} // Namespace } // Namespace

View file

@ -46,8 +46,8 @@ using namespace Misc;
void NIFFile::parse() void NIFFile::parse()
{ {
// Check the header string // Check the header string
const char* head = getString(40); std::string head = getString(40);
if(!begins(head, "NetImmerse File Format")) if(head.compare(0, 22, "NetImmerse File Format") != 0)
fail("Invalid NIF header"); fail("Invalid NIF header");
// Get BCD version // Get BCD version
@ -70,7 +70,7 @@ void NIFFile::parse()
for(int i=0;i<recNum;i++) for(int i=0;i<recNum;i++)
{ {
SString rec = getString(); std::string rec = getString();
//cout << i << ": " << rec.toString() << endl; //cout << i << ": " << rec.toString() << endl;
Record *r = NULL; Record *r = NULL;
@ -155,7 +155,7 @@ void NIFFile::parse()
// Failure // Failure
else else
fail("Unknown record type " + rec.toString()); fail("Unknown record type " + rec);
assert(r != NULL); assert(r != NULL);
assert(r->recType != RC_MISSING); assert(r->recType != RC_MISSING);
@ -190,17 +190,23 @@ void NIFFile::parse()
void NiSkinInstance::post(NIFFile *nif) void NiSkinInstance::post(NIFFile *nif)
{ {
int bnum = bones.length(); data.post(nif);
if(bnum != static_cast<int> (data->bones.size())) root.post(nif);
nif->fail("Mismatch in NiSkinData bone count"); bones.post(nif);
root->makeRootBone(data->trafo); if(data.empty() || root.empty())
nif->fail("NiSkinInstance missing root or data");
for(int i=0; i<bnum; i++) size_t bnum = bones.length();
if(bnum != data->bones.size())
nif->fail("Mismatch in NiSkinData bone count");
root->makeRootBone(&data->trafo);
for(size_t i=0; i<bnum; i++)
{ {
if(!bones.has(i)) if(!bones.has(i))
nif->fail("Oops: Missing bone! Don't know how to handle this."); nif->fail("Oops: Missing bone! Don't know how to handle this.");
bones[i].makeBone(i, data->bones[i]);
bones[i].makeBone(i, data->bones[i]);
} }
} }

View file

@ -24,133 +24,175 @@
#ifndef _NIF_FILE_H_ #ifndef _NIF_FILE_H_
#define _NIF_FILE_H_ #define _NIF_FILE_H_
#include <libs/mangle/stream/stream.hpp> #include <OgreResourceGroupManager.h>
#include <libs/mangle/stream/filters/buffer_stream.hpp> #include <OgreDataStream.h>
#include <components/misc/slice_array.hpp> #include <OgreVector3.h>
#include <OgreVector4.h>
#include <OgreMatrix3.h>
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
#include <string> #include <cassert>
#include <assert.h>
#include "record.hpp" #include "record.hpp"
#include "nif_types.hpp" #include "nif_types.hpp"
using namespace Mangle::Stream;
namespace Nif namespace Nif
{ {
class NIFFile class NIFFile
{ {
enum NIFVersion enum NIFVersion {
{ VER_MW = 0x04000002 // Morrowind NIFs
VER_MW = 0x04000002 // Morrowind NIFs
}; };
/// Nif file version /// Nif file version
int ver; int ver;
/// Input stream /// Input stream
StreamPtr inp; Ogre::DataStreamPtr inp;
/// File name, used for error messages /// File name, used for error messages
std::string filename; std::string filename;
/// Record list /// Record list
std::vector<Record*> records; std::vector<Record*> records;
/// Parse the file /// Parse the file
void parse(); void parse();
public: uint8_t read_byte()
/// Used for error handling
void fail(const std::string &msg)
{ {
std::string err = "NIFFile Error: " + msg; uint8_t byte;
err += "\nFile: " + filename; if(inp->read(&byte, 1) != 1) return 0;
throw std::runtime_error(err); return byte;
}
uint16_t read_le16()
{
uint8_t buffer[2];
if(inp->read(buffer, 2) != 2) return 0;
return buffer[0] | (buffer[1]<<8);
}
uint32_t read_le32()
{
uint8_t buffer[4];
if(inp->read(buffer, 4) != 4) return 0;
return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24);
}
float read_le32f()
{
union {
uint32_t i;
float f;
} u = { read_le32() };
return u.f;
} }
/// Open a NIF stream. The name is used for error messages. public:
NIFFile(StreamPtr nif, const std::string &name) /// Used for error handling
: filename(name) void fail(const std::string &msg)
{ {
/* Load the entire file into memory. This allows us to use std::string err = "NIFFile Error: " + msg;
direct pointers to the data arrays in the NIF, instead of err += "\nFile: " + filename;
individually allocating and copying each one. throw std::runtime_error(err);
The NIF data is only stored temporarily in memory, since once
the mesh data is loaded it is siphoned into OGRE and
deleted. For that reason, we might improve this further and
use a shared region/pool based allocation scheme in the
future, especially since only one NIFFile will ever be loaded
at any given time.
*/
inp = StreamPtr(new BufferStream(nif));
parse();
} }
~NIFFile() /// Open a NIF stream. The name is used for error messages.
NIFFile(const std::string &name)
: filename(name)
{ {
for(std::size_t i=0; i<records.size(); i++) inp = Ogre::ResourceGroupManager::getSingleton().openResource(name);
{ parse();
delete records[i];
}
} }
/// Get a given record ~NIFFile()
Record *getRecord(int index) {
{ for(std::size_t i=0; i<records.size(); i++)
assert(index >= 0 && index < static_cast<int> (records.size())); delete records[i];
Record *res = records[index]; }
assert(res != NULL);
return res;
}
/// Number of records /// Get a given record
int numRecords() { return records.size(); } Record *getRecord(size_t index)
{
Record *res = records.at(index);
assert(res != NULL);
return res;
}
/* ************************************************ /// Number of records
int numRecords() { return records.size(); }
/*************************************************
Parser functions Parser functions
****************************************************/
****************************************************/ void skip(size_t size) { inp->skip(size); }
void skip(size_t size) { inp->getPtr(size); } char getChar() { return read_byte(); }
short getShort() { return read_le16(); }
template<class X> const X* getPtr() { return (const X*)inp->getPtr(sizeof(X)); } unsigned short getUShort() { return read_le16(); }
template<class X> X getType() { return *getPtr<X>(); } int getInt() { return read_le32(); }
unsigned short getShort() { return getType<unsigned short>(); } float getFloat() { return read_le32f(); }
int getInt() { return getType<int>(); } Ogre::Vector3 getVector3()
float getFloat() { return getType<float>(); }
char getByte() { return getType<char>(); }
template<class X>
Misc::SliceArray<X> getArrayLen(int num)
{ return Misc::SliceArray<X>((const X*)inp->getPtr(num*sizeof(X)),num); }
template<class X>
Misc::SliceArray<X> getArray()
{ {
int len = getInt(); float a[3];
return getArrayLen<X>(len); for(size_t i = 0;i < 3;i++)
a[i] = getFloat();
return Ogre::Vector3(a);
}
Ogre::Vector4 getVector4()
{
float a[4];
for(size_t i = 0;i < 4;i++)
a[i] = getFloat();
return Ogre::Vector4(a);
}
Ogre::Matrix3 getMatrix3()
{
Ogre::Real a[3][3];
for(size_t i = 0;i < 3;i++)
{
for(size_t j = 0;j < 3;j++)
a[i][j] = Ogre::Real(getFloat());
}
return Ogre::Matrix3(a);
}
Transformation getTrafo()
{
Transformation t;
t.pos = getVector3();
t.rotation = getMatrix3();
t.scale = getFloat();
t.velocity = getVector3();
return t;
} }
Misc::SString getString() { return getArray<char>(); } std::string getString(size_t length)
{
std::string str;
str.resize(length);
if(inp->read(&str[0], length) != length)
return std::string();
return str.substr(0, str.find('\0'));
}
std::string getString()
{
size_t size = read_le32();
return getString(size);
}
const Vector *getVector() { return getPtr<Vector>(); } void getShorts(std::vector<short> &vec, size_t size)
const Matrix *getMatrix() { return getPtr<Matrix>(); } {
const Transformation *getTrafo() { return getPtr<Transformation>(); } vec.resize(size);
const Vector4 *getVector4() { return getPtr<Vector4>(); } for(size_t i = 0;i < vec.size();i++)
vec[i] = getShort();
Misc::FloatArray getFloatLen(int num) }
{ return getArrayLen<float>(num); } void getFloats(std::vector<float> &vec, size_t size)
{
// For fixed-size strings where you already know the size vec.resize(size);
const char *getString(int size) for(size_t i = 0;i < vec.size();i++)
{ return (const char*)inp->getPtr(size); } vec[i] = getFloat();
}
}; };
} // Namespace } // Namespace

View file

@ -24,59 +24,37 @@
#ifndef _NIF_TYPES_H_ #ifndef _NIF_TYPES_H_
#define _NIF_TYPES_H_ #define _NIF_TYPES_H_
#include <OgreVector3.h>
#include <OgreMatrix3.h>
// Common types used in NIF files // Common types used in NIF files
namespace Nif namespace Nif
{ {
/* These packing #pragmas aren't really necessary on 32 bit
machines. I haven't tested on 64 bit yet. In any case it doesn't
hurt to include them. We can't allow any compiler-generated padding
in any of these structs, since they are used to interface directly
with raw data from the NIF files.
*/
#pragma pack(push)
#pragma pack(1)
struct Vector
{
float array[3];
};
struct Vector4
{
float array[4];
};
struct Matrix
{
Vector v[3];
};
struct Transformation struct Transformation
{ {
Vector pos; Ogre::Vector3 pos;
Matrix rotation; Ogre::Matrix3 rotation;
float scale; float scale;
Vector velocity; Ogre::Vector3 velocity;
static const Transformation* getIdentity() static const Transformation& getIdentity()
{ {
static Transformation identity; static Transformation identity;
static bool iset = false; static bool iset = false;
if (!iset) if (!iset)
{ {
identity.scale = 1.0f; identity.scale = 1.0f;
identity.rotation.v[0].array[0] = 1.0f; identity.rotation[0][0] = 1.0f;
identity.rotation.v[1].array[1] = 1.0f; identity.rotation[1][1] = 1.0f;
identity.rotation.v[2].array[2] = 1.0f; identity.rotation[2][2] = 1.0f;
iset = true; iset = true;
} }
return &identity; return identity;
} }
}; };
#pragma pack(pop)
} // Namespace } // Namespace
#endif #endif

View file

@ -26,10 +26,13 @@
#include "controlled.hpp" #include "controlled.hpp"
#include "data.hpp" #include "data.hpp"
#include "property.hpp"
namespace Nif namespace Nif
{ {
class NiNode;
/** A Node is an object that's part of the main NIF tree. It has /** A Node is an object that's part of the main NIF tree. It has
parent node (unless it's the root), and transformation (location parent node (unless it's the root), and transformation (location
and rotation) relative to it's parent. and rotation) relative to it's parent.
@ -37,191 +40,250 @@ namespace Nif
class Node : public Named class Node : public Named
{ {
public: public:
// Node flags. Interpretation depends somewhat on the type of node. // Node flags. Interpretation depends somewhat on the type of node.
int flags; int flags;
const Transformation *trafo; Transformation trafo;
PropertyList props; PropertyList props;
// Bounding box info // Bounding box info
bool hasBounds; bool hasBounds;
const Vector *boundPos; Ogre::Vector3 boundPos;
const Matrix *boundRot; Ogre::Matrix3 boundRot;
const Vector *boundXYZ; // Box size Ogre::Vector3 boundXYZ; // Box size
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Named::read(nif); Named::read(nif);
flags = nif->getShort(); flags = nif->getUShort();
trafo = nif->getTrafo(); trafo = nif->getTrafo();
props.read(nif); props.read(nif);
hasBounds = !!nif->getInt(); hasBounds = !!nif->getInt();
if(hasBounds) if(hasBounds)
{ {
nif->getInt(); // always 1 nif->getInt(); // always 1
boundPos = nif->getVector(); boundPos = nif->getVector3();
boundRot = nif->getMatrix(); boundRot = nif->getMatrix3();
boundXYZ = nif->getVector(); boundXYZ = nif->getVector3();
} }
boneTrafo = NULL; parent = NULL;
boneIndex = -1;
}
// Bone transformation. If set, node is a part of a skeleton. boneTrafo = NULL;
const NiSkinData::BoneTrafo *boneTrafo; boneIndex = -1;
}
// Bone weight info, from NiSkinData void post(NIFFile *nif)
const NiSkinData::BoneInfo *boneInfo; {
Named::post(nif);
props.post(nif);
}
// Bone index. If -1, this node is either not a bone, or if // Parent node, or NULL for the root node. As far as I'm aware, only
// boneTrafo is set it is the root bone in the skeleton. // NiNodes (or types derived from NiNodes) can be parents.
short boneIndex; NiNode *parent;
void makeRootBone(const NiSkinData::BoneTrafo *tr) // Bone transformation. If set, node is a part of a skeleton.
{ const NiSkinData::BoneTrafo *boneTrafo;
boneTrafo = tr;
boneIndex = -1;
}
void makeBone(short ind, const NiSkinData::BoneInfo &bi) // Bone weight info, from NiSkinData
{ const NiSkinData::BoneInfo *boneInfo;
boneInfo = &bi;
boneTrafo = bi.trafo; // Bone index. If -1, this node is either not a bone, or if
boneIndex = ind; // boneTrafo is set it is the root bone in the skeleton.
} short boneIndex;
void makeRootBone(const NiSkinData::BoneTrafo *tr)
{
boneTrafo = tr;
boneIndex = -1;
}
void makeBone(short ind, const NiSkinData::BoneInfo &bi)
{
boneInfo = &bi;
boneTrafo = &bi.trafo;
boneIndex = ind;
}
}; };
struct NiTriShapeCopy struct NiTriShapeCopy
{ {
std::string sname; std::string sname;
std::vector<std::string> boneSequence; std::vector<std::string> boneSequence;
Nif::NiSkinData::BoneTrafoCopy trafo; Nif::NiSkinData::BoneTrafoCopy trafo;
//Ogre::Quaternion initialBoneRotation; //Ogre::Quaternion initialBoneRotation;
//Ogre::Vector3 initialBoneTranslation; //Ogre::Vector3 initialBoneTranslation;
std::vector<Ogre::Vector3> vertices; std::vector<Ogre::Vector3> vertices;
std::vector<Ogre::Vector3> normals; std::vector<Ogre::Vector3> normals;
std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfo; std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfo;
std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> > vertsToWeights; std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> > vertsToWeights;
Nif::NiMorphData morph; Nif::NiMorphData morph;
}; };
struct NiNode : Node struct NiNode : Node
{ {
NodeList children; NodeList children;
NodeList effects; NodeList effects;
/* Known NiNode flags: /* Known NiNode flags:
0x01 hidden
0x02 use mesh for collision
0x04 use bounding box for collision (?)
0x08 unknown, but common
0x20, 0x40, 0x80 unknown
*/
0x01 hidden void read(NIFFile *nif)
0x02 use mesh for collision {
0x04 use bounding box for collision (?) Node::read(nif);
0x08 unknown, but common children.read(nif);
0x20, 0x40, 0x80 unknown effects.read(nif);
*/ }
void read(NIFFile *nif) void post(NIFFile *nif)
{ {
Node::read(nif); Node::post(nif);
children.read(nif); children.post(nif);
effects.read(nif); effects.post(nif);
}
for(size_t i = 0;i < children.length();i++)
{
// Why would a unique list of children contain empty refs?
if(children.has(i))
children[i].parent = this;
}
}
}; };
struct NiTriShape : Node struct NiTriShape : Node
{ {
/* Possible flags: /* Possible flags:
0x40 - mesh has no vertex normals ? 0x40 - mesh has no vertex normals ?
Only flags included in 0x47 (ie. 0x01, 0x02, 0x04 and 0x40) have Only flags included in 0x47 (ie. 0x01, 0x02, 0x04 and 0x40) have
been observed so far. been observed so far.
*/ */
NiTriShapeDataPtr data; NiTriShapeDataPtr data;
NiSkinInstancePtr skin; NiSkinInstancePtr skin;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Node::read(nif); Node::read(nif);
data.read(nif); data.read(nif);
skin.read(nif); skin.read(nif);
} }
NiTriShapeCopy clone(){ void post(NIFFile *nif)
NiTriShapeCopy copy; {
copy.sname = name.toString(); Node::post(nif);
float *ptr = (float*)data->vertices.ptr; data.post(nif);
float *ptrNormals = (float*)data->normals.ptr; skin.post(nif);
int numVerts = data->vertices.length / 3; }
for(int i = 0; i < numVerts; i++)
{
float *current = (float*) (ptr + i * 3);
copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2)));
if(ptrNormals){ NiTriShapeCopy clone()
float *currentNormals = (float*) (ptrNormals + i * 3); {
copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2))); NiTriShapeCopy copy;
} copy.sname = name;
} float *ptr = (float*)&data->vertices[0];
float *ptrNormals = (float*)&data->normals[0];
int numVerts = data->vertices.size() / 3;
for(int i = 0; i < numVerts; i++)
{
float *current = (float*) (ptr + i * 3);
copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2)));
if(ptrNormals)
{
float *currentNormals = (float*) (ptrNormals + i * 3);
copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2)));
}
}
return copy; return copy;
} }
}; };
struct NiCamera : Node struct NiCamera : Node
{ {
struct Camera struct Camera
{ {
// Camera frustrum // Camera frustrum
float left, right, top, bottom, nearDist, farDist; float left, right, top, bottom, nearDist, farDist;
// Viewport // Viewport
float vleft, vright, vtop, vbottom; float vleft, vright, vtop, vbottom;
// Level of detail modifier // Level of detail modifier
float LOD; float LOD;
};
const Camera *cam; void read(NIFFile *nif)
{
left = nif->getFloat();
right = nif->getFloat();
top = nif->getFloat();
bottom = nif->getFloat();
nearDist = nif->getFloat();
farDist = nif->getFloat();
void read(NIFFile *nif) vleft = nif->getFloat();
{ vright = nif->getFloat();
Node::read(nif); vtop = nif->getFloat();
vbottom = nif->getFloat();
nif->getPtr<Camera>(); LOD = nif->getFloat();
}
};
Camera cam;
nif->getInt(); // -1 void read(NIFFile *nif)
nif->getInt(); // 0 {
} Node::read(nif);
cam.read(nif);
nif->getInt(); // -1
nif->getInt(); // 0
}
}; };
struct NiAutoNormalParticles : Node struct NiAutoNormalParticles : Node
{ {
NiAutoNormalParticlesDataPtr data; NiAutoNormalParticlesDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Node::read(nif); Node::read(nif);
data.read(nif); data.read(nif);
nif->getInt(); // -1 nif->getInt(); // -1
} }
void post(NIFFile *nif)
{
Node::post(nif);
data.post(nif);
}
}; };
struct NiRotatingParticles : Node struct NiRotatingParticles : Node
{ {
NiRotatingParticlesDataPtr data; NiRotatingParticlesDataPtr data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Node::read(nif); Node::read(nif);
data.read(nif); data.read(nif);
nif->getInt(); // -1 nif->getInt(); // -1
} }
void post(NIFFile *nif)
{
Node::post(nif);
data.post(nif);
}
}; };
} // Namespace } // Namespace
#endif #endif

View file

@ -32,104 +32,116 @@ namespace Nif
class Property : public Named class Property : public Named
{ {
public: public:
// The meaning of these depends on the actual property type. // The meaning of these depends on the actual property type.
int flags; int flags;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Named::read(nif); Named::read(nif);
flags = nif->getShort(); flags = nif->getUShort();
} }
}; };
class NiTexturingProperty : public Property class NiTexturingProperty : public Property
{ {
public: public:
// A sub-texture // A sub-texture
struct Texture struct Texture
{ {
/* Clamp mode /* Clamp mode
0 - clampS clampT 0 - clampS clampT
1 - clampS wrapT 1 - clampS wrapT
2 - wrapS clampT 2 - wrapS clampT
3 - wrapS wrapT 3 - wrapS wrapT
*/ */
/* Filter: /* Filter:
0 - nearest 0 - nearest
1 - bilinear 1 - bilinear
2 - trilinear 2 - trilinear
3, 4, 5 - who knows 3, 4, 5 - who knows
*/ */
bool inUse; bool inUse;
NiSourceTexturePtr texture; NiSourceTexturePtr texture;
int clamp, set, filter; int clamp, set, filter;
short unknown2; short unknown2;
void read(NIFFile *nif)
{
inUse = !!nif->getInt();
if(!inUse) return;
texture.read(nif);
clamp = nif->getInt();
filter = nif->getInt();
set = nif->getInt();
// I have no idea, but I think these are actually two
// PS2-specific shorts (ps2L and ps2K), followed by an unknown
// short.
nif->skip(6);
}
void post(NIFFile *nif)
{
texture.post(nif);
}
};
/* Apply mode:
0 - replace
1 - decal
2 - modulate
3 - hilight // These two are for PS2 only?
4 - hilight2
*/
int apply;
/*
* The textures in this list are as follows:
*
* 0 - Base texture
* 1 - Dark texture
* 2 - Detail texture
* 3 - Gloss texture (never used?)
* 4 - Glow texture
* 5 - Bump map texture
* 6 - Decal texture
*/
Texture textures[7];
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
inUse = !!nif->getInt(); Property::read(nif);
if(!inUse) return; apply = nif->getInt();
texture.read(nif); // Unknown, always 7. Probably the number of textures to read
clamp = nif->getInt(); // below
filter = nif->getInt(); nif->getInt();
set = nif->getInt();
// I have no idea, but I think these are actually two textures[0].read(nif); // Base
// PS2-specific shorts (ps2L and ps2K), followed by an unknown textures[1].read(nif); // Dark
// short. textures[2].read(nif); // Detail
nif->skip(6); textures[3].read(nif); // Gloss (never present)
textures[4].read(nif); // Glow
textures[5].read(nif); // Bump map
if(textures[5].inUse)
{
// Ignore these at the moment
/*float lumaScale =*/ nif->getFloat();
/*float lumaOffset =*/ nif->getFloat();
/*const Vector4 *lumaMatrix =*/ nif->getVector4();
}
textures[6].read(nif); // Decal
} }
};
/* Apply mode: void post(NIFFile *nif)
0 - replace {
1 - decal Property::post(nif);
2 - modulate for(int i = 0;i < 7;i++)
3 - hilight // These two are for PS2 only? textures[i].post(nif);
4 - hilight2 }
*/
int apply;
/*
* The textures in this list are as follows:
*
* 0 - Base texture
* 1 - Dark texture
* 2 - Detail texture
* 3 - Gloss texture (never used?)
* 4 - Glow texture
* 5 - Bump map texture
* 6 - Decal texture
*/
Texture textures[7];
void read(NIFFile *nif)
{
Property::read(nif);
apply = nif->getInt();
// Unknown, always 7. Probably the number of textures to read
// below
nif->getInt();
textures[0].read(nif); // Base
textures[1].read(nif); // Dark
textures[2].read(nif); // Detail
textures[3].read(nif); // Gloss (never present)
textures[4].read(nif); // Glow
textures[5].read(nif); // Bump map
if(textures[5].inUse)
{
// Ignore these at the moment
/*float lumaScale =*/ nif->getFloat();
/*float lumaOffset =*/ nif->getFloat();
/*const Vector4 *lumaMatrix =*/ nif->getVector4();
}
textures[6].read(nif); // Decal
}
}; };
// These contain no other data than the 'flags' field in Property // These contain no other data than the 'flags' field in Property
@ -140,88 +152,109 @@ typedef Property NiSpecularProperty;
typedef Property NiWireframeProperty; typedef Property NiWireframeProperty;
// The rest are all struct-based // The rest are all struct-based
template <typename Struct> template <typename T>
struct StructPropT : Property struct StructPropT : Property
{ {
const Struct* data; T data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Property::read(nif); Property::read(nif);
data = nif->getPtr<Struct>(); data.read(nif);
} }
}; };
struct S_MaterialProperty struct S_MaterialProperty
{ {
// The vector components are R,G,B // The vector components are R,G,B
Vector ambient, diffuse, specular, emissive; Ogre::Vector3 ambient, diffuse, specular, emissive;
float glossiness, alpha; float glossiness, alpha;
void read(NIFFile *nif)
{
ambient = nif->getVector3();
diffuse = nif->getVector3();
specular = nif->getVector3();
emissive = nif->getVector3();
glossiness = nif->getFloat();
alpha = nif->getFloat();
}
}; };
struct S_VertexColorProperty struct S_VertexColorProperty
{ {
/* Vertex mode: /* Vertex mode:
0 - source ignore 0 - source ignore
1 - source emmisive 1 - source emmisive
2 - source amb diff 2 - source amb diff
Lighting mode Lighting mode
0 - lighting emmisive 0 - lighting emmisive
1 - lighting emmisive ambient/diffuse 1 - lighting emmisive ambient/diffuse
*/ */
int vertmode, lightmode; int vertmode, lightmode;
void read(NIFFile *nif)
{
vertmode = nif->getInt();
lightmode = nif->getInt();
}
}; };
struct S_AlphaProperty struct S_AlphaProperty
{ {
/* /*
In NiAlphaProperty, the flags have the following meaning: In NiAlphaProperty, the flags have the following meaning:
Bit 0 : alpha blending enable Bit 0 : alpha blending enable
Bits 1-4 : source blend mode Bits 1-4 : source blend mode
Bits 5-8 : destination blend mode Bits 5-8 : destination blend mode
Bit 9 : alpha test enable Bit 9 : alpha test enable
Bit 10-12 : alpha test mode Bit 10-12 : alpha test mode
Bit 13 : no sorter flag ( disables triangle sorting ) Bit 13 : no sorter flag ( disables triangle sorting )
blend modes (glBlendFunc): blend modes (glBlendFunc):
0000 GL_ONE 0000 GL_ONE
0001 GL_ZERO 0001 GL_ZERO
0010 GL_SRC_COLOR 0010 GL_SRC_COLOR
0011 GL_ONE_MINUS_SRC_COLOR 0011 GL_ONE_MINUS_SRC_COLOR
0100 GL_DST_COLOR 0100 GL_DST_COLOR
0101 GL_ONE_MINUS_DST_COLOR 0101 GL_ONE_MINUS_DST_COLOR
0110 GL_SRC_ALPHA 0110 GL_SRC_ALPHA
0111 GL_ONE_MINUS_SRC_ALPHA 0111 GL_ONE_MINUS_SRC_ALPHA
1000 GL_DST_ALPHA 1000 GL_DST_ALPHA
1001 GL_ONE_MINUS_DST_ALPHA 1001 GL_ONE_MINUS_DST_ALPHA
1010 GL_SRC_ALPHA_SATURATE 1010 GL_SRC_ALPHA_SATURATE
test modes (glAlphaFunc): test modes (glAlphaFunc):
000 GL_ALWAYS 000 GL_ALWAYS
001 GL_LESS 001 GL_LESS
010 GL_EQUAL 010 GL_EQUAL
011 GL_LEQUAL 011 GL_LEQUAL
100 GL_GREATER 100 GL_GREATER
101 GL_NOTEQUAL 101 GL_NOTEQUAL
110 GL_GEQUAL 110 GL_GEQUAL
111 GL_NEVER 111 GL_NEVER
Taken from: Taken from:
http://niftools.sourceforge.net/doc/nif/NiAlphaProperty.html http://niftools.sourceforge.net/doc/nif/NiAlphaProperty.html
Right now we only use standard alpha blending (see the Ogre code Right now we only use standard alpha blending (see the Ogre code
that sets it up) and it appears that this is the only blending that sets it up) and it appears that this is the only blending
used in the original game. Bloodmoon (along with several mods) do used in the original game. Bloodmoon (along with several mods) do
however use other settings, such as discarding pixel values with however use other settings, such as discarding pixel values with
alpha < 1.0. This is faster because we don't have to mess with the alpha < 1.0. This is faster because we don't have to mess with the
depth stuff like we did for blending. And OGRE has settings for depth stuff like we did for blending. And OGRE has settings for
this too. this too.
*/ */
// Tested against when certain flags are set (see above.) // Tested against when certain flags are set (see above.)
unsigned char threshold; unsigned char threshold;
void read(NIFFile *nif)
{
threshold = nif->getChar();
}
}; };
typedef StructPropT<S_AlphaProperty> NiAlphaProperty; typedef StructPropT<S_AlphaProperty> NiAlphaProperty;

View file

@ -88,26 +88,25 @@ enum RecordType
/// Base class for all records /// Base class for all records
struct Record struct Record
{ {
// Record type and type name // Record type and type name
int recType; int recType;
Misc::SString recName; std::string recName;
Record() : recType(RC_MISSING) {} Record() : recType(RC_MISSING) {}
/// Parses the record from file /// Parses the record from file
virtual void read(NIFFile *nif) = 0; virtual void read(NIFFile *nif) = 0;
/// Does post-processing, after the entire tree is loaded /// Does post-processing, after the entire tree is loaded
virtual void post(NIFFile *nif) {} virtual void post(NIFFile *nif) {}
virtual ~Record() {} virtual ~Record() {}
/* /*
Use these later if you want custom allocation of all NIF objects Use these later if you want custom allocation of all NIF objects
static void* operator new(size_t size);
static void* operator new(size_t size); static void operator delete(void *p);
static void operator delete(void *p); */
*/
}; };
} // Namespace } // Namespace

View file

@ -37,61 +37,52 @@ namespace Nif
template <class X> template <class X>
class RecordPtrT class RecordPtrT
{ {
int index; union {
X* ptr; intptr_t index;
NIFFile *nif; X* ptr;
};
public: public:
RecordPtrT() : index(-2) {}
RecordPtrT() : index(-2), ptr(NULL) {} /// Read the index from the nif
void read(NIFFile *nif)
{
// Can only read the index once
assert(index == -2);
/// Read the index from the nif // Store the index for later
void read(NIFFile *_nif) index = nif->getInt();
{ assert(index >= -1);
// Can only read the index once }
assert(index == -2);
// Store the NIFFile pointer for later /// Resolve index to pointer
nif = _nif; void post(NIFFile *nif)
{
if(index < 0)
ptr = NULL;
else
{
Record *r = nif->getRecord(index);
// And cast it
ptr = dynamic_cast<X*>(r);
assert(ptr != NULL);
}
}
// And the index, of course /// Look up the actual object from the index
index = nif->getInt(); X* getPtr()
} {
/** Set the pointer explicitly. May be used when you are pointing to
records in another file, eg. when you have a .nif / .kf pair.
*/
void set(X *p)
{
ptr = p;
index = -1;
}
/// Look up the actual object from the index
X* getPtr()
{
// Have we found the pointer already?
if(ptr == NULL)
{
// Get the record
assert(index >= 0);
Record *r = nif->getRecord(index);
// And cast it
ptr = dynamic_cast<X*>(r);
assert(ptr != NULL); assert(ptr != NULL);
} return ptr;
return ptr; }
} X& get() { return *getPtr(); }
/// Syntactic sugar /// Syntactic sugar
X* operator->() { return getPtr(); } X* operator->() { return getPtr(); }
X& get() { return *getPtr(); }
/// Pointers are allowed to be empty /// Pointers are allowed to be empty
bool empty() { return index == -1 && ptr == NULL; } bool empty() { return ptr == NULL; }
int getIndex() { return index; }
}; };
/** A list of references to other records. These are read as a list, /** A list of references to other records. These are read as a list,
@ -101,40 +92,37 @@ class RecordPtrT
template <class X> template <class X>
class RecordListT class RecordListT
{ {
typedef RecordPtrT<X> Ptr; typedef RecordPtrT<X> Ptr;
std::vector<Ptr> list; std::vector<Ptr> list;
public: public:
void read(NIFFile *nif)
void read(NIFFile *nif)
{
int len = nif->getInt();
list.resize(len);
assert(len >= 0 && len < 1000);
for(int i=0;i<len;i++)
list[i].read(nif);
}
X& operator[](int index)
{ {
assert(index >= 0 && index < static_cast<int> (list.size())); int len = nif->getInt();
return list[index].get(); list.resize(len);
for(size_t i=0;i < list.size();i++)
list[i].read(nif);
} }
bool has(int index) void post(NIFFile *nif)
{
assert(index >= 0 && index < static_cast<int> (list.size()));
return !list[index].empty();
}
int getIndex(int index)
{ {
if(has(index)) return list[index].getIndex(); for(size_t i=0;i < list.size();i++)
else return -1; list[i].post(nif);
} }
int length() { return list.size(); } X& operator[](size_t index)
{
return list.at(index).get();
}
bool has(size_t index)
{
return !list.at(index).empty();
}
size_t length()
{ return list.size(); }
}; };

View file

@ -1,4 +1,4 @@
/* /*
OpenMW - The completely unofficial reimplementation of Morrowind OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008-2010 Nicolay Korslund Copyright (C) 2008-2010 Nicolay Korslund
Email: < korslund@gmail.com > Email: < korslund@gmail.com >
@ -23,9 +23,8 @@ http://www.gnu.org/licenses/ .
#include "bullet_nif_loader.hpp" #include "bullet_nif_loader.hpp"
#include <Ogre.h> #include <Ogre.h>
#include <stdio.h> #include <cstdio>
#include <libs/mangle/vfs/servers/ogre_vfs.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"
@ -44,32 +43,15 @@ http://www.gnu.org/licenses/ .
typedef unsigned char ubyte; typedef unsigned char ubyte;
using namespace std;
using namespace Ogre;
using namespace Nif;
using namespace Mangle::VFS;
using namespace NifBullet; using namespace NifBullet;
ManualBulletShapeLoader::~ManualBulletShapeLoader() ManualBulletShapeLoader::~ManualBulletShapeLoader()
{ {
delete vfs;
} }
Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr)
{
Ogre::Matrix3 rot(tr->rotation.v[0].array[0],tr->rotation.v[0].array[1],tr->rotation.v[0].array[2],
tr->rotation.v[1].array[0],tr->rotation.v[1].array[1],tr->rotation.v[1].array[2],
tr->rotation.v[2].array[0],tr->rotation.v[2].array[1],tr->rotation.v[2].array[2]);
return rot;
}
Ogre::Vector3 ManualBulletShapeLoader::getVector(Nif::Transformation* tr)
{
Ogre::Vector3 vect3(tr->pos.array[0],tr->pos.array[1],tr->pos.array[2]);
return vect3;
}
btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 m) btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 &m)
{ {
Ogre::Quaternion oquat(m); Ogre::Quaternion oquat(m);
btQuaternion quat; btQuaternion quat;
@ -80,10 +62,9 @@ btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 m)
return quat; return quat;
} }
btVector3 ManualBulletShapeLoader::getbtVector(Nif::Vector v) btVector3 ManualBulletShapeLoader::getbtVector(Ogre::Vector3 &v)
{ {
btVector3 a(v.array[0],v.array[1],v.array[2]); return btVector3(v[0], v[1], v[2]);
return a;
} }
void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
@ -94,20 +75,11 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
mTriMesh = new btTriangleMesh(); mTriMesh = new btTriangleMesh();
if (!vfs) vfs = new OgreVFS(resourceGroup);
if (!vfs->isFile(resourceName))
{
warn("File not found.");
return;
}
// Load the NIF. TODO: Wrap this in a try-catch block once we're out // Load the NIF. TODO: Wrap this in a try-catch block once we're out
// of the early stages of development. Right now we WANT to catch // of the early stages of development. Right now we WANT to catch
// every error as early and intrusively as possible, as it's most // every error as early and intrusively as possible, as it's most
// likely a sign of incomplete code rather than faulty input. // likely a sign of incomplete code rather than faulty input.
Nif::NIFFile nif(vfs->open(resourceName), resourceName); Nif::NIFFile nif(resourceName);
if (nif.numRecords() < 1) if (nif.numRecords() < 1)
{ {
warn("Found no records in NIF."); warn("Found no records in NIF.");
@ -120,26 +92,25 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
assert(r != NULL); assert(r != NULL);
Nif::Node *node = dynamic_cast<Nif::Node*>(r); Nif::Node *node = dynamic_cast<Nif::Node*>(r);
if (node == NULL) if (node == NULL)
{ {
warn("First record in file was not a node, but a " + warn("First record in file was not a node, but a " +
r->recName.toString() + ". Skipping file."); r->recName + ". Skipping file.");
return; return;
} }
bool hasCollisionNode = hasRootCollisionNode(node); bool hasCollisionNode = hasRootCollisionNode(node);
//do a first pass //do a first pass
handleNode(node,0,Ogre::Matrix3::IDENTITY,Ogre::Vector3::ZERO,1,hasCollisionNode,false,false); handleNode(node,0,NULL,hasCollisionNode,false,false);
//if collide = false, then it does a second pass which create a shape for raycasting. //if collide = false, then it does a second pass which create a shape for raycasting.
if(cShape->collide == false) if(cShape->collide == false)
{ {
handleNode(node,0,Ogre::Matrix3::IDENTITY,Ogre::Vector3::ZERO,1,hasCollisionNode,false,true); handleNode(node,0,NULL,hasCollisionNode,false,true);
} }
cShape->collide = hasCollisionNode&&cShape->collide; //cShape->collide = hasCollisionNode&&cShape->collide;
struct TriangleMeshShape : public btBvhTriangleMeshShape struct TriangleMeshShape : public btBvhTriangleMeshShape
{ {
@ -186,8 +157,9 @@ bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node)
} }
void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly) const Nif::Transformation *trafo,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly)
{ {
// Accumulate the flags from all the child nodes. This works for all // Accumulate the flags from all the child nodes. This works for all
// the flags we currently use, at least. // the flags we currently use, at least.
flags |= node->flags; flags |= node->flags;
@ -221,18 +193,26 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
} }
} }
//transfo of parents node + curent node
Ogre::Matrix3 finalRot;
Ogre::Vector3 finalPos;
float finalScale;
Nif::Transformation &final = *((Nif::Transformation*)node->trafo); if (trafo)
Ogre::Vector3 nodePos = getVector(&final); {
Ogre::Matrix3 nodeRot = getMatrix(&final);
finalPos = nodePos + parentPos; // Get a non-const reference to the node's data, since we're
finalRot = parentRot*nodeRot; // overwriting it. TODO: Is this necessary?
finalScale = final.scale*parentScale; Nif::Transformation &final = node->trafo;
// For both position and rotation we have that:
// final_vector = old_vector + old_rotation*new_vector*old_scale
final.pos = trafo->pos + trafo->rotation*final.pos*trafo->scale;
final.velocity = trafo->velocity + trafo->rotation*final.velocity*trafo->scale;
// Merge the rotations together
final.rotation = trafo->rotation * final.rotation;
// Scale
final.scale *= trafo->scale;
}
// For NiNodes, loop through children // For NiNodes, loop through children
@ -244,14 +224,14 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
{ {
if (list.has(i)) if (list.has(i))
{ {
handleNode(&list[i], flags,finalRot,finalPos,finalScale,hasCollisionNode,isCollisionNode,raycastingOnly); handleNode(&list[i], flags,&node->trafo,hasCollisionNode,isCollisionNode,raycastingOnly);
} }
} }
} }
else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode))
{ {
cShape->collide = true; cShape->collide = true;
handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,finalRot,finalPos,parentScale,raycastingOnly); handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,node->trafo.rotation,node->trafo.pos,node->trafo.scale,raycastingOnly);
} }
else if(node->recType == Nif::RC_RootCollisionNode) else if(node->recType == Nif::RC_RootCollisionNode)
{ {
@ -260,7 +240,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
for (int i=0; i<n; i++) for (int i=0; i<n; i++)
{ {
if (list.has(i)) if (list.has(i))
handleNode(&list[i], flags,finalRot,finalPos,finalScale,hasCollisionNode,true,raycastingOnly); handleNode(&list[i], flags,&node->trafo, hasCollisionNode,true,raycastingOnly);
} }
} }
} }
@ -292,17 +272,19 @@ void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape *shape, int flags
Nif::NiTriShapeData *data = shape->data.getPtr(); Nif::NiTriShapeData *data = shape->data.getPtr();
float* vertices = (float*)data->vertices.ptr; float* vertices = &data->vertices[0];
unsigned short* triangles = (unsigned short*)data->triangles.ptr; short* triangles = &data->triangles[0];
const Ogre::Matrix3 &rot = shape->trafo.rotation;
for(unsigned int i=0; i < data->triangles.length; i = i+3) const Ogre::Vector3 &pos = shape->trafo.pos;
float scale = shape->trafo.scale;
for(unsigned int i=0; i < data->triangles.size(); i = i+3)
{ {
Ogre::Vector3 b1(vertices[triangles[i+0]*3]*parentScale,vertices[triangles[i+0]*3+1]*parentScale,vertices[triangles[i+0]*3+2]*parentScale); Ogre::Vector3 b1(vertices[triangles[i+0]*3]*parentScale,vertices[triangles[i+0]*3+1]*parentScale,vertices[triangles[i+0]*3+2]*parentScale);
Ogre::Vector3 b2(vertices[triangles[i+1]*3]*parentScale,vertices[triangles[i+1]*3+1]*parentScale,vertices[triangles[i+1]*3+2]*parentScale); Ogre::Vector3 b2(vertices[triangles[i+1]*3]*parentScale,vertices[triangles[i+1]*3+1]*parentScale,vertices[triangles[i+1]*3+2]*parentScale);
Ogre::Vector3 b3(vertices[triangles[i+2]*3]*parentScale,vertices[triangles[i+2]*3+1]*parentScale,vertices[triangles[i+2]*3+2]*parentScale); Ogre::Vector3 b3(vertices[triangles[i+2]*3]*parentScale,vertices[triangles[i+2]*3+1]*parentScale,vertices[triangles[i+2]*3+2]*parentScale);
b1 = parentRot * b1 + parentPos; b1 = pos + rot*b1*scale;
b2 = parentRot * b2 + parentPos; b2 = pos + rot*b2*scale;
b3 = parentRot * b3 + parentPos; b3 = pos + rot*b3*scale;
mTriMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z)); mTriMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z));
} }
} }

View file

@ -25,37 +25,21 @@
#define _BULLET_NIF_LOADER_H_ #define _BULLET_NIF_LOADER_H_
#include <OgreMesh.h> #include <OgreMesh.h>
#include <assert.h> #include <cassert>
#include <string> #include <string>
#include <BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h> #include <BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h>
#include <BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h> #include <BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h>
#include <btBulletDynamicsCommon.h> #include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>
#include "openengine/bullet/BulletShapeLoader.h" #include "openengine/bullet/BulletShapeLoader.h"
#include <vector>
#include <list>
// For warning messages // For warning messages
#include <iostream> #include <iostream>
// float infinity
#include <limits>
namespace Nif namespace Nif
{ {
class Node; class Node;
class Transformation; class Transformation;
class NiTriShape; class NiTriShape;
class Vector;
class Matrix;
}
namespace Mangle
{
namespace VFS
{
class OgreVFS;
}
} }
namespace NifBullet namespace NifBullet
@ -68,7 +52,7 @@ class ManualBulletShapeLoader : public BulletShapeLoader
{ {
public: public:
ManualBulletShapeLoader():resourceGroup("General"){vfs = 0;} ManualBulletShapeLoader():resourceGroup("General"){}
virtual ~ManualBulletShapeLoader(); virtual ~ManualBulletShapeLoader();
void warn(std::string msg) void warn(std::string msg)
@ -95,22 +79,18 @@ public:
void load(const std::string &name,const std::string &group); void load(const std::string &name,const std::string &group);
private: private:
Ogre::Matrix3 getMatrix(Nif::Transformation* tr); btQuaternion getbtQuat(Ogre::Matrix3 &m);
Ogre::Vector3 getVector(Nif::Transformation* tr); btVector3 getbtVector(Ogre::Vector3 &v);
btQuaternion getbtQuat(Ogre::Matrix3 m);
btVector3 getbtVector(Nif::Vector v);
/** /**
*Parse a node. *Parse a node.
*/ */
void handleNode(Nif::Node *node, int flags, void handleNode(Nif::Node *node, int flags,
Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly); const Nif::Transformation *trafo, bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly);
/** /**
*Helpler function *Helper function
*/ */
bool hasRootCollisionNode(Nif::Node* node); bool hasRootCollisionNode(Nif::Node* node);
@ -119,8 +99,6 @@ private:
*/ */
void handleNiTriShape(Nif::NiTriShape *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScales,bool raycastingOnly); void handleNiTriShape(Nif::NiTriShape *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScales,bool raycastingOnly);
Mangle::VFS::OgreVFS *vfs;
std::string resourceName; std::string resourceName;
std::string resourceGroup; std::string resourceGroup;

View file

@ -39,9 +39,7 @@
typedef unsigned char ubyte; typedef unsigned char ubyte;
using namespace std; using namespace std;
using namespace Ogre;
using namespace Nif; using namespace Nif;
using namespace Mangle::VFS;
using namespace Misc; using namespace Misc;
using namespace NifOgre; using namespace NifOgre;
@ -67,21 +65,6 @@ void NIFLoader::fail(string msg)
assert(1); assert(1);
} }
Vector3 NIFLoader::convertVector3(const Nif::Vector& vec)
{
return Ogre::Vector3(vec.array);
}
Quaternion NIFLoader::convertRotation(const Nif::Matrix& rot)
{
Real matrix[3][3];
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
matrix[i][j] = rot.v[i].array[j];
return Quaternion(Matrix3(matrix));
}
// Helper class that computes the bounding box and of a mesh // Helper class that computes the bounding box and of a mesh
class BoundsFinder class BoundsFinder
@ -217,16 +200,16 @@ void NIFLoader::setOutputAnimFiles(bool output){
void NIFLoader::setVerbosePath(std::string path){ void NIFLoader::setVerbosePath(std::string path){
verbosePath = path; verbosePath = path;
} }
void NIFLoader::createMaterial(const String &name, void NIFLoader::createMaterial(const Ogre::String &name,
const Vector &ambient, const Ogre::Vector3 &ambient,
const Vector &diffuse, const Ogre::Vector3 &diffuse,
const Vector &specular, const Ogre::Vector3 &specular,
const Vector &emissive, const Ogre::Vector3 &emissive,
float glossiness, float alpha, float glossiness, float alpha,
int alphaFlags, float alphaTest, int alphaFlags, float alphaTest,
const String &texName) const Ogre::String &texName)
{ {
MaterialPtr material = MaterialManager::getSingleton().create(name, resourceGroup); Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(name, resourceGroup);
//Hardware Skinning code, textures may be the wrong color if enabled //Hardware Skinning code, textures may be the wrong color if enabled
@ -249,11 +232,11 @@ void NIFLoader::createMaterial(const String &name,
if (!texName.empty()) if (!texName.empty())
{ {
Pass *pass = material->getTechnique(0)->getPass(0); Ogre::Pass *pass = material->getTechnique(0)->getPass(0);
/*TextureUnitState *txt =*/ /*TextureUnitState *txt =*/
pass->createTextureUnitState(texName); pass->createTextureUnitState(texName);
pass->setVertexColourTracking(TVC_DIFFUSE); pass->setVertexColourTracking(Ogre::TVC_DIFFUSE);
// As of yet UNTESTED code from Chris: // As of yet UNTESTED code from Chris:
/*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC); /*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
@ -294,13 +277,13 @@ void NIFLoader::createMaterial(const String &name,
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName); NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
if (result.first) if (result.first)
{ {
pass->setAlphaRejectFunction(CMPF_GREATER_EQUAL); pass->setAlphaRejectFunction(Ogre::CMPF_GREATER_EQUAL);
pass->setAlphaRejectValue(result.second); pass->setAlphaRejectValue(result.second);
} }
else else
{ {
// Enable transparency // Enable transparency
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
//pass->setDepthCheckEnabled(false); //pass->setDepthCheckEnabled(false);
pass->setDepthWriteEnabled(false); pass->setDepthWriteEnabled(false);
@ -322,11 +305,11 @@ void NIFLoader::createMaterial(const String &name,
const int numsplits = 3; const int numsplits = 3;
for (int i = 0; i < (split ? numsplits : 1); ++i) for (int i = 0; i < (split ? numsplits : 1); ++i)
{ {
TextureUnitState* tu = material->getTechnique(0)->getPass(0)->createTextureUnitState(); Ogre::TextureUnitState* tu = material->getTechnique(0)->getPass(0)->createTextureUnitState();
tu->setName("shadowMap" + StringConverter::toString(i)); tu->setName("shadowMap" + Ogre::StringConverter::toString(i));
tu->setContentType(TextureUnitState::CONTENT_SHADOW); tu->setContentType(Ogre::TextureUnitState::CONTENT_SHADOW);
tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER); tu->setTextureAddressingMode(Ogre::TextureUnitState::TAM_BORDER);
tu->setTextureBorderColour(ColourValue::White); tu->setTextureBorderColour(Ogre::ColourValue::White);
} }
} }
@ -339,11 +322,11 @@ void NIFLoader::createMaterial(const String &name,
} }
// Create a fallback technique without shadows and without mrt // Create a fallback technique without shadows and without mrt
Technique* tech2 = material->createTechnique(); Ogre::Technique* tech2 = material->createTechnique();
tech2->setSchemeName("Fallback"); tech2->setSchemeName("Fallback");
Pass* pass2 = tech2->createPass(); Ogre::Pass* pass2 = tech2->createPass();
pass2->createTextureUnitState(texName); pass2->createTextureUnitState(texName);
pass2->setVertexColourTracking(TVC_DIFFUSE); pass2->setVertexColourTracking(Ogre::TVC_DIFFUSE);
if (Settings::Manager::getBool("shaders", "Objects")) if (Settings::Manager::getBool("shaders", "Objects"))
{ {
pass2->setVertexProgram("main_fallback_vp"); pass2->setVertexProgram("main_fallback_vp");
@ -352,16 +335,16 @@ void NIFLoader::createMaterial(const String &name,
} }
// Add material bells and whistles // Add material bells and whistles
material->setAmbient(ambient.array[0], ambient.array[1], ambient.array[2]); material->setAmbient(ambient[0], ambient[1], ambient[2]);
material->setDiffuse(diffuse.array[0], diffuse.array[1], diffuse.array[2], alpha); material->setDiffuse(diffuse[0], diffuse[1], diffuse[2], alpha);
material->setSpecular(specular.array[0], specular.array[1], specular.array[2], alpha); material->setSpecular(specular[0], specular[1], specular[2], alpha);
material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]); material->setSelfIllumination(emissive[0], emissive[1], emissive[2]);
material->setShininess(glossiness); material->setShininess(glossiness);
} }
// Takes a name and adds a unique part to it. This is just used to // Takes a name and adds a unique part to it. This is just used to
// make sure that all materials are given unique names. // make sure that all materials are given unique names.
String NIFLoader::getUniqueName(const String &input) Ogre::String NIFLoader::getUniqueName(const Ogre::String &input)
{ {
static int addon = 0; static int addon = 0;
static char buf[8]; static char buf[8];
@ -377,29 +360,25 @@ String NIFLoader::getUniqueName(const String &input)
// does not, change the string IN PLACE to say .dds instead and try // does not, change the string IN PLACE to say .dds instead and try
// that. The texture may still not exist, but no information of value // that. The texture may still not exist, but no information of value
// is lost in that case. // is lost in that case.
void NIFLoader::findRealTexture(String &texName) void NIFLoader::findRealTexture(Ogre::String &texName)
{ {
assert(vfs); if(Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
if (vfs->isFile(texName)) return; return;
int len = texName.size();
if (len < 4) return;
// Change texture extension to .dds // Change texture extension to .dds
texName[len-3] = 'd'; Ogre::String::size_type pos = texName.rfind('.');
texName[len-2] = 'd'; texName.replace(pos, texName.length(), ".dds");
texName[len-1] = 's';
} }
//Handle node at top //Handle node at top
// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given // Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given
// mesh. // mesh.
void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list<VertexBoneAssignment> &vertexBoneAssignments) void NIFLoader::createOgreSubMesh(NiTriShape *shape, const Ogre::String &material, std::list<Ogre::VertexBoneAssignment> &vertexBoneAssignments)
{ {
// cout << "s:" << shape << "\n"; // cout << "s:" << shape << "\n";
NiTriShapeData *data = shape->data.getPtr(); NiTriShapeData *data = shape->data.getPtr();
SubMesh *sub = mesh->createSubMesh(shape->name.toString()); Ogre::SubMesh *sub = mesh->createSubMesh(shape->name);
int nextBuf = 0; int nextBuf = 0;
@ -407,27 +386,27 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
// great. // great.
// Add vertices // Add vertices
int numVerts = data->vertices.length / 3; int numVerts = data->vertices.size() / 3;
sub->vertexData = new VertexData(); sub->vertexData = new Ogre::VertexData();
sub->vertexData->vertexCount = numVerts; sub->vertexData->vertexCount = numVerts;
sub->useSharedVertices = false; sub->useSharedVertices = false;
VertexDeclaration *decl = sub->vertexData->vertexDeclaration; Ogre::VertexDeclaration *decl = sub->vertexData->vertexDeclaration;
decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION); decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareVertexBufferSharedPtr vbuf =
HardwareBufferManager::getSingleton().createVertexBuffer( Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT3), Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
numVerts, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false); numVerts, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false);
if(flip) if(flip)
{ {
float *datamod = new float[data->vertices.length]; float *datamod = new float[data->vertices.size()];
//std::cout << "Shape" << shape->name.toString() << "\n"; //std::cout << "Shape" << shape->name.toString() << "\n";
for(int i = 0; i < numVerts; i++) for(int i = 0; i < numVerts; i++)
{ {
int index = i * 3; int index = i * 3;
const float *pos = data->vertices.ptr + index; const float *pos = &data->vertices[index];
Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2)); Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2));
original = mTransform * original; original = mTransform * original;
mBoundingBox.merge(original); mBoundingBox.merge(original);
@ -440,30 +419,30 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
} }
else else
{ {
vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, false); vbuf->writeData(0, vbuf->getSizeInBytes(), &data->vertices[0], false);
} }
VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding; Ogre::VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
bind->setBinding(nextBuf++, vbuf); bind->setBinding(nextBuf++, vbuf);
if (data->normals.length) if (data->normals.size())
{ {
decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL); decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT3), Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
if(flip) if(flip)
{ {
Quaternion rotation = mTransform.extractQuaternion(); Ogre::Quaternion rotation = mTransform.extractQuaternion();
rotation.normalise(); rotation.normalise();
float *datamod = new float[data->normals.length]; float *datamod = new float[data->normals.size()];
for(int i = 0; i < numVerts; i++) for(int i = 0; i < numVerts; i++)
{ {
int index = i * 3; int index = i * 3;
const float *pos = data->normals.ptr + index; const float *pos = &data->normals[index];
Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2)); Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2));
original = rotation * original; original = rotation * original;
if (mNormaliseNormals) if (mNormaliseNormals)
@ -481,49 +460,49 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
} }
else else
{ {
vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, false); vbuf->writeData(0, vbuf->getSizeInBytes(), &data->normals[0], false);
} }
bind->setBinding(nextBuf++, vbuf); bind->setBinding(nextBuf++, vbuf);
} }
// Vertex colors // Vertex colors
if (data->colors.length) if (data->colors.size())
{ {
const float *colors = data->colors.ptr; const float *colors = &data->colors[0];
RenderSystem* rs = Root::getSingleton().getRenderSystem(); Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
std::vector<RGBA> colorsRGB(numVerts); std::vector<Ogre::RGBA> colorsRGB(numVerts);
RGBA *pColour = &colorsRGB.front(); Ogre::RGBA *pColour = &colorsRGB.front();
for (int i=0; i<numVerts; i++) for (int i=0; i<numVerts; i++)
{ {
rs->convertColourValue(ColourValue(colors[0],colors[1],colors[2], rs->convertColourValue(Ogre::ColourValue(colors[0],colors[1],colors[2],
colors[3]),pColour++); colors[3]),pColour++);
colors += 4; colors += 4;
} }
decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE); decl->addElement(nextBuf, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_COLOUR), Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true); vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true);
bind->setBinding(nextBuf++, vbuf); bind->setBinding(nextBuf++, vbuf);
} }
if (data->uvlist.length) if (data->uvlist.size())
{ {
decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); decl->addElement(nextBuf, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT2), Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY,false); numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,false);
if(flip) if(flip)
{ {
float *datamod = new float[data->uvlist.length]; float *datamod = new float[data->uvlist.size()];
for(unsigned int i = 0; i < data->uvlist.length; i+=2){ for(unsigned int i = 0; i < data->uvlist.size(); i+=2){
float x = *(data->uvlist.ptr + i); float x = data->uvlist[i];
float y = *(data->uvlist.ptr + i + 1); float y = data->uvlist[i + 1];
datamod[i] =x; datamod[i] =x;
datamod[i + 1] =y; datamod[i + 1] =y;
@ -532,36 +511,34 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
delete [] datamod; delete [] datamod;
} }
else else
vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, false); vbuf->writeData(0, vbuf->getSizeInBytes(), &data->uvlist[0], false);
bind->setBinding(nextBuf++, vbuf); bind->setBinding(nextBuf++, vbuf);
} }
// Triangle faces - The total number of triangle points // Triangle faces - The total number of triangle points
int numFaces = data->triangles.length; int numFaces = data->triangles.size();
if (numFaces) if (numFaces)
{ {
sub->indexData->indexCount = numFaces; sub->indexData->indexCount = numFaces;
sub->indexData->indexStart = 0; sub->indexData->indexStart = 0;
HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().
createIndexBuffer(HardwareIndexBuffer::IT_16BIT, createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, numFaces,
numFaces, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);
HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);
if(flip && mFlipVertexWinding && sub->indexData->indexCount % 3 == 0){ if(flip && mFlipVertexWinding && sub->indexData->indexCount % 3 == 0){
sub->indexData->indexBuffer = ibuf; sub->indexData->indexBuffer = ibuf;
uint16 *datamod = new uint16[numFaces]; uint16_t *datamod = new uint16_t[numFaces];
int index = 0; int index = 0;
for (size_t i = 0; i < sub->indexData->indexCount; i+=3) for (size_t i = 0; i < sub->indexData->indexCount; i+=3)
{ {
const short *pos = data->triangles.ptr + index; const short *pos = &data->triangles[index];
uint16 i0 = (uint16) *(pos+0); uint16_t i0 = (uint16_t) *(pos+0);
uint16 i1 = (uint16) *(pos+1); uint16_t i1 = (uint16_t) *(pos+1);
uint16 i2 = (uint16) *(pos+2); uint16_t i2 = (uint16_t) *(pos+2);
//std::cout << "i0: " << i0 << "i1: " << i1 << "i2: " << i2 << "\n"; //std::cout << "i0: " << i0 << "i1: " << i1 << "i2: " << i2 << "\n";
@ -578,7 +555,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
} }
else else
ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false); ibuf->writeData(0, ibuf->getSizeInBytes(), &data->triangles[0], false);
sub->indexData->indexBuffer = ibuf; sub->indexData->indexBuffer = ibuf;
} }
@ -587,7 +564,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
//add vertex bone assignments //add vertex bone assignments
for (std::list<VertexBoneAssignment>::iterator it = vertexBoneAssignments.begin(); for (std::list<Ogre::VertexBoneAssignment>::iterator it = vertexBoneAssignments.begin();
it != vertexBoneAssignments.end(); it++) it != vertexBoneAssignments.end(); it++)
{ {
sub->addBoneAssignment(*it); sub->addBoneAssignment(*it);
@ -598,23 +575,8 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
// Helper math functions. Reinventing linear algebra for the win! // Helper math functions. Reinventing linear algebra for the win!
// Computes B = AxB (matrix*matrix)
static void matrixMul(const Matrix &A, Matrix &B)
{
for (int i=0;i<3;i++)
{
float a = B.v[0].array[i];
float b = B.v[1].array[i];
float c = B.v[2].array[i];
B.v[0].array[i] = a*A.v[0].array[0] + b*A.v[0].array[1] + c*A.v[0].array[2];
B.v[1].array[i] = a*A.v[1].array[0] + b*A.v[1].array[1] + c*A.v[1].array[2];
B.v[2].array[i] = a*A.v[2].array[0] + b*A.v[2].array[1] + c*A.v[2].array[2];
}
}
// Computes C = B + AxC*scale // Computes C = B + AxC*scale
static void vectorMulAdd(const Matrix &A, const Vector &B, float *C, float scale) static void vectorMulAdd(const Ogre::Matrix3 &A, const Ogre::Vector3 &B, float *C, float scale)
{ {
// Keep the original values // Keep the original values
float a = C[0]; float a = C[0];
@ -623,11 +585,11 @@ static void vectorMulAdd(const Matrix &A, const Vector &B, float *C, float scale
// Perform matrix multiplication, scaling and addition // Perform matrix multiplication, scaling and addition
for (int i=0;i<3;i++) for (int i=0;i<3;i++)
C[i] = B.array[i] + (a*A.v[i].array[0] + b*A.v[i].array[1] + c*A.v[i].array[2])*scale; C[i] = B[i] + (a*A[i][0] + b*A[i][1] + c*A[i][2])*scale;
} }
// Computes B = AxB (matrix*vector) // Computes B = AxB (matrix*vector)
static void vectorMul(const Matrix &A, float *C) static void vectorMul(const Ogre::Matrix3 &A, float *C)
{ {
// Keep the original values // Keep the original values
float a = C[0]; float a = C[0];
@ -636,7 +598,7 @@ static void vectorMul(const Matrix &A, float *C)
// Perform matrix multiplication, scaling and addition // Perform matrix multiplication, scaling and addition
for (int i=0;i<3;i++) for (int i=0;i<3;i++)
C[i] = a*A.v[i].array[0] + b*A.v[i].array[1] + c*A.v[i].array[2]; C[i] = a*A[i][0] + b*A[i][1] + c*A[i][2];
} }
@ -671,7 +633,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
return; return;
// Material name for this submesh, if any // Material name for this submesh, if any
String material; Ogre::String material;
// Skip the entire material phase for hidden nodes // Skip the entire material phase for hidden nodes
if (!hidden) if (!hidden)
@ -700,14 +662,12 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
} }
// Texture // Texture
String texName; Ogre::String texName;
if (t && t->textures[0].inUse) if (t && t->textures[0].inUse)
{ {
NiSourceTexture *st = t->textures[0].texture.getPtr(); NiSourceTexture *st = t->textures[0].texture.getPtr();
if (st->external) if (st->external)
{ {
SString tname = st->filename;
/* findRealTexture checks if the file actually /* findRealTexture checks if the file actually
exists. If it doesn't, and the name ends in .tga, it exists. If it doesn't, and the name ends in .tga, it
will try replacing the extension with .dds instead will try replacing the extension with .dds instead
@ -721,7 +681,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
problem since all the nif data is stored in a local problem since all the nif data is stored in a local
throwaway buffer. throwaway buffer.
*/ */
texName = "textures\\" + tname.toString(); texName = "textures\\" + st->filename;
findRealTexture(texName); findRealTexture(texName);
} }
else warn("Found internal texture, ignoring."); else warn("Found internal texture, ignoring.");
@ -733,7 +693,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
if (a) if (a)
{ {
alphaFlags = a->flags; alphaFlags = a->flags;
alphaTest = a->data->threshold; alphaTest = a->data.threshold;
} }
// Material // Material
@ -748,7 +708,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
if (m) if (m)
{ {
// Use NiMaterialProperty data to create the data // Use NiMaterialProperty data to create the data
const S_MaterialProperty *d = m->data; const S_MaterialProperty *d = &m->data;
std::multimap<std::string,std::string>::iterator itr = MaterialMap.find(texName); std::multimap<std::string,std::string>::iterator itr = MaterialMap.find(texName);
std::multimap<std::string,std::string>::iterator lastElement; std::multimap<std::string,std::string>::iterator lastElement;
@ -775,14 +735,8 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
{ {
// We only have a texture name. Create a default // We only have a texture name. Create a default
// material for it. // material for it.
Vector zero, one; const Ogre::Vector3 zero(0.0f), one(1.0f);
for (int i=0; i<3;i++) createMaterial(material, one, one, zero, zero, 0.0f, 1.0f,
{
zero.array[i] = 0.0;
one.array[i] = 1.0;
}
createMaterial(material, one, one, zero, zero, 0.0, 1.0,
alphaFlags, alphaTest, texName); alphaFlags, alphaTest, texName);
} }
} }
@ -795,12 +749,12 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
level. level.
*/ */
NiTriShapeData *data = shape->data.getPtr(); NiTriShapeData *data = shape->data.getPtr();
int numVerts = data->vertices.length / 3; int numVerts = data->vertices.size() / 3;
float *ptr = (float*)data->vertices.ptr; float *ptr = (float*)&data->vertices[0];
float *optr = ptr; float *optr = ptr;
std::list<VertexBoneAssignment> vertexBoneAssignments; std::list<Ogre::VertexBoneAssignment> vertexBoneAssignments;
Nif::NiTriShapeCopy copy = shape->clone(); Nif::NiTriShapeCopy copy = shape->clone();
@ -828,14 +782,14 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
std::vector<Ogre::Vector3> vertexPosOriginal(numVerts, Ogre::Vector3::ZERO); std::vector<Ogre::Vector3> vertexPosOriginal(numVerts, Ogre::Vector3::ZERO);
std::vector<Ogre::Vector3> vertexNormalOriginal(numVerts, Ogre::Vector3::ZERO); std::vector<Ogre::Vector3> vertexNormalOriginal(numVerts, Ogre::Vector3::ZERO);
float *ptrNormals = (float*)data->normals.ptr; float *ptrNormals = (float*)&data->normals[0];
//the bone from skin->bones[boneIndex] is linked to skin->data->bones[boneIndex] //the bone from skin->bones[boneIndex] is linked to skin->data->bones[boneIndex]
//the first one contains a link to the bone, the second vertex transformation //the first one contains a link to the bone, the second vertex transformation
//relative to the bone //relative to the bone
int boneIndex = 0; int boneIndex = 0;
Bone *bonePtr; Ogre::Bone *bonePtr;
Vector3 vecPos; Ogre::Vector3 vecPos;
Quaternion vecRot; Ogre::Quaternion vecRot;
std::vector<NiSkinData::BoneInfo> boneList = shape->skin->data->bones; std::vector<NiSkinData::BoneInfo> boneList = shape->skin->data->bones;
@ -849,33 +803,33 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
{ {
if(mSkel.isNull()) if(mSkel.isNull())
{ {
std::cout << "No skeleton for :" << shape->skin->bones[boneIndex].name.toString() << std::endl; std::cout << "No skeleton for :" << shape->skin->bones[boneIndex].name << std::endl;
break; break;
} }
//get the bone from bones array of skindata //get the bone from bones array of skindata
if(!mSkel->hasBone(shape->skin->bones[boneIndex].name.toString())) if(!mSkel->hasBone(shape->skin->bones[boneIndex].name))
std::cout << "We don't have this bone"; std::cout << "We don't have this bone";
bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name.toString()); bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name);
// final_vector = old_vector + old_rotation*new_vector*old_scale // final_vector = old_vector + old_rotation*new_vector*old_scale
Nif::NiSkinData::BoneInfoCopy boneinfocopy; Nif::NiSkinData::BoneInfoCopy boneinfocopy;
boneinfocopy.trafo.rotation = convertRotation(it->trafo->rotation); boneinfocopy.trafo.rotation = it->trafo.rotation;
boneinfocopy.trafo.trans = convertVector3(it->trafo->trans); boneinfocopy.trafo.trans = it->trafo.trans;
boneinfocopy.bonename = shape->skin->bones[boneIndex].name.toString(); boneinfocopy.bonename = shape->skin->bones[boneIndex].name;
boneinfocopy.bonehandle = bonePtr->getHandle(); boneinfocopy.bonehandle = bonePtr->getHandle();
copy.boneinfo.push_back(boneinfocopy); copy.boneinfo.push_back(boneinfocopy);
for (unsigned int i=0; i<it->weights.length; i++) for (unsigned int i=0; i<it->weights.size(); i++)
{ {
vecPos = bonePtr->_getDerivedPosition() + vecPos = bonePtr->_getDerivedPosition() +
bonePtr->_getDerivedOrientation() * convertVector3(it->trafo->trans); bonePtr->_getDerivedOrientation() * it->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo->rotation); vecRot = bonePtr->_getDerivedOrientation() * it->trafo.rotation;
unsigned int verIndex = (it->weights.ptr + i)->vertex; unsigned int verIndex = it->weights[i].vertex;
//boneinfo.weights.push_back(*(it->weights.ptr + i)); //boneinfo.weights.push_back(*(it->weights.ptr + i));
Nif::NiSkinData::IndividualWeight ind; Nif::NiSkinData::IndividualWeight ind;
ind.weight = (it->weights.ptr + i)->weight; ind.weight = it->weights[i].weight;
ind.boneinfocopyindex = copy.boneinfo.size() - 1; ind.boneinfocopyindex = copy.boneinfo.size() - 1;
if(copy.vertsToWeights.find(verIndex) == copy.vertsToWeights.end()) if(copy.vertsToWeights.find(verIndex) == copy.vertsToWeights.end())
{ {
@ -892,9 +846,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
if (vertexPosAbsolut[verIndex] == false) if (vertexPosAbsolut[verIndex] == false)
{ {
//apply transformation to the vertices //apply transformation to the vertices
Vector3 absVertPos = vecPos + vecRot * Vector3(ptr + verIndex *3); Ogre::Vector3 absVertPos = vecPos + vecRot * Ogre::Vector3(ptr + verIndex *3);
absVertPos = absVertPos * (it->weights.ptr + i)->weight; absVertPos = absVertPos * it->weights[i].weight;
vertexPosOriginal[verIndex] = Vector3(ptr + verIndex *3); vertexPosOriginal[verIndex] = Ogre::Vector3(ptr + verIndex *3);
mBoundingBox.merge(absVertPos); mBoundingBox.merge(absVertPos);
//convert it back to float * //convert it back to float *
@ -903,11 +857,11 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
//apply rotation to the normals (not every vertex has a normal) //apply rotation to the normals (not every vertex has a normal)
//FIXME: I guessed that vertex[i] = normal[i], is that true? //FIXME: I guessed that vertex[i] = normal[i], is that true?
if (verIndex < data->normals.length) if (verIndex < data->normals.size())
{ {
Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3); Ogre::Vector3 absNormalsPos = vecRot * Ogre::Vector3(ptrNormals + verIndex *3);
absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight; absNormalsPos = absNormalsPos * it->weights[i].weight;
vertexNormalOriginal[verIndex] = Vector3(ptrNormals + verIndex *3); vertexNormalOriginal[verIndex] = Ogre::Vector3(ptrNormals + verIndex *3);
for (int j=0; j<3; j++) for (int j=0; j<3; j++)
(ptrNormals + verIndex*3)[j] = absNormalsPos[j]; (ptrNormals + verIndex*3)[j] = absNormalsPos[j];
@ -917,9 +871,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
} }
else else
{ {
Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex]; Ogre::Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex];
absVertPos = absVertPos * (it->weights.ptr + i)->weight; absVertPos = absVertPos * it->weights[i].weight;
Vector3 old = Vector3(ptr + verIndex *3); Ogre::Vector3 old = Ogre::Vector3(ptr + verIndex *3);
absVertPos = absVertPos + old; absVertPos = absVertPos + old;
mBoundingBox.merge(absVertPos); mBoundingBox.merge(absVertPos);
@ -929,11 +883,11 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
//apply rotation to the normals (not every vertex has a normal) //apply rotation to the normals (not every vertex has a normal)
//FIXME: I guessed that vertex[i] = normal[i], is that true? //FIXME: I guessed that vertex[i] = normal[i], is that true?
if (verIndex < data->normals.length) if (verIndex < data->normals.size())
{ {
Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex]; Ogre::Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex];
absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight; absNormalsPos = absNormalsPos * it->weights[i].weight;
Vector3 oldNormal = Vector3(ptrNormals + verIndex *3); Ogre::Vector3 oldNormal = Ogre::Vector3(ptrNormals + verIndex *3);
absNormalsPos = absNormalsPos + oldNormal; absNormalsPos = absNormalsPos + oldNormal;
for (int j=0; j<3; j++) for (int j=0; j<3; j++)
@ -942,10 +896,10 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
} }
VertexBoneAssignment vba; Ogre::VertexBoneAssignment vba;
vba.boneIndex = bonePtr->getHandle(); vba.boneIndex = bonePtr->getHandle();
vba.vertexIndex = verIndex; vba.vertexIndex = verIndex;
vba.weight = (it->weights.ptr + i)->weight; vba.weight = it->weights[i].weight;
vertexBoneAssignments.push_back(vba); vertexBoneAssignments.push_back(vba);
@ -962,12 +916,12 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
copy.boneSequence = boneSequence; copy.boneSequence = boneSequence;
// Rotate, scale and translate all the vertices, // Rotate, scale and translate all the vertices,
const Matrix &rot = shape->trafo->rotation; const Ogre::Matrix3 &rot = shape->trafo.rotation;
const Vector &pos = shape->trafo->pos; const Ogre::Vector3 &pos = shape->trafo.pos;
float scale = shape->trafo->scale; float scale = shape->trafo.scale;
copy.trafo.trans = convertVector3(original.pos); copy.trafo.trans = original.pos;
copy.trafo.rotation = convertRotation(original.rotation); copy.trafo.rotation = original.rotation;
copy.trafo.scale = original.scale; copy.trafo.scale = original.scale;
//We don't use velocity for anything yet, so it does not need to be saved //We don't use velocity for anything yet, so it does not need to be saved
@ -975,15 +929,15 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
for (int i=0; i<numVerts; i++) for (int i=0; i<numVerts; i++)
{ {
vectorMulAdd(rot, pos, ptr, scale); vectorMulAdd(rot, pos, ptr, scale);
Ogre::Vector3 absVertPos = Ogre::Vector3(*(ptr + 3 * i), *(ptr + 3 * i + 1), *(ptr + 3 * i + 2)); Ogre::Vector3 absVertPos = Ogre::Vector3(ptr);
mBoundingBox.merge(absVertPos); mBoundingBox.merge(absVertPos);
ptr += 3; ptr += 3;
} }
// Remember to rotate all the vertex normals as well // Remember to rotate all the vertex normals as well
if (data->normals.length) if (data->normals.size())
{ {
ptr = (float*)data->normals.ptr; ptr = (float*)&data->normals[0];
for (int i=0; i<numVerts; i++) for (int i=0; i<numVerts; i++)
{ {
vectorMul(rot, ptr); vectorMul(rot, ptr);
@ -995,7 +949,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
boneIndex = mSkel->getNumBones() - 1; boneIndex = mSkel->getNumBones() - 1;
for(int i = 0; i < numVerts; i++){ for(int i = 0; i < numVerts; i++){
VertexBoneAssignment vba; Ogre::VertexBoneAssignment vba;
vba.boneIndex = boneIndex; vba.boneIndex = boneIndex;
vba.vertexIndex = i; vba.vertexIndex = i;
vba.weight = 1; vba.weight = 1;
@ -1019,15 +973,15 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
void NIFLoader::calculateTransform() void NIFLoader::calculateTransform()
{ {
// Calculate transform // Calculate transform
Matrix4 transform = Matrix4::IDENTITY; Ogre::Matrix4 transform = Ogre::Matrix4::IDENTITY;
transform = Matrix4::getScale(vector) * transform; transform = Ogre::Matrix4::getScale(vector) * transform;
// Check whether we have to flip vertex winding. // Check whether we have to flip vertex winding.
// We do have to, if we changed our right hand base. // We do have to, if we changed our right hand base.
// We can test it by using the cross product from X and Y and see, if it is a non-negative // We can test it by using the cross product from X and Y and see, if it is a non-negative
// projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet, // projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet,
// but the test is cheap either way. // but the test is cheap either way.
Matrix3 m3; Ogre::Matrix3 m3;
transform.extract3x3Matrix(m3); transform.extract3x3Matrix(m3);
if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0) if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0)
@ -1090,7 +1044,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
for(std::vector<Nif::NiTextKeyExtraData::TextKey>::iterator textiter = extra->list.begin(); textiter != extra->list.end(); textiter++) for(std::vector<Nif::NiTextKeyExtraData::TextKey>::iterator textiter = extra->list.begin(); textiter != extra->list.end(); textiter++)
{ {
std::string text = textiter->text.toString(); std::string text = textiter->text;
replace(text.begin(), text.end(), '\n', '/'); replace(text.begin(), text.end(), '\n', '/');
@ -1121,7 +1075,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
} }
} }
Bone *bone = 0; Ogre::Bone *bone = 0;
// create skeleton or add bones // create skeleton or add bones
if (node->recType == RC_NiNode) if (node->recType == RC_NiNode)
@ -1131,14 +1085,14 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
{ {
inTheSkeletonTree = true; inTheSkeletonTree = true;
mSkel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true); mSkel = Ogre::SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true);
} }
else if (!mSkel.isNull() && !parentBone) else if (!mSkel.isNull() && !parentBone)
inTheSkeletonTree = false; inTheSkeletonTree = false;
if (!mSkel.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;
// 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.
@ -1151,30 +1105,29 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
parentBone->addChild(bone); parentBone->addChild(bone);
bone->setInheritOrientation(true); bone->setInheritOrientation(true);
bone->setPosition(convertVector3(node->trafo->pos)); bone->setPosition(node->trafo.pos);
bone->setOrientation(convertRotation(node->trafo->rotation)); bone->setOrientation(node->trafo.rotation);
} }
} }
} }
Transformation original = *(node->trafo); Transformation original = node->trafo;
// Apply the parent transformation to this node. We overwrite the // Apply the parent transformation to this node. We overwrite the
// existing data with the final transformation. // existing data with the final transformation.
if (trafo) if (trafo)
{ {
// Get a non-const reference to the node's data, since we're // Get a non-const reference to the node's data, since we're
// overwriting it. TODO: Is this necessary? // overwriting it. TODO: Is this necessary?
Transformation &final = *((Transformation*)node->trafo); Transformation &final = node->trafo;
// For both position and rotation we have that: // For both position and rotation we have that:
// final_vector = old_vector + old_rotation*new_vector*old_scale // final_vector = old_vector + old_rotation*new_vector*old_scale
vectorMulAdd(trafo->rotation, trafo->pos, final.pos.array, trafo->scale); final.pos = trafo->pos + trafo->rotation*final.pos*trafo->scale;
vectorMulAdd(trafo->rotation, trafo->velocity, final.velocity.array, trafo->scale); final.velocity = trafo->velocity + trafo->rotation*final.velocity*trafo->scale;
// Merge the rotations together // Merge the rotations together
matrixMul(trafo->rotation, final.rotation); final.rotation = trafo->rotation * final.rotation;
// Scalar values are so nice to deal with. Why can't everything // Scale
// just be scalar?
final.scale *= trafo->scale; final.scale *= trafo->scale;
} }
@ -1187,12 +1140,12 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
{ {
if (list.has(i)) if (list.has(i))
handleNode(&list[i], flags, node->trafo, bounds, bone, boneSequence); handleNode(&list[i], flags, &node->trafo, bounds, bone, boneSequence);
} }
} }
else if (node->recType == RC_NiTriShape && bNiTri) else if (node->recType == RC_NiTriShape && bNiTri)
{ {
std::string nodename = node->name.toString(); std::string nodename = node->name;
if (triname == "") if (triname == "")
{ {
@ -1207,7 +1160,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
} }
} }
void NIFLoader::loadResource(Resource *resource) void NIFLoader::loadResource(Ogre::Resource *resource)
{ {
inTheSkeletonTree = false; inTheSkeletonTree = false;
allanim.clear(); allanim.clear();
@ -1293,22 +1246,13 @@ void NIFLoader::loadResource(Resource *resource)
{ {
calculateTransform(); calculateTransform();
} }
// Set up the VFS if it hasn't been done already
if (!vfs) vfs = new OgreVFS(resourceGroup);
// Get the mesh // Get the mesh
mesh = dynamic_cast<Mesh*>(resource); mesh = dynamic_cast<Ogre::Mesh*>(resource);
assert(mesh); assert(mesh);
// Look it up // Look it up
resourceName = mesh->getName(); resourceName = mesh->getName();
//std::cout << resourceName << "\n";
if (!vfs->isFile(resourceName))
{
warn("File "+resourceName+" not found.");
return;
}
// Helper that computes bounding boxes for us. // Helper that computes bounding boxes for us.
BoundsFinder bounds; BoundsFinder bounds;
@ -1317,8 +1261,7 @@ void NIFLoader::loadResource(Resource *resource)
// of the early stages of development. Right now we WANT to catch // of the early stages of development. Right now we WANT to catch
// every error as early and intrusively as possible, as it's most // every error as early and intrusively as possible, as it's most
// likely a sign of incomplete code rather than faulty input. // likely a sign of incomplete code rather than faulty input.
NIFFile nif(vfs->open(resourceName), resourceName); NIFFile nif(resourceName);
if (nif.numRecords() < 1) if (nif.numRecords() < 1)
{ {
warn("Found no records in NIF."); warn("Found no records in NIF.");
@ -1334,7 +1277,7 @@ void NIFLoader::loadResource(Resource *resource)
if (node == NULL) if (node == NULL)
{ {
warn("First record in file was not a node, but a " + warn("First record in file was not a node, but a " +
r->recName.toString() + ". Skipping file."); r->recName + ". Skipping file.");
return; return;
} }
@ -1358,7 +1301,7 @@ void NIFLoader::loadResource(Resource *resource)
if (f->timeStart >= 10000000000000000.0f) if (f->timeStart >= 10000000000000000.0f)
continue; continue;
data->setBonename(o->name.toString()); data->setBonename(o->name);
data->setStartTime(f->timeStart); data->setStartTime(f->timeStart);
data->setStopTime(f->timeStop); data->setStopTime(f->timeStop);
@ -1369,8 +1312,8 @@ void NIFLoader::loadResource(Resource *resource)
// set the bounding value. // set the bounding value.
if (bounds.isValid()) if (bounds.isValid())
{ {
mesh->_setBounds(AxisAlignedBox(bounds.minX(), bounds.minY(), bounds.minZ(), mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX(), bounds.minY(), bounds.minZ(),
bounds.maxX(), bounds.maxY(), bounds.maxZ())); bounds.maxX(), bounds.maxY(), bounds.maxZ()));
mesh->_setBoundingSphereRadius(bounds.getRadius()); mesh->_setBoundingSphereRadius(bounds.getRadius());
} }
if(hasAnim && addAnim){ if(hasAnim && addAnim){
@ -1392,7 +1335,7 @@ void NIFLoader::loadResource(Resource *resource)
for(std::vector<Ogre::SubMesh*>::iterator iter = needBoneAssignments.begin(); iter != needBoneAssignments.end(); iter++) for(std::vector<Ogre::SubMesh*>::iterator iter = needBoneAssignments.begin(); iter != needBoneAssignments.end(); iter++)
{ {
int boneIndex = mSkel->getNumBones() - 1; int boneIndex = mSkel->getNumBones() - 1;
VertexBoneAssignment vba; Ogre::VertexBoneAssignment vba;
vba.boneIndex = boneIndex; vba.boneIndex = boneIndex;
vba.vertexIndex = 0; vba.vertexIndex = 0;
vba.weight = 1; vba.weight = 1;
@ -1411,20 +1354,19 @@ void NIFLoader::loadResource(Resource *resource)
MeshPtr NIFLoader::load(const std::string &name, Ogre::MeshPtr NIFLoader::load(const std::string &name, const std::string &group)
const std::string &group)
{ {
MeshManager *m = MeshManager::getSingletonPtr(); Ogre::MeshManager *m = Ogre::MeshManager::getSingletonPtr();
// Check if the resource already exists // Check if the resource already exists
ResourcePtr ptr = m->getByName(name, group); Ogre::ResourcePtr ptr = m->getByName(name, group);
MeshPtr themesh; Ogre::MeshPtr themesh;
if (!ptr.isNull()){ if (!ptr.isNull()){
themesh = MeshPtr(ptr); themesh = Ogre::MeshPtr(ptr);
} }
else // Nope, create a new one. else // Nope, create a new one.
{ {
themesh = MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr()); themesh = Ogre::MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr());
} }
return themesh; return themesh;
} }

View file

@ -28,32 +28,20 @@
#include <OgreMesh.h> #include <OgreMesh.h>
#include <cassert> #include <cassert>
#include <string>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <libs/mangle/vfs/servers/ogre_vfs.hpp>
#include "../nif/nif_file.hpp"
#include "../nif/node.hpp" #include "../nif/node.hpp"
#include "../nif/data.hpp"
#include "../nif/property.hpp"
#include "../nif/controller.hpp"
#include "../nif/extra.hpp"
#include <libs/platform/strings.h> #include <libs/platform/strings.h>
#include <vector>
#include <list>
// For warning messages
#include <limits>
using namespace boost::algorithm;
class BoundsFinder; class BoundsFinder;
struct ciLessBoost : std::binary_function<std::string, std::string, bool> struct ciLessBoost : std::binary_function<std::string, std::string, bool>
{ {
bool operator() (const std::string & s1, const std::string & s2) const { bool operator() (const std::string & s1, const std::string & s2) const
//case insensitive version of is_less {
return lexicographical_compare(s1, s2, is_iless()); //case insensitive version of is_less
return boost::algorithm::lexicographical_compare(s1, s2, boost::algorithm::is_iless());
} }
}; };
@ -62,16 +50,6 @@ namespace Nif
class Node; class Node;
class Transformation; class Transformation;
class NiTriShape; class NiTriShape;
class Vector;
class Matrix;
}
namespace Mangle
{
namespace VFS
{
class OgreVFS;
}
} }
namespace NifOgre namespace NifOgre
@ -110,9 +88,6 @@ class NIFLoader : Ogre::ManualResourceLoader
std::map<std::string, float>* getTextIndices(std::string name); std::map<std::string, float>* getTextIndices(std::string name);
Ogre::Vector3 convertVector3(const Nif::Vector& vec);
Ogre::Quaternion convertRotation(const Nif::Matrix& rot);
void setOutputAnimFiles(bool output); void setOutputAnimFiles(bool output);
void setVerbosePath(std::string path); void setVerbosePath(std::string path);
@ -136,10 +111,10 @@ class NIFLoader : Ogre::ManualResourceLoader
void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material, std::list<Ogre::VertexBoneAssignment> &vertexBoneAssignments); void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material, std::list<Ogre::VertexBoneAssignment> &vertexBoneAssignments);
void createMaterial(const Ogre::String &name, void createMaterial(const Ogre::String &name,
const Nif::Vector &ambient, const Ogre::Vector3 &ambient,
const Nif::Vector &diffuse, const Ogre::Vector3 &diffuse,
const Nif::Vector &specular, const Ogre::Vector3 &specular,
const Nif::Vector &emissive, const Ogre::Vector3 &emissive,
float glossiness, float alpha, float glossiness, float alpha,
int alphaFlags, float alphaTest, int alphaFlags, float alphaTest,
const Ogre::String &texName); const Ogre::String &texName);
@ -154,13 +129,6 @@ class NIFLoader : Ogre::ManualResourceLoader
return resourceName + ".skel"; return resourceName + ".skel";
} }
// This is the interface to the Ogre resource system. It allows us to
// load NIFs from BSAs, in the file system and in any other place we
// tell Ogre to look (eg. in zip or rar files.) It's also used to
// check for the existence of texture files, so we can exchange the
// extension from .tga to .dds if the texture is missing.
Mangle::VFS::OgreVFS *vfs;
std::string verbosePath; std::string verbosePath;
std::string resourceName; std::string resourceName;
std::string resourceGroup; std::string resourceGroup;
@ -197,3 +165,5 @@ class NIFLoader : Ogre::ManualResourceLoader
} }
#endif #endif

View file

@ -1,6 +1,5 @@
#include <Ogre.h> #include <Ogre.h>
#include <iostream> #include <iostream>
#include <assert.h>
using namespace std; using namespace std;
using namespace Ogre; using namespace Ogre;

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