From 2da51e5f5a72b2b5d715a73a8359a1b3d81626a6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 26 Jul 2010 17:15:38 +0800 Subject: [PATCH 01/24] read attribute names from GMST instead of using hard-coded names (doesn't fully work yet, because of encoding issues) --- apps/openmw/CMakeLists.txt | 12 +++++- apps/openmw/engine.cpp | 11 +++++ apps/openmw/mwgui/mw_layouts.hpp | 27 ++++++++---- apps/openmw/mwgui/window_manager.cpp | 6 +++ apps/openmw/mwgui/window_manager.hpp | 5 +++ apps/openmw/mwmechanics/mechanicsmanager.cpp | 43 ++++++++++++++++++++ apps/openmw/mwmechanics/mechanicsmanager.hpp | 30 ++++++++++++++ apps/openmw/mwworld/environment.hpp | 9 +++- components/esm_store/reclists.hpp | 9 ++++ 9 files changed, 140 insertions(+), 12 deletions(-) create mode 100644 apps/openmw/mwmechanics/mechanicsmanager.cpp create mode 100644 apps/openmw/mwmechanics/mechanicsmanager.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index c254dcaef..83960d64a 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -87,10 +87,18 @@ set(GAMEWORLD_HEADER ) source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER}) +set(GAMEMECHANICS + mwmechanics/mechanicsmanager.cpp) +set(GAMEMECHANICS_HEADER + mwmechanics/mechanicsmanager.hpp) +source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER}) -set(OPENMW_CPP ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT} ${GAMESOUND} ${GAMEGUI} ${GAMEWORLD}) +set(OPENMW_CPP ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT} ${GAMESOUND} ${GAMEGUI} ${GAMEWORLD} + ${GAMEMECHANICS} + ) set(OPENMW_HEADER ${GAME_HEADER} ${GAMEREND_HEADER} ${GAMEINPUT_HEADER} ${GAMESCRIPT_HEADER} - ${GAMESOUND_HEADER} ${GAMEGUI_HEADER} ${GAMEWORLD_HEADER}) + ${GAMESOUND_HEADER} ${GAMEGUI_HEADER} ${GAMEWORLD_HEADER} ${GAMEMECHANICS_HEADER} + ) # Main executable add_executable(openmw diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 39cfd7e2b..374ca41a1 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -24,6 +24,8 @@ #include "mwworld/ptr.hpp" #include "mwworld/environment.hpp" +#include "mwmechanics/mechanicsmanager.hpp" + #include void OMW::Engine::executeLocalScripts() @@ -81,6 +83,7 @@ OMW::Engine::~Engine() delete mEnvironment.mWorld; delete mEnvironment.mSoundManager; delete mEnvironment.mGlobalScripts; + delete mEnvironment.mMechanicsManager; delete mScriptManager; delete mScriptContext; } @@ -196,8 +199,10 @@ void OMW::Engine::go() mEnvironment.mWindowManager = new MWGui::WindowManager(mGuiManager->getGui(), mEnvironment, mExtensions, mNewGame); + // Create sound system mEnvironment.mSoundManager = new MWSound::SoundManager; + // Create script system mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full, mEnvironment); mScriptContext->setExtensions (&mExtensions); @@ -207,6 +212,12 @@ void OMW::Engine::go() mEnvironment.mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(), *mScriptManager); + + // Create game mechanics system + mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager ( + mEnvironment.mWorld->getStore(), *mEnvironment.mWindowManager); + + mEnvironment.mMechanicsManager->configureGUI(); // Sets up the input system MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayerPos(), diff --git a/apps/openmw/mwgui/mw_layouts.hpp b/apps/openmw/mwgui/mw_layouts.hpp index 33b1bd7de..6df5ee391 100644 --- a/apps/openmw/mwgui/mw_layouts.hpp +++ b/apps/openmw/mwgui/mw_layouts.hpp @@ -161,15 +161,6 @@ namespace MWGui setText("Race_str", "Race"); setText("Class_str", "Class"); - setText("Attrib1", "Strength"); - setText("Attrib2", "Intelligence"); - setText("Attrib3", "Willpower"); - setText("Attrib4", "Agility"); - setText("Attrib5", "Speed"); - setText("Attrib6", "Endurance"); - setText("Attrib7", "Personality"); - setText("Attrib8", "Luck"); - // These are just demo values, you should replace these with // real calls from outside the class later. setPlayerName("ThePlayer"); @@ -196,6 +187,24 @@ namespace MWGui { mMainWidget->setCaption(playerName); } + + /// Set label text for the value with the given ID. + void setLabel (const std::string& id, const std::string& label) + { + static const char *ids[] = + { + "Attrib1", "Attrib2", "Attrib3", "Attrib4", "Attrib5", "Attrib6", + "Attrib7", "Attrib8", + 0 + }; + + for (int i=0; ids[i]; ++i) + if (ids[i]==id) + { + setText (id, label); + break; + } + } }; } #endif diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 1cd70ec08..02a3e3561 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -84,3 +84,9 @@ void WindowManager::updateVisible() // All other modes are ignored } + +void WindowManager::setLabel (const std::string& id, const std::string& label) +{ + stats->setLabel (id, label); +} + diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 24021a6c6..d576c10b2 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -10,6 +10,8 @@ this class. */ +#include + namespace MyGUI { class Gui; @@ -134,6 +136,9 @@ namespace MWGui } MyGUI::Gui* getGui() const { return gui; } + + void setLabel (const std::string& id, const std::string& label); + ///< Set label text for the value with the given ID. }; } #endif diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp new file mode 100644 index 000000000..2d28b03ac --- /dev/null +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -0,0 +1,43 @@ + +#include "mechanicsmanager.hpp" + +#include + +#include "../mwgui/window_manager.hpp" + +namespace MWMechanics +{ + MechanicsManager::MechanicsManager (const ESMS::ESMStore& store, + MWGui::WindowManager& windowManager) + : mStore (store), mWindowManager (windowManager) + { + + } + + void MechanicsManager::configureGUI() + { + const char *names[][2] = + { + { "Attrib1", "sAttributeStrength" }, + { "Attrib2", "sAttributeIntelligence" }, + { "Attrib3", "sAttributeWillpower" }, + { "Attrib4", "sAttributeAgility" }, + { "Attrib5", "sAttributeSpeed" }, + { "Attrib6", "sAttributeEndurance" }, + { "Attrib7", "sAttributePersonality" }, + { "Attrib8", "sAttributeLuck" }, + { 0, 0 } + }; + + for (int i=0; names[i][0]; ++i) + { +// This crashes because of encoding problems: +// std::string label = mStore.gameSettings.find (names[i][1])->str; + + std::string label = names[i][1]; // until the problem is fixed, use the GMST ID as label + + mWindowManager.setLabel (names[i][0], label); + } + } +} + diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp new file mode 100644 index 000000000..c74495795 --- /dev/null +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -0,0 +1,30 @@ +#ifndef GAME_MWMECHANICS_PTR_H +#define GAME_MWMECHANICS_PTR_H + +namespace ESMS +{ + class ESMStore; +} + +namespace MWGui +{ + class WindowManager; +} + +namespace MWMechanics +{ + class MechanicsManager + { + const ESMS::ESMStore& mStore; + MWGui::WindowManager& mWindowManager; + + public: + + MechanicsManager (const ESMS::ESMStore& store, MWGui::WindowManager& windowManager); + + void configureGUI(); + }; +} + +#endif + diff --git a/apps/openmw/mwworld/environment.hpp b/apps/openmw/mwworld/environment.hpp index ab0989d49..0c6476d52 100644 --- a/apps/openmw/mwworld/environment.hpp +++ b/apps/openmw/mwworld/environment.hpp @@ -16,6 +16,11 @@ namespace MWGui class WindowManager; } +namespace MWMechanics +{ + class MechanicsManager; +} + namespace MWWorld { class World; @@ -25,13 +30,15 @@ namespace MWWorld { public: Environment() - : mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0), mFrameDuration (0) + : mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0), + mMechanicsManager (0), mFrameDuration (0) {} World *mWorld; MWSound::SoundManager *mSoundManager; MWScript::GlobalScripts *mGlobalScripts; MWGui::WindowManager *mWindowManager; + MWMechanics::MechanicsManager *mMechanicsManager; float mFrameDuration; }; } diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 83181b687..ba099da94 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -75,6 +75,15 @@ namespace ESMS ref.load(esm); } + // Find the given object ID, or return NULL if not found. + const X* find(const std::string &id) const + { + std::string id2 = toLower (id); + if(list.find(id2) == list.end()) + return NULL; + return &list.find(id2)->second; + } + int getSize() { return list.size(); } }; From f141fd093165b3140d4930b02cf9c0379fe3c648 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 26 Jul 2010 17:40:03 +0800 Subject: [PATCH 02/24] split reclists find function into find and search functions (search can be used to check if an object does not exist, while find would see this as an error situation and would throw an exception) --- components/esm_store/reclists.hpp | 40 ++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index ba099da94..5763dc6f9 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace ESMS { @@ -45,13 +46,24 @@ namespace ESMS } // Find the given object ID, or return NULL if not found. - const X* find(const std::string &id) const + const X* search(const std::string &id) const { std::string id2 = toLower (id); if(list.find(id2) == list.end()) return NULL; return &list.find(id2)->second; } + + // Find the given object ID (throws an exception if not found) + const X* find(const std::string &id) const + { + const X *object = search (id); + + if (!object) + throw std::runtime_error ("object " + id + " not found"); + + return object; + } int getSize() { return list.size(); } }; @@ -76,7 +88,7 @@ namespace ESMS } // Find the given object ID, or return NULL if not found. - const X* find(const std::string &id) const + const X* search(const std::string &id) const { std::string id2 = toLower (id); if(list.find(id2) == list.end()) @@ -84,6 +96,17 @@ namespace ESMS return &list.find(id2)->second; } + // Find the given object ID (throws an exception if not found) + const X* find(const std::string &id) const + { + const X *object = search (id); + + if (!object) + throw std::runtime_error ("object " + id + " not found"); + + return object; + } + int getSize() { return list.size(); } }; @@ -177,7 +200,7 @@ namespace ESMS } // Find the given object ID, or return NULL if not found. - const X* find(const std::string &id) const + const X* search(const std::string &id) const { std::string id2 = toLower (id); if(list.find(id2) == list.end()) @@ -185,6 +208,17 @@ namespace ESMS return &list.find(id2)->second; } + // Find the given object ID (throws an exception if not found) + const X* find(const std::string &id) const + { + const X *object = search (id); + + if (!object) + throw std::runtime_error ("object " + id + " not found"); + + return object; + } + int getSize() { return list.size(); } }; From 6159feb0da5cc83d30f82f5334f584042eddb203 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 26 Jul 2010 17:58:49 +0800 Subject: [PATCH 03/24] fixed an include guard --- apps/openmw/mwmechanics/mechanicsmanager.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index c74495795..2ffc580aa 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -1,5 +1,5 @@ -#ifndef GAME_MWMECHANICS_PTR_H -#define GAME_MWMECHANICS_PTR_H +#ifndef GAME_MWMECHANICS_MECHANICSMANAGER_H +#define GAME_MWMECHANICS_MECHANICSMANAGER_H namespace ESMS { From d54cd377cd187a6547ba18a5b53dc0c9ca4bcf4f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 26 Jul 2010 18:52:32 +0800 Subject: [PATCH 04/24] added first set of character and creature stats (attributes) --- apps/openmw/CMakeLists.txt | 5 ++- apps/openmw/mwmechanics/creaturestats.hpp | 15 +++++++ apps/openmw/mwmechanics/stat.hpp | 49 +++++++++++++++++++++ apps/openmw/mwworld/ptr.hpp | 53 ++++++++++++++++++++++- apps/openmw/mwworld/refdata.hpp | 18 ++++++++ 5 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 apps/openmw/mwmechanics/creaturestats.hpp create mode 100644 apps/openmw/mwmechanics/stat.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 83960d64a..3464a2c33 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -90,7 +90,10 @@ source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER}) set(GAMEMECHANICS mwmechanics/mechanicsmanager.cpp) set(GAMEMECHANICS_HEADER - mwmechanics/mechanicsmanager.hpp) + mwmechanics/mechanicsmanager.hpp + mwmechanics/stat.hpp + mwmechanics/creaturestats.hpp + ) source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER}) set(OPENMW_CPP ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT} ${GAMESOUND} ${GAMEGUI} ${GAMEWORLD} diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp new file mode 100644 index 000000000..f8aaa3caf --- /dev/null +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -0,0 +1,15 @@ +#ifndef GAME_MWMECHANICS_CREATURESTATS_H +#define GAME_MWMECHANICS_CREATURESTATS_H + +#include "stat.hpp" + +namespace MWMechanics +{ + struct CreatureStats + { + Stat mAttributes[8]; + }; +} + +#endif + diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp new file mode 100644 index 000000000..eb0e35bd9 --- /dev/null +++ b/apps/openmw/mwmechanics/stat.hpp @@ -0,0 +1,49 @@ +#ifndef GAME_MWMECHANICS_STAT_H +#define GAME_MWMECHANICS_STAT_H + +namespace MWMechanics +{ + template + class Stat + { + T mBase; + T mModified; + + public: + + Stat() : mBase (0), mModified (0) {} + + const T& getBase() const + { + return mBase; + } + + const T& getModified() const + { + return mModified; + } + + /// Set base and modified to \a value. + void set (const T& value) + { + mBase = mModified = value; + } + + /// Set base and adjust modified accordingly. + void setBase (const T& value) + { + T diff = value - mBase; + mBase = value; + mModified += diff; + } + + /// Change modified relatively. + void modify (const T& diff) + { + mModified += diff; + } + }; +} + +#endif + diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index a65fcb7cc..5f8c938a3 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -5,8 +5,12 @@ #include +#include +#include #include +#include "../mwmechanics/creaturestats.hpp" + #include "refdata.hpp" namespace MWWorld @@ -45,7 +49,7 @@ namespace MWWorld template ESMS::LiveCellRef *get() const { - return boost::any_cast*> (mPtr); + return boost::any_cast*> (mPtr); } ESM::CellRef& getCellRef() const @@ -65,6 +69,53 @@ namespace MWWorld assert (mCell); return mCell; } + + /// Throws an exception, if the ID type does not support creature stats. + MWMechanics::CreatureStats& getCreatureStats() const + { + RefData& data = getRefData(); + + if (!data.getCreatureStats().get()) + { + if (mPtr.type()==typeid (ESMS::LiveCellRef *)) + { + boost::shared_ptr stats; + data.getCreatureStats() = stats; + + ESMS::LiveCellRef *ref = get(); + + stats->mAttributes[0].set (ref->base->data.strength); + stats->mAttributes[1].set (ref->base->data.intelligence); + stats->mAttributes[2].set (ref->base->data.willpower); + stats->mAttributes[3].set (ref->base->data.agility); + stats->mAttributes[4].set (ref->base->data.speed); + stats->mAttributes[5].set (ref->base->data.endurance); + stats->mAttributes[6].set (ref->base->data.personality); + stats->mAttributes[7].set (ref->base->data.luck); + } + else if (mPtr.type()==typeid (ESMS::LiveCellRef *)) + { + boost::shared_ptr stats; + data.getCreatureStats() = stats; + + ESMS::LiveCellRef *ref = get(); + + stats->mAttributes[0].set (ref->base->npdt52.strength); + stats->mAttributes[1].set (ref->base->npdt52.intelligence); + stats->mAttributes[2].set (ref->base->npdt52.willpower); + stats->mAttributes[3].set (ref->base->npdt52.agility); + stats->mAttributes[4].set (ref->base->npdt52.speed); + stats->mAttributes[5].set (ref->base->npdt52.endurance); + stats->mAttributes[6].set (ref->base->npdt52.personality); + stats->mAttributes[7].set (ref->base->npdt52.luck); + } + else + throw std::runtime_error ( + "CreatureStats not available for this ID type"); + } + + return *data.getCreatureStats(); + } }; } diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 58c169c0e..919f4f8a0 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -3,6 +3,8 @@ #include +#include + #include "../mwscript/locals.hpp" namespace ESM @@ -10,6 +12,11 @@ namespace ESM class Script; } +namespace MWMechanics +{ + struct CreatureStats; +} + namespace MWWorld { class RefData @@ -21,6 +28,12 @@ namespace MWWorld // we can make this a pointer later. bool mHasLocals; bool mEnabled; + + // we are using shared pointer here to avoid having to create custom copy-constructor, + // assignment operator and destructor. As a consequence though copying a RefData object + // manually will probably give unexcepted results. This is not a problem since RefData + // are never copied outside of container operations. + boost::shared_ptr mCreatureStats; public: @@ -64,6 +77,11 @@ namespace MWWorld { mEnabled = true; } + + boost::shared_ptr& getCreatureStats() + { + return mCreatureStats; + } }; } From e7abbbedda6d7a070c5cc26afd92e4dec965d528 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 26 Jul 2010 18:59:50 +0800 Subject: [PATCH 05/24] added a CellStore pointer to PlayerPos --- apps/openmw/mwrender/playerpos.hpp | 9 ++++++++- apps/openmw/mwworld/world.cpp | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/playerpos.hpp b/apps/openmw/mwrender/playerpos.hpp index 0eed8b7b4..3501850b6 100644 --- a/apps/openmw/mwrender/playerpos.hpp +++ b/apps/openmw/mwrender/playerpos.hpp @@ -6,6 +6,7 @@ #include #include "../mwworld/refdata.hpp" +#include "../mwworld/ptr.hpp" namespace MWRender { @@ -15,11 +16,12 @@ namespace MWRender class PlayerPos { ESMS::LiveCellRef mPlayer; + MWWorld::Ptr::CellStore *mCellStore; Ogre::Camera *camera; public: PlayerPos(Ogre::Camera *cam, const ESM::NPC *player) : - camera(cam) + mCellStore (0), camera(cam) { mPlayer.base = player; mPlayer.ref.pos.pos[0] = mPlayer.ref.pos.pos[1] = mPlayer.ref.pos.pos[2] = 0; @@ -40,6 +42,11 @@ namespace MWRender // TODO: Update sound listener } + + void setCell (MWWorld::Ptr::CellStore *cellStore) + { + mCellStore = cellStore; + } Ogre::Camera *getCamera() { return camera; } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 944d18f87..f2b8aa7e9 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -183,6 +183,7 @@ namespace MWWorld insertInteriorScripts (mInteriors[startCell]); mPlayerPos = new MWRender::PlayerPos (mScene.getCamera(), mStore.npcs.find ("player")); + mPlayerPos->setCell (&mInteriors[startCell]); // global variables mGlobalVariables = new Globals (mStore); @@ -444,6 +445,7 @@ namespace MWWorld insertInteriorScripts (mInteriors[cellName]); mPlayerPos->setPos (position.pos[0], position.pos[1], position.pos[2]); + mPlayerPos->setCell (&mInteriors[cellName]); // TODO orientation // This connects the cell data with the rendering scene. From d4f21fccdd6feb008abe99e7b296e62c9bff59de Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 26 Jul 2010 19:09:44 +0800 Subject: [PATCH 06/24] changed PlayerPos::getPlayer return type from CellRef to Ptr --- apps/openmw/mwrender/playerpos.hpp | 10 +++------- apps/openmw/mwworld/world.cpp | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwrender/playerpos.hpp b/apps/openmw/mwrender/playerpos.hpp index 3501850b6..48a4fd8d5 100644 --- a/apps/openmw/mwrender/playerpos.hpp +++ b/apps/openmw/mwrender/playerpos.hpp @@ -76,15 +76,11 @@ namespace MWRender setPos(relX, relY, relZ); } - ESMS::LiveCellRef *getPlayer() + MWWorld::Ptr getPlayer() { - return &mPlayer; + MWWorld::Ptr ptr (&mPlayer, mCellStore); + return ptr; } - - const ESMS::LiveCellRef *getPlayer() const - { - return &mPlayer; - } }; } #endif diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index f2b8aa7e9..d71276fe9 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -259,7 +259,7 @@ namespace MWWorld // the player is always in an active cell. if (name=="player") { - return Ptr (mPlayerPos->getPlayer(), mCurrentCell); + return mPlayerPos->getPlayer(); } // active cells From 25e720cf653e73e9b665fd227ae7b13f57992196 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 27 Jul 2010 04:00:50 +0800 Subject: [PATCH 07/24] fixed a reclist bug induced a couple of commits ago --- apps/openmw/mwscript/compilercontext.cpp | 40 ++++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwscript/compilercontext.cpp b/apps/openmw/mwscript/compilercontext.cpp index de00353ca..15cc599a7 100644 --- a/apps/openmw/mwscript/compilercontext.cpp +++ b/apps/openmw/mwscript/compilercontext.cpp @@ -23,26 +23,26 @@ namespace MWScript bool CompilerContext::isId (const std::string& name) const { return - mEnvironment.mWorld->getStore().activators.find (name) || - mEnvironment.mWorld->getStore().potions.find (name) || - mEnvironment.mWorld->getStore().appas.find (name) || - mEnvironment.mWorld->getStore().armors.find (name) || - mEnvironment.mWorld->getStore().books.find (name) || - mEnvironment.mWorld->getStore().clothes.find (name) || - mEnvironment.mWorld->getStore().containers.find (name) || - mEnvironment.mWorld->getStore().creatures.find (name) || - mEnvironment.mWorld->getStore().doors.find (name) || - mEnvironment.mWorld->getStore().ingreds.find (name) || - mEnvironment.mWorld->getStore().creatureLists.find (name) || - mEnvironment.mWorld->getStore().itemLists.find (name) || - mEnvironment.mWorld->getStore().lights.find (name) || - mEnvironment.mWorld->getStore().lockpicks.find (name) || - mEnvironment.mWorld->getStore().miscItems.find (name) || - mEnvironment.mWorld->getStore().npcs.find (name) || - mEnvironment.mWorld->getStore().probes.find (name) || - mEnvironment.mWorld->getStore().repairs.find (name) || - mEnvironment.mWorld->getStore().statics.find (name) || - mEnvironment.mWorld->getStore().weapons.find (name); + mEnvironment.mWorld->getStore().activators.search (name) || + mEnvironment.mWorld->getStore().potions.search (name) || + mEnvironment.mWorld->getStore().appas.search (name) || + mEnvironment.mWorld->getStore().armors.search (name) || + mEnvironment.mWorld->getStore().books.search (name) || + mEnvironment.mWorld->getStore().clothes.search (name) || + mEnvironment.mWorld->getStore().containers.search (name) || + mEnvironment.mWorld->getStore().creatures.search (name) || + mEnvironment.mWorld->getStore().doors.search (name) || + mEnvironment.mWorld->getStore().ingreds.search (name) || + mEnvironment.mWorld->getStore().creatureLists.search (name) || + mEnvironment.mWorld->getStore().itemLists.search (name) || + mEnvironment.mWorld->getStore().lights.search (name) || + mEnvironment.mWorld->getStore().lockpicks.search (name) || + mEnvironment.mWorld->getStore().miscItems.search (name) || + mEnvironment.mWorld->getStore().npcs.search (name) || + mEnvironment.mWorld->getStore().probes.search (name) || + mEnvironment.mWorld->getStore().repairs.search (name) || + mEnvironment.mWorld->getStore().statics.search (name) || + mEnvironment.mWorld->getStore().weapons.search (name); } } From 3f8c8c33f553836efaae8800f3308fcb191dc1ef Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 27 Jul 2010 05:09:37 +0800 Subject: [PATCH 08/24] added get-, set- and mod-instructions for attributes --- apps/openmw/CMakeLists.txt | 2 + apps/openmw/mwmechanics/stat.hpp | 22 ++ apps/openmw/mwscript/docs/vmformat.txt | 8 +- apps/openmw/mwscript/extensions.cpp | 3 + apps/openmw/mwscript/interpretercontext.cpp | 2 +- apps/openmw/mwscript/statsextensions.cpp | 211 ++++++++++++++++++++ apps/openmw/mwscript/statsextensions.hpp | 25 +++ apps/openmw/mwworld/ptr.hpp | 12 +- 8 files changed, 279 insertions(+), 6 deletions(-) create mode 100644 apps/openmw/mwscript/statsextensions.cpp create mode 100644 apps/openmw/mwscript/statsextensions.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 3464a2c33..260ebcd70 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -50,6 +50,7 @@ set(GAMESCRIPT mwscript/guiextensions.cpp mwscript/soundextensions.cpp mwscript/skyextensions.cpp + mwscript/statsextensions.cpp mwscript/extensions.cpp mwscript/globalscripts.cpp ) @@ -63,6 +64,7 @@ set(GAMESCRIPT_HEADER mwscript/guiextensions.hpp mwscript/soundextensions.hpp mwscript/skyextensions.hpp + mwscript/statsextensions.hpp mwscript/extensions.hpp mwscript/globalscripts.hpp ) diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index eb0e35bd9..e13c0aff2 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -1,6 +1,8 @@ #ifndef GAME_MWMECHANICS_STAT_H #define GAME_MWMECHANICS_STAT_H +#include + namespace MWMechanics { template @@ -37,6 +39,26 @@ namespace MWMechanics mModified += diff; } + /// Set modified value an adjust base accordingly. + void setModified (T value, const T& min, const T& max = std::numeric_limits::max()) + { + T diff = value - mModified; + + if (mBase+diffmax-diff) + { + value = max + (mModified - mBase); + diff = value - mModified; + } + + mModified = value; + mBase += diff; + } + /// Change modified relatively. void modify (const T& diff) { diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 6d78065b3..55b34f32d 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -60,5 +60,11 @@ op 0x2000023: TurnMoonRed op 0x2000024: GetMasserPhase op 0x2000025: GetSecundaPhase op 0x2000026: COC -opcodes 0x2000027-0x3ffffff unused +op 0x2000027-0x200002e: GetAttribute +op 0x200002f-0x2000036: GetAttribute, explicit reference +op 0x2000037-0x200003e: SetAttribute +op 0x200003f-0x2000046: SetAttribute, explicit reference +op 0x2000047-0x200004e: ModAttribute +op 0x200004f-0x2000056: ModAttribute, explicit reference +opcodes 0x2000057-0x3ffffff unused diff --git a/apps/openmw/mwscript/extensions.cpp b/apps/openmw/mwscript/extensions.cpp index 94f553b58..3abaac58c 100644 --- a/apps/openmw/mwscript/extensions.cpp +++ b/apps/openmw/mwscript/extensions.cpp @@ -9,6 +9,7 @@ #include "miscextensions.hpp" #include "guiextensions.hpp" #include "skyextensions.hpp" +#include "statsextensions.hpp" namespace MWScript { @@ -19,6 +20,7 @@ namespace MWScript Gui::registerExtensions (extensions); Sound::registerExtensions (extensions); Sky::registerExtensions (extensions); + Stats::registerExtensions (extensions); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -29,6 +31,7 @@ namespace MWScript Gui::installOpcodes (interpreter); Sound::installOpcodes (interpreter); Sky::installOpcodes (interpreter); + Stats::installOpcodes (interpreter); } } diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index cc9d5f33b..f2dc57dd0 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -242,7 +242,7 @@ namespace MWScript MWWorld::Ptr InterpreterContext::getReference() { - return mReference; + return getReference ("", true); } } diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp new file mode 100644 index 000000000..fd1f5eda6 --- /dev/null +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -0,0 +1,211 @@ + +#include "statsextensions.hpp" + +#include + +#include +#include +#include + +#include "interpretercontext.hpp" + +namespace MWScript +{ + namespace Stats + { + class OpGetAttribute : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpGetAttribute (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + Interpreter::Type_Integer value = + context.getReference().getCreatureStats().mAttributes[mIndex]. + getModified(); + + runtime.push (value); + } + }; + + class OpGetAttributeExplicit : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpGetAttributeExplicit (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer value = + context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. + getModified(); + + runtime.push (value); + } + }; + + class OpSetAttribute : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpSetAttribute (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + context.getReference().getCreatureStats().mAttributes[mIndex]. + setModified (value, 0); + } + }; + + class OpSetAttributeExplicit : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpSetAttributeExplicit (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. + setModified (value, 0); + } + }; + + class OpModAttribute : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpModAttribute (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + value += context.getReference().getCreatureStats().mAttributes[mIndex]. + getModified(); + + context.getReference().getCreatureStats().mAttributes[mIndex]. + setModified (value, 0, 100); + } + }; + + class OpModAttributeExplicit : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpModAttributeExplicit (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + value += + context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. + getModified(); + + context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. + setModified (value, 0, 100); + } + }; + + const int numberOfAttributes = 8; + + const int opcodeGetAttribute = 0x2000027; + const int opcodeGetAttributeExplicit = 0x200002f; + const int opcodeSetAttribute = 0x2000037; + const int opcodeSetAttributeExplicit = 0x200003f; + const int opcodeModAttribute = 0x2000047; + const int opcodeModAttributeExplicit = 0x200004f; + + void registerExtensions (Compiler::Extensions& extensions) + { + static const char *attributes[numberOfAttributes] = + { + "strength", "intelligence", "willpower", "agility", "speed", "endurance", + "personality", "luck" + }; + + std::string get ("get"); + std::string set ("set"); + std::string mod ("mod"); + + for (int i=0; i *)) { - boost::shared_ptr stats; - data.getCreatureStats() = stats; + boost::shared_ptr stats ( + new MWMechanics::CreatureStats); ESMS::LiveCellRef *ref = get(); @@ -92,11 +92,13 @@ namespace MWWorld stats->mAttributes[5].set (ref->base->data.endurance); stats->mAttributes[6].set (ref->base->data.personality); stats->mAttributes[7].set (ref->base->data.luck); + + data.getCreatureStats() = stats; } else if (mPtr.type()==typeid (ESMS::LiveCellRef *)) { - boost::shared_ptr stats; - data.getCreatureStats() = stats; + boost::shared_ptr stats ( + new MWMechanics::CreatureStats); ESMS::LiveCellRef *ref = get(); @@ -108,6 +110,8 @@ namespace MWWorld stats->mAttributes[5].set (ref->base->npdt52.endurance); stats->mAttributes[6].set (ref->base->npdt52.personality); stats->mAttributes[7].set (ref->base->npdt52.luck); + + data.getCreatureStats() = stats; } else throw std::runtime_error ( From 0ff742fb6c875682fd2eb7f6e35f7228dc1cb7a0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 27 Jul 2010 18:04:52 +0800 Subject: [PATCH 09/24] added comparison operators for Ptr class --- apps/openmw/mwworld/ptr.hpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index 44e480ab8..778a66b67 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -121,6 +121,36 @@ namespace MWWorld return *data.getCreatureStats(); } }; + + inline bool operator== (const Ptr& left, const Ptr& right) + { + return left.mRefData==right.mRefData; + } + + inline bool operator!= (const Ptr& left, const Ptr& right) + { + return !(left==right); + } + + inline bool operator< (const Ptr& left, const Ptr& right) + { + return left.mRefData= (const Ptr& left, const Ptr& right) + { + return !(left (const Ptr& left, const Ptr& right) + { + return rightright); + } } #endif From 858f174355f29bb777a53d1f237b4328bc09ee7f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 27 Jul 2010 19:09:35 +0800 Subject: [PATCH 10/24] removed duplicate code from World class --- apps/openmw/engine.cpp | 8 +++++++- apps/openmw/mwworld/world.cpp | 19 +------------------ apps/openmw/mwworld/world.hpp | 2 +- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 374ca41a1..e7e682e31 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -187,7 +187,7 @@ void OMW::Engine::go() loadBSA(); // Create the world - mEnvironment.mWorld = new MWWorld::World (mOgre, mDataDir, mMaster, mCellName, mNewGame); + mEnvironment.mWorld = new MWWorld::World (mOgre, mDataDir, mMaster, mNewGame); // Set up the GUI system mGuiManager = new OEngine::GUI::MyGUIManager(mOgre.getWindow(), @@ -219,6 +219,12 @@ void OMW::Engine::go() mEnvironment.mMechanicsManager->configureGUI(); + // load cell + ESM::Position pos; + pos.pos[0] = pos.pos[1] = pos.pos[2] = 0; + pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; + mEnvironment.mWorld->changeCell (mCellName, pos); + // Sets up the input system MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayerPos(), *mEnvironment.mWindowManager, mDebug); diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index d71276fe9..3c2ea3256 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -164,7 +164,7 @@ namespace MWWorld } World::World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir, - const std::string& master, const std::string& startCell, bool newGame) + const std::string& master, bool newGame) : mSkyManager (0), mScene (renderer), mPlayerPos (0), mCurrentCell (0), mGlobalVariables (0), mSky (false), mCellChanged (false) { @@ -177,13 +177,7 @@ namespace MWWorld mEsm.open (masterPath.file_string()); mStore.load (mEsm); - mInteriors[startCell].loadInt (startCell, mStore, mEsm); - mCurrentCell = &mInteriors[startCell]; - - insertInteriorScripts (mInteriors[startCell]); - mPlayerPos = new MWRender::PlayerPos (mScene.getCamera(), mStore.npcs.find ("player")); - mPlayerPos->setCell (&mInteriors[startCell]); // global variables mGlobalVariables = new Globals (mStore); @@ -194,19 +188,8 @@ namespace MWWorld mGlobalVariables->setInt ("chargenstate", 1); } - // This connects the cell data with the rendering scene. - mActiveCells.insert (std::make_pair (&mInteriors[startCell], - new MWRender::InteriorCellRender (mInteriors[startCell], mScene))); - - // Load the cell and insert it into the renderer - for (CellRenderCollection::iterator iter (mActiveCells.begin()); - iter!=mActiveCells.end(); ++iter) - iter->second->show(); - mSkyManager = MWRender::SkyManager::create(renderer.getWindow(), mScene.getCamera()); - - toggleSky(); } World::~World() diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index abb17a6ee..d1cf2de31 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -74,7 +74,7 @@ namespace MWWorld public: World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& master, - const std::string& dataDir, const std::string& startCell, bool newGame); + const std::string& dataDir, bool newGame); ~World(); From 362605860b13a57da86375e71271d96376797cf5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 27 Jul 2010 20:05:05 +0800 Subject: [PATCH 11/24] register actors in active cells with MechanicsManager --- apps/openmw/engine.cpp | 2 +- apps/openmw/mwmechanics/mechanicsmanager.cpp | 18 ++++++++ apps/openmw/mwmechanics/mechanicsmanager.hpp | 15 ++++++- apps/openmw/mwworld/world.cpp | 45 ++++++++++++++++---- apps/openmw/mwworld/world.hpp | 5 ++- 5 files changed, 72 insertions(+), 13 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index e7e682e31..d515fcac1 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -187,7 +187,7 @@ void OMW::Engine::go() loadBSA(); // Create the world - mEnvironment.mWorld = new MWWorld::World (mOgre, mDataDir, mMaster, mNewGame); + mEnvironment.mWorld = new MWWorld::World (mOgre, mDataDir, mMaster, mNewGame, mEnvironment); // Set up the GUI system mGuiManager = new OEngine::GUI::MyGUIManager(mOgre.getWindow(), diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 2d28b03ac..4287c6a64 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -39,5 +39,23 @@ namespace MWMechanics mWindowManager.setLabel (names[i][0], label); } } + + void MechanicsManager::addActor (const MWWorld::Ptr& ptr) + { + mActors.insert (ptr); + } + + void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore) + { + std::set::iterator iter = mActors.begin(); + + while (iter!=mActors.end()) + if (iter->getCell()==cellStore) + { + mActors.erase (iter++); + } + else + ++iter; + } } diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index 2ffc580aa..0a46a8f26 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -1,6 +1,10 @@ #ifndef GAME_MWMECHANICS_MECHANICSMANAGER_H #define GAME_MWMECHANICS_MECHANICSMANAGER_H +#include + +#include "../mwworld/ptr.hpp" + namespace ESMS { class ESMStore; @@ -15,14 +19,21 @@ namespace MWMechanics { class MechanicsManager { - const ESMS::ESMStore& mStore; - MWGui::WindowManager& mWindowManager; + const ESMS::ESMStore& mStore; + MWGui::WindowManager& mWindowManager; + std::set mActors; public: MechanicsManager (const ESMS::ESMStore& store, MWGui::WindowManager& windowManager); void configureGUI(); + + void addActor (const MWWorld::Ptr& ptr); + ///< Register an actor for stats management + + void dropActors (const MWWorld::Ptr::CellStore *cellStore); + ///< Deregister all actors in the given cell. }; } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 3c2ea3256..a3f82417c 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -4,12 +4,15 @@ #include #include -#include "components/bsa/bsa_archive.hpp" +#include -#include "apps/openmw/mwrender/sky.hpp" -#include "apps/openmw/mwrender/interior.hpp" +#include "../mwrender/sky.hpp" +#include "../mwrender/interior.hpp" + +#include "../mwmechanics/mechanicsmanager.hpp" #include "ptr.hpp" +#include "environment.hpp" namespace { @@ -164,9 +167,9 @@ namespace MWWorld } World::World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir, - const std::string& master, bool newGame) + const std::string& master, bool newGame, Environment& environment) : mSkyManager (0), mScene (renderer), mPlayerPos (0), mCurrentCell (0), mGlobalVariables (0), - mSky (false), mCellChanged (false) + mSky (false), mCellChanged (false), mEnvironment (environment) { boost::filesystem::path masterPath (dataDir); masterPath /= master; @@ -413,35 +416,59 @@ namespace MWWorld { // Load cell. mInteriors[cellName].loadInt (cellName, mStore, mEsm); + Ptr::CellStore *cell = &mInteriors[cellName]; // remove active CellRenderCollection::iterator active = mActiveCells.begin(); if (active!=mActiveCells.end()) { + mEnvironment.mMechanicsManager->dropActors (active->first); active->second->destroy(); delete active->second; mActiveCells.erase (active); } + // register local scripts mLocalScripts.clear(); // FIXME won't work with exteriors - insertInteriorScripts (mInteriors[cellName]); + insertInteriorScripts (*cell); + // adjust player mPlayerPos->setPos (position.pos[0], position.pos[1], position.pos[2]); - mPlayerPos->setCell (&mInteriors[cellName]); + mPlayerPos->setCell (cell); // TODO orientation // This connects the cell data with the rendering scene. std::pair result = - mActiveCells.insert (std::make_pair (&mInteriors[cellName], - new MWRender::InteriorCellRender (mInteriors[cellName], mScene))); + mActiveCells.insert (std::make_pair (cell, + new MWRender::InteriorCellRender (*cell, mScene))); if (result.second) { // Load the cell and insert it into the renderer result.first->second->show(); } + + // Actors + mEnvironment.mMechanicsManager->addActor (mPlayerPos->getPlayer()); + for (ESMS::CellRefList::List::iterator iter ( + cell->creatures.list.begin()); + iter!=cell->creatures.list.end(); ++iter) + { + Ptr ptr (&*iter, cell); + mEnvironment.mMechanicsManager->addActor (ptr); + } + + for (ESMS::CellRefList::List::iterator iter ( + cell->npcs.list.begin()); + iter!=cell->npcs.list.end(); ++iter) + { + Ptr ptr (&*iter, cell); + mEnvironment.mMechanicsManager->addActor (ptr); + } + + // Sky system if (mSky) { toggleSky(); diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index d1cf2de31..953fe93e4 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -33,6 +33,8 @@ namespace MWRender namespace MWWorld { + class Environment; + /// \brief The game world and its visual representation class World @@ -58,6 +60,7 @@ namespace MWWorld MWWorld::Globals *mGlobalVariables; bool mSky; bool mCellChanged; + Environment& mEnvironment; // not implemented World (const World&); @@ -74,7 +77,7 @@ namespace MWWorld public: World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& master, - const std::string& dataDir, bool newGame); + const std::string& dataDir, bool newGame, Environment& environment); ~World(); From fef6fc134019a8a58c41f7170b73cfbf39c155fc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 27 Jul 2010 20:43:46 +0800 Subject: [PATCH 12/24] implemented handling of disabled actors --- apps/openmw/mwmechanics/mechanicsmanager.cpp | 5 ++++ apps/openmw/mwmechanics/mechanicsmanager.hpp | 5 +++- apps/openmw/mwworld/ptr.hpp | 6 +++++ apps/openmw/mwworld/world.cpp | 28 +++++++++++++++++--- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 4287c6a64..ad40d2e0c 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -45,6 +45,11 @@ namespace MWMechanics mActors.insert (ptr); } + void MechanicsManager::removeActor (const MWWorld::Ptr& ptr) + { + mActors.erase (ptr); + } + void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore) { std::set::iterator iter = mActors.begin(); diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index 0a46a8f26..e0c44b93e 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -31,7 +31,10 @@ namespace MWMechanics void addActor (const MWWorld::Ptr& ptr); ///< Register an actor for stats management - + + void removeActor (const MWWorld::Ptr& ptr); + ///< Deregister an actor for stats management + void dropActors (const MWWorld::Ptr::CellStore *cellStore); ///< Deregister all actors in the given cell. }; diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index 778a66b67..0c4e76f22 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -37,6 +37,12 @@ namespace MWWorld return mPtr.empty(); } + const std::type_info& getType() + { + assert (!mPtr.empty()); + return mPtr.type(); + } + template Ptr (ESMS::LiveCellRef *liveCellRef, CellStore *cell) { diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index a3f82417c..e450cc513 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -275,6 +275,13 @@ namespace MWWorld if (MWRender::CellRender *render = searchRender (reference.getCell())) { render->enable (reference.getRefData().getHandle()); + + if (mActiveCells.find (reference.getCell())!=mActiveCells.end() && + (reference.getType()==typeid (ESMS::LiveCellRef) || + reference.getType()==typeid (ESMS::LiveCellRef))) + { + mEnvironment.mMechanicsManager->addActor (reference); + } } } } @@ -288,6 +295,13 @@ namespace MWWorld if (MWRender::CellRender *render = searchRender (reference.getCell())) { render->disable (reference.getRefData().getHandle()); + + if (mActiveCells.find (reference.getCell())!=mActiveCells.end() && + (reference.getType()==typeid (ESMS::LiveCellRef) || + reference.getType()==typeid (ESMS::LiveCellRef))) + { + mEnvironment.mMechanicsManager->removeActor (reference); + } } } } @@ -456,16 +470,22 @@ namespace MWWorld cell->creatures.list.begin()); iter!=cell->creatures.list.end(); ++iter) { - Ptr ptr (&*iter, cell); - mEnvironment.mMechanicsManager->addActor (ptr); + if (iter->mData.isEnabled()) + { + Ptr ptr (&*iter, cell); + mEnvironment.mMechanicsManager->addActor (ptr); + } } for (ESMS::CellRefList::List::iterator iter ( cell->npcs.list.begin()); iter!=cell->npcs.list.end(); ++iter) { - Ptr ptr (&*iter, cell); - mEnvironment.mMechanicsManager->addActor (ptr); + if (iter->mData.isEnabled()) + { + Ptr ptr (&*iter, cell); + mEnvironment.mMechanicsManager->addActor (ptr); + } } // Sky system From 0383ad550a27b50aea081e39d6d12fdd73851580 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 27 Jul 2010 20:46:05 +0800 Subject: [PATCH 13/24] added MechanicsManager::update function (doesn't update anything yet) --- apps/openmw/engine.cpp | 3 +++ apps/openmw/mwmechanics/mechanicsmanager.cpp | 5 +++++ apps/openmw/mwmechanics/mechanicsmanager.hpp | 3 +++ 3 files changed, 11 insertions(+) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index d515fcac1..93dd4c8b6 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -64,6 +64,9 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) if (changed) // keep change flag for another frame, if cell changed happend in local script mEnvironment.mWorld->markCellAsUnchanged(); + + // update actors + mEnvironment.mMechanicsManager->update(); return true; } diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index ad40d2e0c..96f82c287 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -62,5 +62,10 @@ namespace MWMechanics else ++iter; } + + void MechanicsManager::update() + { + + } } diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index e0c44b93e..af01a2e2e 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -37,6 +37,9 @@ namespace MWMechanics void dropActors (const MWWorld::Ptr::CellStore *cellStore); ///< Deregister all actors in the given cell. + + void update(); + ///< Update actor stats }; } From 089a38568631cf43ccd935d7ee1a3d1a3f975eb6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 27 Jul 2010 21:59:41 +0800 Subject: [PATCH 14/24] update attribute values in stats window --- apps/openmw/mwgui/mw_layouts.hpp | 29 ++++++++++++++++++++ apps/openmw/mwgui/window_manager.cpp | 5 ++++ apps/openmw/mwgui/window_manager.hpp | 5 ++++ apps/openmw/mwmechanics/mechanicsmanager.cpp | 26 +++++++++++++++++- apps/openmw/mwmechanics/mechanicsmanager.hpp | 8 ++++++ apps/openmw/mwmechanics/stat.hpp | 13 +++++++++ apps/openmw/mwworld/world.cpp | 1 + 7 files changed, 86 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/mw_layouts.hpp b/apps/openmw/mwgui/mw_layouts.hpp index 6df5ee391..fba2b411d 100644 --- a/apps/openmw/mwgui/mw_layouts.hpp +++ b/apps/openmw/mwgui/mw_layouts.hpp @@ -205,6 +205,35 @@ namespace MWGui break; } } + + /// Set value for the given ID. + void setValue (const std::string& id, const MWMechanics::Stat& value) + { + static const char *ids[] = + { + "AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5", + "AttribVal6", "AttribVal7", "AttribVal8", + 0 + }; + + for (int i=0; ids[i]; ++i) + if (ids[i]==id) + { + std::ostringstream valueString; + valueString << value.getModified(); + setText (id, valueString.str()); + + if (value.getModified()>value.getBase()) + setTextColor (id, 0, 1, 0); + else if (value.getModified()setLabel (id, label); } +void WindowManager::setValue (const std::string& id, const MWMechanics::Stat& value) +{ + stats->setValue (id, value); +} + diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index d576c10b2..007738fd1 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -12,6 +12,8 @@ #include +#include "../mwmechanics/stat.hpp" + namespace MyGUI { class Gui; @@ -139,6 +141,9 @@ namespace MWGui void setLabel (const std::string& id, const std::string& label); ///< Set label text for the value with the given ID. + + void setValue (const std::string& id, const MWMechanics::Stat& value); + ///< Set value for the given ID. }; } #endif diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 96f82c287..06a04e7f0 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -63,9 +63,33 @@ namespace MWMechanics ++iter; } + void MechanicsManager::watchActor (const MWWorld::Ptr& ptr) + { + mWatched = ptr; + } + void MechanicsManager::update() { - + if (!mWatched.isEmpty()) + { + MWMechanics::CreatureStats& stats = mWatched.getCreatureStats(); + + static const char *attributeNames[8] = + { + "AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5", + "AttribVal6", "AttribVal7", "AttribVal8" + }; + + for (int i=0; i<8; ++i) + { + if (stats.mAttributes[i]!=mWatchedCreature.mAttributes[i]) + { + mWatchedCreature.mAttributes[i] = stats.mAttributes[i]; + + mWindowManager.setValue (attributeNames[i], stats.mAttributes[i]); + } + } + } } } diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index af01a2e2e..ca4c1c47b 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -5,6 +5,8 @@ #include "../mwworld/ptr.hpp" +#include "creaturestats.hpp" + namespace ESMS { class ESMStore; @@ -22,6 +24,8 @@ namespace MWMechanics const ESMS::ESMStore& mStore; MWGui::WindowManager& mWindowManager; std::set mActors; + MWWorld::Ptr mWatched; + CreatureStats mWatchedCreature; public: @@ -38,6 +42,10 @@ namespace MWMechanics void dropActors (const MWWorld::Ptr::CellStore *cellStore); ///< Deregister all actors in the given cell. + void watchActor (const MWWorld::Ptr& ptr); + ///< On each update look for changes in a previously registered actor and update the + /// GUI accordingly. + void update(); ///< Update actor stats }; diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index e13c0aff2..139036628 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -65,6 +65,19 @@ namespace MWMechanics mModified += diff; } }; + + template + inline bool operator== (const Stat& left, const Stat& right) + { + return left.getBase()==right.getBase() && + left.getModified()==right.getModified(); + } + + template + inline bool operator!= (const Stat& left, const Stat& right) + { + return !(left==right); + } } #endif diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index e450cc513..55be70f1c 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -465,6 +465,7 @@ namespace MWWorld // Actors mEnvironment.mMechanicsManager->addActor (mPlayerPos->getPlayer()); + mEnvironment.mMechanicsManager->watchActor (mPlayerPos->getPlayer()); for (ESMS::CellRefList::List::iterator iter ( cell->creatures.list.begin()); From 9e9b014f1de3d5305d065d3359366e2d6311fd3e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 29 Jul 2010 00:27:46 +0800 Subject: [PATCH 15/24] added get, set and mod instructions for health, magicka and fatigue --- apps/openmw/mwmechanics/creaturestats.hpp | 1 + apps/openmw/mwmechanics/stat.hpp | 109 ++++++-- apps/openmw/mwscript/docs/vmformat.txt | 9 +- apps/openmw/mwscript/statsextensions.cpp | 301 ++++++++++++++++++---- apps/openmw/mwworld/ptr.hpp | 53 ++-- 5 files changed, 379 insertions(+), 94 deletions(-) diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index f8aaa3caf..ee3631c90 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -8,6 +8,7 @@ namespace MWMechanics struct CreatureStats { Stat mAttributes[8]; + DynamicStat mDynamic[3]; // health, magicka, fatigue }; } diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index 139036628..7d7c64527 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -10,27 +10,27 @@ namespace MWMechanics { T mBase; T mModified; - + public: - + Stat() : mBase (0), mModified (0) {} - + const T& getBase() const { return mBase; } - + const T& getModified() const { return mModified; } - + /// Set base and modified to \a value. void set (const T& value) { mBase = mModified = value; } - + /// Set base and adjust modified accordingly. void setBase (const T& value) { @@ -38,12 +38,12 @@ namespace MWMechanics mBase = value; mModified += diff; } - + /// Set modified value an adjust base accordingly. void setModified (T value, const T& min, const T& max = std::numeric_limits::max()) { T diff = value - mModified; - + if (mBase+diff inline bool operator== (const Stat& left, const Stat& right) { return left.getBase()==right.getBase() && - left.getModified()==right.getModified(); + left.getModified()==right.getModified(); } - + template inline bool operator!= (const Stat& left, const Stat& right) { return !(left==right); } + + template + class DynamicStat + { + Stat mStatic; + T mCurrent; + + public: + + const T& getBase() const + { + return mStatic.getBase(); + } + + const T& getModified() const + { + return mStatic.getModified(); + } + + const T& getCurrent() const + { + return mCurrent; + } + + /// Set base, modified and current to \a value. + void set (const T& value) + { + mStatic.set (value); + mCurrent = value; + } + + /// Set base and adjust modified accordingly. + void setBase (const T& value) + { + mStatic.setBase (value); + + if (mCurrent>getModified()) + mCurrent = getModified(); + } + + /// Set modified value an adjust base accordingly. + void setModified (T value, const T& min, const T& max = std::numeric_limits::max()) + { + mStatic.setModified (value, min, max); + + if (mCurrent>getModified()) + mCurrent = getModified(); + } + + /// Change modified relatively. + void modify (const T& diff) + { + mStatic.modify (diff); + modifyCurrent (diff); + } + + void setCurrent (const T& value) + { + mCurrent = value; + + if (mCurrent<0) + mCurrent = 0; + else if (mCurrent>getModified()) + mCurrent = getModified(); + } + }; + + template + inline bool operator== (const DynamicStat& left, const DynamicStat& right) + { + return left.getBase()==right.getBase() && + left.getModified()==right.getModified() && + left.getCurrent()==right.getCurrent(); + } + + template + inline bool operator!= (const DynamicStat& left, const DynamicStat& right) + { + return !(left==right); + } } #endif - diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 55b34f32d..205cdeeb1 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -66,5 +66,10 @@ op 0x2000037-0x200003e: SetAttribute op 0x200003f-0x2000046: SetAttribute, explicit reference op 0x2000047-0x200004e: ModAttribute op 0x200004f-0x2000056: ModAttribute, explicit reference -opcodes 0x2000057-0x3ffffff unused - +op 0x2000057-0x2000059: GetDynamic (health, magicka, fatigue) +op 0x200005a-0x200005c: GetDynamic (health, magicka, fatigue), explicit reference +op 0x200005d-0x200005f: SetDynamic (health, magicka, fatigue) +op 0x2000060-0x2000062: SetDynamic (health, magicka, fatigue), explicit reference +op 0x2000063-0x2000065: ModDynamic (health, magicka, fatigue) +op 0x2000066-0x2000068: ModDynamic (health, magicka, fatigue), explicit reference +opcodes 0x2000069-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index fd1f5eda6..3ff6c67ce 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -16,32 +16,32 @@ namespace MWScript class OpGetAttribute : public Interpreter::Opcode0 { int mIndex; - + public: - + OpGetAttribute (int index) : mIndex (index) {} - + virtual void execute (Interpreter::Runtime& runtime) { MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + Interpreter::Type_Integer value = context.getReference().getCreatureStats().mAttributes[mIndex]. getModified(); - + runtime.push (value); - } - }; + } + }; class OpGetAttributeExplicit : public Interpreter::Opcode0 { int mIndex; - + public: - + OpGetAttributeExplicit (int index) : mIndex (index) {} - + virtual void execute (Interpreter::Runtime& runtime) { MWScript::InterpreterContext& context @@ -49,44 +49,44 @@ namespace MWScript std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - + Interpreter::Type_Integer value = context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. getModified(); - - runtime.push (value); - } - }; - + + runtime.push (value); + } + }; + class OpSetAttribute : public Interpreter::Opcode0 { int mIndex; - + public: - + OpSetAttribute (int index) : mIndex (index) {} - + virtual void execute (Interpreter::Runtime& runtime) { MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - + context.getReference().getCreatureStats().mAttributes[mIndex]. setModified (value, 0); - } - }; + } + }; class OpSetAttributeExplicit : public Interpreter::Opcode0 { int mIndex; - + public: - + OpSetAttributeExplicit (int index) : mIndex (index) {} - + virtual void execute (Interpreter::Runtime& runtime) { MWScript::InterpreterContext& context @@ -100,41 +100,41 @@ namespace MWScript context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. setModified (value, 0); - } + } }; - + class OpModAttribute : public Interpreter::Opcode0 { int mIndex; - + public: - + OpModAttribute (int index) : mIndex (index) {} - + virtual void execute (Interpreter::Runtime& runtime) { MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - + value += context.getReference().getCreatureStats().mAttributes[mIndex]. getModified(); - + context.getReference().getCreatureStats().mAttributes[mIndex]. setModified (value, 0, 100); - } - }; + } + }; class OpModAttributeExplicit : public Interpreter::Opcode0 { int mIndex; - + public: - + OpModAttributeExplicit (int index) : mIndex (index) {} - + virtual void execute (Interpreter::Runtime& runtime) { MWScript::InterpreterContext& context @@ -151,10 +151,165 @@ namespace MWScript getModified(); context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. - setModified (value, 0, 100); - } - }; - + setModified (value, 0, 100); + } + }; + + class OpGetDynamic : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpGetDynamic (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + if (mIndex==0) + { + // TODO health is a special case + + + } + + Interpreter::Type_Integer value = + context.getReference().getCreatureStats().mDynamic[mIndex]. + getCurrent(); + + runtime.push (value); + } + }; + + class OpGetDynamicExplicit : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpGetDynamicExplicit (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer value = + context.getWorld().getPtr (id, false).getCreatureStats().mDynamic[mIndex]. + getCurrent(); + + runtime.push (value); + } + }; + + class OpSetDynamic : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpSetDynamic (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + context.getReference().getCreatureStats().mDynamic[mIndex]. + setModified (value, 0); + } + }; + + class OpSetDynamicExplicit : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpSetDynamicExplicit (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + context.getWorld().getPtr (id, false).getCreatureStats().mDynamic[mIndex]. + setModified (value, 0); + } + }; + + class OpModDynamic : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpModDynamic (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + Interpreter::Type_Integer diff = runtime[0].mInteger; + runtime.pop(); + + MWMechanics::CreatureStats& stats = context.getReference().getCreatureStats(); + + Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); + + stats.mDynamic[mIndex].setModified ( + diff + stats.mDynamic[mIndex].getModified(), 0); + + stats.mDynamic[mIndex].setCurrent (diff + current); + } + }; + + class OpModDynamicExplicit : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpModDynamicExplicit (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer diff = runtime[0].mInteger; + runtime.pop(); + + MWMechanics::CreatureStats& stats = + context.getWorld().getPtr (id, false).getCreatureStats(); + + Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); + + stats.mDynamic[mIndex].setModified ( + diff + stats.mDynamic[mIndex].getModified(), 0); + + stats.mDynamic[mIndex].setCurrent (diff + current); + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -163,7 +318,16 @@ namespace MWScript const int opcodeSetAttributeExplicit = 0x200003f; const int opcodeModAttribute = 0x2000047; const int opcodeModAttributeExplicit = 0x200004f; - + + const int numberOfDynamics = 3; + + const int opcodeGetDynamic = 0x2000057; + const int opcodeGetDynamicExplicit = 0x200005a; + const int opcodeSetDynamic = 0x200005d; + const int opcodeSetDynamicExplicit = 0x2000060; + const int opcodeModDynamic = 0x2000063; + const int opcodeModDynamicExplicit = 0x2000066; + void registerExtensions (Compiler::Extensions& extensions) { static const char *attributes[numberOfAttributes] = @@ -171,11 +335,16 @@ namespace MWScript "strength", "intelligence", "willpower", "agility", "speed", "endurance", "personality", "luck" }; - + + static const char *dynamics[numberOfDynamics] = + { + "health", "magicka", "fatigue" + }; + std::string get ("get"); std::string set ("set"); std::string mod ("mod"); - + for (int i=0; i CellStore; - + boost::any mPtr; ESM::CellRef *mCellRef; RefData *mRefData; CellStore *mCell; - + public: - + Ptr() : mCellRef (0), mRefData (0), mCell (0) {} - + bool isEmpty() const { return mPtr.empty(); } - + const std::type_info& getType() { assert (!mPtr.empty()); return mPtr.type(); } - + template Ptr (ESMS::LiveCellRef *liveCellRef, CellStore *cell) { @@ -51,45 +51,45 @@ namespace MWWorld mRefData = &liveCellRef->mData; mCell = cell; } - + template ESMS::LiveCellRef *get() const { return boost::any_cast*> (mPtr); } - + ESM::CellRef& getCellRef() const { assert (mCellRef); return *mCellRef; } - + RefData& getRefData() const { assert (mRefData); return *mRefData; } - + Ptr::CellStore *getCell() const { assert (mCell); return mCell; } - + /// Throws an exception, if the ID type does not support creature stats. MWMechanics::CreatureStats& getCreatureStats() const { RefData& data = getRefData(); - + if (!data.getCreatureStats().get()) { if (mPtr.type()==typeid (ESMS::LiveCellRef *)) { boost::shared_ptr stats ( new MWMechanics::CreatureStats); - + ESMS::LiveCellRef *ref = get(); - + stats->mAttributes[0].set (ref->base->data.strength); stats->mAttributes[1].set (ref->base->data.intelligence); stats->mAttributes[2].set (ref->base->data.willpower); @@ -98,6 +98,9 @@ namespace MWWorld stats->mAttributes[5].set (ref->base->data.endurance); stats->mAttributes[6].set (ref->base->data.personality); stats->mAttributes[7].set (ref->base->data.luck); + stats->mDynamic[0].set (ref->base->data.health); + stats->mDynamic[1].set (ref->base->data.mana); + stats->mDynamic[2].set (ref->base->data.fatigue); data.getCreatureStats() = stats; } @@ -105,9 +108,9 @@ namespace MWWorld { boost::shared_ptr stats ( new MWMechanics::CreatureStats); - + ESMS::LiveCellRef *ref = get(); - + stats->mAttributes[0].set (ref->base->npdt52.strength); stats->mAttributes[1].set (ref->base->npdt52.intelligence); stats->mAttributes[2].set (ref->base->npdt52.willpower); @@ -116,23 +119,26 @@ namespace MWWorld stats->mAttributes[5].set (ref->base->npdt52.endurance); stats->mAttributes[6].set (ref->base->npdt52.personality); stats->mAttributes[7].set (ref->base->npdt52.luck); + stats->mDynamic[0].set (ref->base->npdt52.health); + stats->mDynamic[1].set (ref->base->npdt52.mana); + stats->mDynamic[2].set (ref->base->npdt52.fatigue); data.getCreatureStats() = stats; } else throw std::runtime_error ( - "CreatureStats not available for this ID type"); + "CreatureStats not available for this ID type"); } - + return *data.getCreatureStats(); - } + } }; - + inline bool operator== (const Ptr& left, const Ptr& right) { return left.mRefData==right.mRefData; } - + inline bool operator!= (const Ptr& left, const Ptr& right) { return !(left==right); @@ -160,4 +166,3 @@ namespace MWWorld } #endif - From 9a7880ff7f206f86fb86a7a8569a9488a3f8a9a8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 29 Jul 2010 00:48:01 +0800 Subject: [PATCH 16/24] added GUI update for health, magicka and fatigue --- apps/openmw/mwgui/mw_layouts.hpp | 71 ++++++++++++++++---- apps/openmw/mwgui/window_manager.cpp | 5 ++ apps/openmw/mwgui/window_manager.hpp | 9 ++- apps/openmw/mwmechanics/mechanicsmanager.cpp | 42 ++++++++---- apps/openmw/mwmechanics/stat.hpp | 2 + 5 files changed, 99 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwgui/mw_layouts.hpp b/apps/openmw/mwgui/mw_layouts.hpp index fba2b411d..ce4a1ae98 100644 --- a/apps/openmw/mwgui/mw_layouts.hpp +++ b/apps/openmw/mwgui/mw_layouts.hpp @@ -89,6 +89,40 @@ namespace MWGui void setEffect(const char *img) { effect1->setImageTexture(img); } + void setValue (const std::string& id, const MWMechanics::DynamicStat& value) + { + static const char *ids[] = + { + "HBar", "MBar", "FBar", + 0 + }; + + for (int i=0; ids[i]; ++i) + if (ids[i]==id) + { + switch (i) + { + case 0: + + health->setProgressRange (value.getModified()); + health->setProgressPosition (value.getCurrent()); + break; + + case 1: + + magicka->setProgressRange (value.getModified()); + magicka->setProgressPosition (value.getCurrent()); + break; + + case 2: + + stamina->setProgressRange (value.getModified()); + stamina->setProgressPosition (value.getCurrent()); + break; + } + } + } + MyGUI::ProgressPtr health, magicka, stamina; MyGUI::StaticImagePtr weapImage, spellImage; @@ -136,7 +170,7 @@ namespace MWGui class StatsWindow : public OEngine::GUI::Layout { public: - void setBar(const char* name, const char* tname, int val, int max) + void setBar(const std::string& name, const std::string& tname, int val, int max) { MyGUI::ProgressPtr pt; getWidget(pt, name); @@ -169,10 +203,6 @@ namespace MWGui setText("RaceText", "Wood Elf"); setText("ClassText", "Pilgrim"); - setBar("HBar", "HBarT", 60, 100); - setBar("MBar", "MBarT", 30, 100); - setBar("FBar", "FBarT", 80, 100); - setText("AttribVal1", "30"); setText("AttribVal2", "40"); setText("AttribVal3", "30"); @@ -187,7 +217,7 @@ namespace MWGui { mMainWidget->setCaption(playerName); } - + /// Set label text for the value with the given ID. void setLabel (const std::string& id, const std::string& label) { @@ -197,7 +227,7 @@ namespace MWGui "Attrib7", "Attrib8", 0 }; - + for (int i=0; ids[i]; ++i) if (ids[i]==id) { @@ -205,7 +235,7 @@ namespace MWGui break; } } - + /// Set value for the given ID. void setValue (const std::string& id, const MWMechanics::Stat& value) { @@ -214,7 +244,7 @@ namespace MWGui "AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5", "AttribVal6", "AttribVal7", "AttribVal8", 0 - }; + }; for (int i=0; ids[i]; ++i) if (ids[i]==id) @@ -222,18 +252,33 @@ namespace MWGui std::ostringstream valueString; valueString << value.getModified(); setText (id, valueString.str()); - + if (value.getModified()>value.getBase()) setTextColor (id, 0, 1, 0); else if (value.getModified()& value) + { + static const char *ids[] = + { + "HBar", "MBar", "FBar", + 0 + }; + + for (int i=0; ids[i]; ++i) + if (ids[i]==id) + { + std::string id (ids[i]); + setBar (id, id + "T", value.getCurrent(), value.getModified()); + } } - }; } #endif diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index b6457f156..db4eb6f41 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -95,3 +95,8 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::StatsetValue (id, value); } +void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat& value) +{ + stats->setValue (id, value); + hud->setValue (id, value); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 007738fd1..aa1a8cbf9 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -113,7 +113,7 @@ namespace MWGui { if (newMode==GM_Inventory && allowed==GW_None) return; - + mode = newMode; updateVisible(); } @@ -138,12 +138,15 @@ namespace MWGui } MyGUI::Gui* getGui() const { return gui; } - + void setLabel (const std::string& id, const std::string& label); ///< Set label text for the value with the given ID. - + void setValue (const std::string& id, const MWMechanics::Stat& value); ///< Set value for the given ID. + + void setValue (const std::string& id, const MWMechanics::DynamicStat& value); + ///< Set value for the given ID. }; } #endif diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 06a04e7f0..0ba3c8f61 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -6,12 +6,12 @@ #include "../mwgui/window_manager.hpp" namespace MWMechanics -{ +{ MechanicsManager::MechanicsManager (const ESMS::ESMStore& store, MWGui::WindowManager& windowManager) : mStore (store), mWindowManager (windowManager) { - + } void MechanicsManager::configureGUI() @@ -28,32 +28,32 @@ namespace MWMechanics { "Attrib8", "sAttributeLuck" }, { 0, 0 } }; - + for (int i=0; names[i][0]; ++i) { -// This crashes because of encoding problems: +// This crashes because of encoding problems: // std::string label = mStore.gameSettings.find (names[i][1])->str; std::string label = names[i][1]; // until the problem is fixed, use the GMST ID as label - + mWindowManager.setLabel (names[i][0], label); } } - + void MechanicsManager::addActor (const MWWorld::Ptr& ptr) { mActors.insert (ptr); } - + void MechanicsManager::removeActor (const MWWorld::Ptr& ptr) { mActors.erase (ptr); } - + void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore) { std::set::iterator iter = mActors.begin(); - + while (iter!=mActors.end()) if (iter->getCell()==cellStore) { @@ -62,24 +62,29 @@ namespace MWMechanics else ++iter; } - + void MechanicsManager::watchActor (const MWWorld::Ptr& ptr) { mWatched = ptr; } - + void MechanicsManager::update() { if (!mWatched.isEmpty()) { MWMechanics::CreatureStats& stats = mWatched.getCreatureStats(); - + static const char *attributeNames[8] = { "AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5", "AttribVal6", "AttribVal7", "AttribVal8" }; - + + static const char *dynamicNames[3] = + { + "HBar", "MBar", "FBar" + }; + for (int i=0; i<8; ++i) { if (stats.mAttributes[i]!=mWatchedCreature.mAttributes[i]) @@ -89,7 +94,16 @@ namespace MWMechanics mWindowManager.setValue (attributeNames[i], stats.mAttributes[i]); } } + + for (int i=0; i<3; ++i) + { + if (stats.mDynamic[i]!=mWatchedCreature.mDynamic[i]) + { + mWatchedCreature.mDynamic[i] = stats.mDynamic[i]; + + mWindowManager.setValue (dynamicNames[i], stats.mDynamic[i]); + } + } } } } - diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index 7d7c64527..a42b53444 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -87,6 +87,8 @@ namespace MWMechanics public: + DynamicStat() : mCurrent (0) {} + const T& getBase() const { return mStatic.getBase(); From b13895cf3a5a376110f8d556beb3272dbc18bb89 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 29 Jul 2010 01:00:54 +0800 Subject: [PATCH 17/24] added ModCurrentHealth, ModCurrentMagicka, ModCurrentFatigue --- apps/openmw/mwscript/docs/vmformat.txt | 4 +- apps/openmw/mwscript/statsextensions.cpp | 63 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 205cdeeb1..64877d399 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -72,4 +72,6 @@ op 0x200005d-0x200005f: SetDynamic (health, magicka, fatigue) op 0x2000060-0x2000062: SetDynamic (health, magicka, fatigue), explicit reference op 0x2000063-0x2000065: ModDynamic (health, magicka, fatigue) op 0x2000066-0x2000068: ModDynamic (health, magicka, fatigue), explicit reference -opcodes 0x2000069-0x3ffffff unused +op 0x2000069-0x200006b: ModDynamic (health, magicka, fatigue) +op 0x200006c-0x200006e: ModDynamic (health, magicka, fatigue), explicit reference +opcodes 0x200006f-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 3ff6c67ce..388a5b6c7 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -310,6 +310,59 @@ namespace MWScript } }; + + class OpModCurrentDynamic : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpModCurrentDynamic (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + Interpreter::Type_Integer diff = runtime[0].mInteger; + runtime.pop(); + + MWMechanics::CreatureStats& stats = context.getReference().getCreatureStats(); + + Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); + + stats.mDynamic[mIndex].setCurrent (diff + current); + } + }; + + class OpModCurrentDynamicExplicit : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpModCurrentDynamicExplicit (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer diff = runtime[0].mInteger; + runtime.pop(); + + MWMechanics::CreatureStats& stats = + context.getWorld().getPtr (id, false).getCreatureStats(); + + Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); + + stats.mDynamic[mIndex].setCurrent (diff + current); + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -327,6 +380,8 @@ namespace MWScript const int opcodeSetDynamicExplicit = 0x2000060; const int opcodeModDynamic = 0x2000063; const int opcodeModDynamicExplicit = 0x2000066; + const int opcodeModCurrentDynamic = 0x2000069; + const int opcodeModCurrentDynamicExplicit = 0x200006c; void registerExtensions (Compiler::Extensions& extensions) { @@ -344,6 +399,7 @@ namespace MWScript std::string get ("get"); std::string set ("set"); std::string mod ("mod"); + std::string modCurrent ("modcurrent"); for (int i=0; i Date: Thu, 29 Jul 2010 01:12:50 +0800 Subject: [PATCH 18/24] added GetHealthGetRatio --- apps/openmw/mwscript/docs/vmformat.txt | 4 +- apps/openmw/mwscript/statsextensions.cpp | 69 ++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 64877d399..939467960 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -74,4 +74,6 @@ op 0x2000063-0x2000065: ModDynamic (health, magicka, fatigue) op 0x2000066-0x2000068: ModDynamic (health, magicka, fatigue), explicit reference op 0x2000069-0x200006b: ModDynamic (health, magicka, fatigue) op 0x200006c-0x200006e: ModDynamic (health, magicka, fatigue), explicit reference -opcodes 0x200006f-0x3ffffff unused +op 0x200006f-0x2000071: GetDynamic (health, magicka, fatigue) +op 0x2000072-0x2000074: GetDynamic (health, magicka, fatigue), explicit reference +opcodes 0x2000075-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 388a5b6c7..53ff1b1b3 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -363,6 +363,62 @@ namespace MWScript } }; + class OpGetDynamicGetRatio : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpGetDynamicGetRatio (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + MWMechanics::CreatureStats& stats = context.getReference().getCreatureStats(); + + Interpreter::Type_Float value = 0; + + Interpreter::Type_Float max = stats.mDynamic[mIndex].getModified(); + + if (max>0) + value = stats.mDynamic[mIndex].getCurrent() / max; + + runtime.push (value); + } + }; + + class OpGetDynamicGetRatioExplicit : public Interpreter::Opcode0 + { + int mIndex; + + public: + + OpGetDynamicGetRatioExplicit (int index) : mIndex (index) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + MWMechanics::CreatureStats& stats = + context.getWorld().getPtr (id, false).getCreatureStats(); + + Interpreter::Type_Float value = 0; + + Interpreter::Type_Float max = stats.mDynamic[mIndex].getModified(); + + if (max>0) + value = stats.mDynamic[mIndex].getCurrent() / max; + + runtime.push (value); + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -382,6 +438,8 @@ namespace MWScript const int opcodeModDynamicExplicit = 0x2000066; const int opcodeModCurrentDynamic = 0x2000069; const int opcodeModCurrentDynamicExplicit = 0x200006c; + const int opcodeGetDynamicGetRatio = 0x200006f; + const int opcodeGetDynamicGetRatioExplicit = 0x2000072; void registerExtensions (Compiler::Extensions& extensions) { @@ -400,6 +458,7 @@ namespace MWScript std::string set ("set"); std::string mod ("mod"); std::string modCurrent ("modcurrent"); + std::string getRatio ("getratio"); for (int i=0; i Date: Thu, 29 Jul 2010 01:38:14 +0800 Subject: [PATCH 19/24] added special case implementation for GetHealth (max weapon and armor health) --- apps/openmw/mwscript/statsextensions.cpp | 49 +++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 53ff1b1b3..727c48c71 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -170,9 +170,29 @@ namespace MWScript if (mIndex==0) { - // TODO health is a special case + // health is a special case + if (context.getReference().getType()== + typeid (ESMS::LiveCellRef *)) + { + ESMS::LiveCellRef *ref = + context.getReference().get(); + Interpreter::Type_Integer value = ref->base->data.health; + runtime.push (value); + return; + } + else if (context.getReference().getType()== + typeid (ESMS::LiveCellRef *)) + { + ESMS::LiveCellRef *ref = + context.getReference().get(); + + Interpreter::Type_Integer value = ref->base->data.health; + runtime.push (value); + + return; + } } Interpreter::Type_Integer value = @@ -199,6 +219,33 @@ namespace MWScript std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); + if (mIndex==0) + { + // health is a special case + if (context.getWorld().getPtr (id, false).getType()== + typeid (ESMS::LiveCellRef *)) + { + ESMS::LiveCellRef *ref = + context.getWorld().getPtr (id, false).get(); + + Interpreter::Type_Integer value = ref->base->data.health; + runtime.push (value); + + return; + } + else if (context.getWorld().getPtr (id, false).getType()== + typeid (ESMS::LiveCellRef *)) + { + ESMS::LiveCellRef *ref = + context.getWorld().getPtr (id, false).get(); + + Interpreter::Type_Integer value = ref->base->data.health; + runtime.push (value); + + return; + } + } + Interpreter::Type_Integer value = context.getWorld().getPtr (id, false).getCreatureStats().mDynamic[mIndex]. getCurrent(); From 416b61d06a4b62f42bca94b52a2c4aebe89d9941 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 29 Jul 2010 01:45:06 +0800 Subject: [PATCH 20/24] removed a special case, that wasn't a special case (MW Scripting for Dummies seems to be wrong here) --- apps/openmw/mwscript/statsextensions.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 727c48c71..997e2473a 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -533,9 +533,8 @@ namespace MWScript extensions.registerInstruction (modCurrent + dynamics[i], "l", opcodeModCurrentDynamic+i, opcodeModCurrentDynamicExplicit+i); - if (i==0) // GetMagickaGetRatio and GetFatigueGetRatio don't exist in original MW - extensions.registerFunction (get + dynamics[i] + getRatio, 'f', "", - opcodeGetDynamicGetRatio+i, opcodeGetDynamicGetRatioExplicit+i); + extensions.registerFunction (get + dynamics[i] + getRatio, 'f', "", + opcodeGetDynamicGetRatio+i, opcodeGetDynamicGetRatioExplicit+i); } } From 4c53495d9971838166fd888cc1d3cc8a4739d36e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 1 Aug 2010 01:41:15 +0800 Subject: [PATCH 21/24] removed encoding workaround for attribute names --- apps/openmw/mwmechanics/mechanicsmanager.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 0ba3c8f61..0c8cce8bd 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -31,10 +31,7 @@ namespace MWMechanics for (int i=0; names[i][0]; ++i) { -// This crashes because of encoding problems: -// std::string label = mStore.gameSettings.find (names[i][1])->str; - - std::string label = names[i][1]; // until the problem is fixed, use the GMST ID as label + std::string label = mStore.gameSettings.find (names[i][1])->str; mWindowManager.setLabel (names[i][0], label); } From fb3bf91dfb4f07c70f0e61779898d0ea5198ada7 Mon Sep 17 00:00:00 2001 From: Armin Preiml Date: Sun, 1 Aug 2010 20:46:51 +0200 Subject: [PATCH 22/24] Added inserting of NPC meshes. Only heads and bodys and not well placed for now. --- apps/openmw/mwrender/cellimp.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/openmw/mwrender/cellimp.cpp b/apps/openmw/mwrender/cellimp.cpp index 86bddb3a9..53911782e 100644 --- a/apps/openmw/mwrender/cellimp.cpp +++ b/apps/openmw/mwrender/cellimp.cpp @@ -40,6 +40,20 @@ void insertObj(CellRenderImp& cellRender, ESMS::LiveCellRef +void insertObj(CellRenderImp& cellRender, ESMS::LiveCellRef& liveRef ) +{ + std::string skinName = "meshes\\b\\B_N_" //some constants (seems so) + + liveRef.base->race + + "_" + + ((liveRef.base->flags & ESM::NPC::Female ) ? "F" : "M"); + + cellRender.insertBegin(liveRef.ref); + cellRender.insertMesh(skinName + "_Skins.nif"); + cellRender.insertMesh("meshes\\B\\" + liveRef.base->head + ".nif"); + liveRef.mData.setHandle (cellRender.insertEnd (liveRef.mData.isEnabled())); +} + template void insertCellRefList (CellRenderImp& cellRender, T& cellRefList) { From 389a28a836a7e9b21aca52c32400ba14dc832a0e Mon Sep 17 00:00:00 2001 From: Armin Preiml Date: Mon, 2 Aug 2010 09:59:59 +0200 Subject: [PATCH 23/24] Added const reference to esmstore to some methods down to CellRenderImp. Body part mesh names will be now obtained by the bodypart id. --- apps/openmw/mwrender/cellimp.cpp | 68 ++++++++++++++++--------------- apps/openmw/mwrender/cellimp.hpp | 7 +++- apps/openmw/mwrender/interior.cpp | 2 +- apps/openmw/mwrender/interior.hpp | 5 ++- apps/openmw/mwworld/world.cpp | 2 +- 5 files changed, 47 insertions(+), 37 deletions(-) diff --git a/apps/openmw/mwrender/cellimp.cpp b/apps/openmw/mwrender/cellimp.cpp index 53911782e..50047c1d9 100644 --- a/apps/openmw/mwrender/cellimp.cpp +++ b/apps/openmw/mwrender/cellimp.cpp @@ -5,7 +5,7 @@ using namespace MWRender; template -void insertObj(CellRenderImp& cellRender, T& liveRef) +void insertObj(CellRenderImp& cellRender, T& liveRef, const ESMS::ESMStore& store) { assert (liveRef.base != NULL); const std::string &model = liveRef.base->model; @@ -18,7 +18,7 @@ void insertObj(CellRenderImp& cellRender, T& liveRef) } template<> -void insertObj(CellRenderImp& cellRender, ESMS::LiveCellRef& liveRef) +void insertObj(CellRenderImp& cellRender, ESMS::LiveCellRef& liveRef, const ESMS::ESMStore& store) { assert (liveRef.base != NULL); const std::string &model = liveRef.base->model; @@ -41,52 +41,56 @@ void insertObj(CellRenderImp& cellRender, ESMS::LiveCellRef -void insertObj(CellRenderImp& cellRender, ESMS::LiveCellRef& liveRef ) +void insertObj(CellRenderImp& cellRender, ESMS::LiveCellRef& liveRef, const ESMS::ESMStore& store) { - std::string skinName = "meshes\\b\\B_N_" //some constants (seems so) - + liveRef.base->race - + "_" - + ((liveRef.base->flags & ESM::NPC::Female ) ? "F" : "M"); + std::string headID = liveRef.base->head; + + //get the part of the bodypart id which describes the race and the gender + std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); + std::string headModel = "meshes\\" + store.bodyParts.find(headID)->model; cellRender.insertBegin(liveRef.ref); - cellRender.insertMesh(skinName + "_Skins.nif"); - cellRender.insertMesh("meshes\\B\\" + liveRef.base->head + ".nif"); + cellRender.insertMesh(headModel); + + //TODO: define consts for each bodypart e.g. chest, foot, wrist... and put the parts in the right place + cellRender.insertMesh("meshes\\" + store.bodyParts.find(bodyRaceID + "chest")->model); + liveRef.mData.setHandle (cellRender.insertEnd (liveRef.mData.isEnabled())); } template -void insertCellRefList (CellRenderImp& cellRender, T& cellRefList) +void insertCellRefList (CellRenderImp& cellRender, const ESMS::ESMStore& store, T& cellRefList) { for(typename T::List::iterator it = cellRefList.list.begin(); it != cellRefList.list.end(); it++) { - insertObj (cellRender, *it); + insertObj (cellRender, *it, store); } } -void CellRenderImp::insertCell(ESMS::CellStore &cell) +void CellRenderImp::insertCell(ESMS::CellStore &cell, const ESMS::ESMStore& store) { // Loop through all references in the cell - insertCellRefList (*this, cell.activators); - insertCellRefList (*this, cell.potions); - insertCellRefList (*this, cell.appas); - insertCellRefList (*this, cell.armors); - insertCellRefList (*this, cell.books); - insertCellRefList (*this, cell.clothes); - insertCellRefList (*this, cell.containers); - insertCellRefList (*this, cell.creatures); - insertCellRefList (*this, cell.doors); - insertCellRefList (*this, cell.ingreds); -// insertCellRefList (*this, cell.creatureLists); -// insertCellRefList (*this, cell.itemLists); - insertCellRefList (*this, cell.lights); - insertCellRefList (*this, cell.lockpicks); - insertCellRefList (*this, cell.miscItems); - insertCellRefList (*this, cell.npcs); - insertCellRefList (*this, cell.probes); - insertCellRefList (*this, cell.repairs); - insertCellRefList (*this, cell.statics); - insertCellRefList (*this, cell.weapons); + insertCellRefList (*this, store, cell.activators); + insertCellRefList (*this, store, cell.potions); + insertCellRefList (*this, store, cell.appas); + insertCellRefList (*this, store, cell.armors); + insertCellRefList (*this, store, cell.books); + insertCellRefList (*this, store, cell.clothes); + insertCellRefList (*this, store, cell.containers); + insertCellRefList (*this, store, cell.creatures); + insertCellRefList (*this, store, cell.doors); + insertCellRefList (*this, store, cell.ingreds); + // insertCellRefList (*this, store, cell.creatureLists); + // insertCellRefList (*this, store, cell.itemLists); + insertCellRefList (*this, store, cell.lights); + insertCellRefList (*this, store, cell.lockpicks); + insertCellRefList (*this, store, cell.miscItems); + insertCellRefList (*this, store, cell.npcs); + insertCellRefList (*this, store, cell.probes); + insertCellRefList (*this, store, cell.repairs); + insertCellRefList (*this, store, cell.statics); + insertCellRefList (*this, store, cell.weapons); } diff --git a/apps/openmw/mwrender/cellimp.hpp b/apps/openmw/mwrender/cellimp.hpp index f93bbbbf3..a4bb6868c 100644 --- a/apps/openmw/mwrender/cellimp.hpp +++ b/apps/openmw/mwrender/cellimp.hpp @@ -12,6 +12,11 @@ namespace ESM class CellRef; } +namespace ESMS +{ + class ESMStore; +} + namespace MWRender { /// Base class for cell render, that implements inserting references into a cell in a @@ -35,7 +40,7 @@ namespace MWRender /// finish inserting a new reference and return a handle to it. virtual std::string insertEnd (bool Enable) = 0; - void insertCell(ESMS::CellStore &cell); + void insertCell(ESMS::CellStore &cell, const ESMS::ESMStore& store); }; } diff --git a/apps/openmw/mwrender/interior.cpp b/apps/openmw/mwrender/interior.cpp index 7f361141a..c67bc8878 100644 --- a/apps/openmw/mwrender/interior.cpp +++ b/apps/openmw/mwrender/interior.cpp @@ -186,7 +186,7 @@ void InteriorCellRender::show() configureAmbient(); configureFog(); - insertCell(cell); + insertCell(cell, store); } void InteriorCellRender::hide() diff --git a/apps/openmw/mwrender/interior.hpp b/apps/openmw/mwrender/interior.hpp index a8b5c7a8a..0ef5ec85c 100644 --- a/apps/openmw/mwrender/interior.hpp +++ b/apps/openmw/mwrender/interior.hpp @@ -43,6 +43,7 @@ namespace MWRender static bool lightOutQuadInLin; ESMS::CellStore &cell; + const ESMS::ESMStore &store; MWScene &scene; /// The scene node that contains all objects belonging to this @@ -78,8 +79,8 @@ namespace MWRender public: - InteriorCellRender(ESMS::CellStore &_cell, MWScene &_scene) - : cell(_cell), scene(_scene), base(NULL), insert(NULL), ambientMode (0) {} + InteriorCellRender(ESMS::CellStore &_cell, const ESMS::ESMStore& _store, MWScene &_scene) + : cell(_cell), store(_store), scene(_scene), base(NULL), insert(NULL), ambientMode (0) {} virtual ~InteriorCellRender() { destroy(); } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 55be70f1c..d6cb8f110 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -455,7 +455,7 @@ namespace MWWorld // This connects the cell data with the rendering scene. std::pair result = mActiveCells.insert (std::make_pair (cell, - new MWRender::InteriorCellRender (*cell, mScene))); + new MWRender::InteriorCellRender (*cell, mStore, mScene))); if (result.second) { From 986325b3b251cba9179482e7af46b8df3a9af914 Mon Sep 17 00:00:00 2001 From: Armin Preiml Date: Mon, 2 Aug 2010 13:22:50 +0200 Subject: [PATCH 24/24] Changed decoding code page from ISO-8859-1 to WINDOWS-1252 --- components/esm/esm_reader.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esm/esm_reader.hpp b/components/esm/esm_reader.hpp index 098afc513..70a81e6f4 100644 --- a/components/esm/esm_reader.hpp +++ b/components/esm/esm_reader.hpp @@ -618,13 +618,13 @@ public: return convertToUTF8(res); } - // Convert a string from ISO-8859-1 encoding to UTF-8 + // Convert a string from the encoding used by Morrowind to UTF-8 std::string convertToUTF8(std::string input) { std::string output = ""; //create convert description - iconv_t cd = iconv_open("UTF-8", "ISO-8859-1"); + iconv_t cd = iconv_open("UTF-8", "WINDOWS-1252"); if (cd == (iconv_t)-1) //error handling {