diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 88aaaecd4..465e485e4 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -14,16 +14,18 @@ set(GAMEREND mwrender/cellimp.cpp mwrender/interior.cpp mwrender/exterior.cpp - mwrender/playerpos.cpp - mwrender/sky.cpp) + mwrender/sky.cpp + mwrender/player.cpp + ) set(GAMEREND_HEADER mwrender/cell.hpp mwrender/cellimp.hpp mwrender/mwscene.hpp mwrender/interior.hpp mwrender/exterior.hpp - mwrender/playerpos.hpp - mwrender/sky.hpp) + mwrender/sky.hpp + mwrender/player.hpp + ) source_group(apps\\openmw\\mwrender FILES ${GAMEREND} ${GAMEREND_HEADER}) set(GAMEINPUT @@ -103,6 +105,7 @@ set(GAMESCRIPT_HEADER mwscript/controlextensions.hpp mwscript/extensions.hpp mwscript/globalscripts.hpp + mwscript/ref.hpp ) source_group(apps\\openmw\\mwscript FILES ${GAMESCRIPT} ${GAMESCRIPT_HEADER}) @@ -120,6 +123,7 @@ set(GAMEWORLD mwworld/actiontalk.cpp mwworld/actiontake.cpp mwworld/containerutil.cpp + mwworld/player.cpp ) set(GAMEWORLD_HEADER mwworld/refdata.hpp @@ -137,6 +141,7 @@ set(GAMEWORLD_HEADER mwworld/containerstore.hpp mwworld/manualref.hpp mwworld/containerutil.hpp + mwworld/player.hpp ) source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER}) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 21e042fd2..fda8e8d78 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -29,6 +29,7 @@ #include "mwworld/ptr.hpp" #include "mwworld/environment.hpp" #include "mwworld/class.hpp" +#include "mwworld/player.hpp" #include "mwclass/classes.hpp" @@ -75,9 +76,7 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) std::string effect; - - - MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayerPos().getPlayer().getCell(); + MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell(); //If the region has changed if(!(current->cell->data.flags & current->cell->Interior) && timer.elapsed() >= 10){ timer.restart(); @@ -377,7 +376,7 @@ void OMW::Engine::go() } // Sets up the input system - MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayerPos(), + MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayer(), *mEnvironment.mWindowManager, mDebug, *this); mEnvironment.mInputManager = &input; @@ -439,7 +438,7 @@ void OMW::Engine::activate() &ptr.getRefData().getLocals(), ptr); boost::shared_ptr action = - MWWorld::Class::get (ptr).activate (ptr, mEnvironment.mWorld->getPlayerPos().getPlayer(), + MWWorld::Class::get (ptr).activate (ptr, mEnvironment.mWorld->getPlayer().getPlayer(), mEnvironment); interpreterContext.activate (ptr, action); diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 32b33e95a..4f294ce87 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -5,8 +5,7 @@ #include -#include "../mwrender/playerpos.hpp" - +#include "../mwworld/player.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/nullaction.hpp" #include "../mwworld/actionteleport.hpp" @@ -65,7 +64,7 @@ namespace MWClass if (ref->ref.teleport) { // teleport door - if (environment.mWorld->getPlayerPos().getPlayer()==actor) + if (environment.mWorld->getPlayer().getPlayer()==actor) { // the player is using the door return boost::shared_ptr ( diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 0f6e73276..f78160cd7 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -13,6 +13,7 @@ #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" #include "../mwworld/refdata.hpp" +#include "../mwworld/player.hpp" #include "../mwinput/inputmanager.hpp" @@ -225,7 +226,7 @@ namespace MWDialogue // check cell if (!info.cell.empty()) - if (mEnvironment.mWorld->getPlayerPos().getPlayer().getCell()->cell->name != info.cell) + if (mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell->name != info.cell) return false; // TODO check DATAstruct diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index 501b234d1..581a5a576 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -4,6 +4,7 @@ #include "../mwmechanics/mechanicsmanager.hpp" #include "../mwgui/window_manager.hpp" +#include #include #include #include diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index 9eb6092ce..456849ed3 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -8,6 +8,8 @@ #include #include +#include + using namespace MWGui; using namespace Widgets; diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index 0544df6f0..31623fb58 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -15,10 +15,13 @@ #include #include -#include "../mwrender/playerpos.hpp" #include "../engine.hpp" +#include "../mwworld/player.hpp" + +#include "../mwrender/player.hpp" + #include #include #include @@ -58,7 +61,7 @@ namespace MWInput OEngine::Input::Poller poller; OEngine::Render::MouseLookEventPtr mouse; OEngine::GUI::EventInjectorPtr guiEvents; - MWRender::PlayerPos &player; + MWWorld::Player &player; MWGui::WindowManager &windows; OMW::Engine& mEngine; @@ -124,7 +127,7 @@ namespace MWInput public: InputImpl(OEngine::Render::OgreRenderer &_ogre, - MWRender::PlayerPos &_player, + MWWorld::Player &_player, MWGui::WindowManager &_windows, bool debug, OMW::Engine& engine) @@ -164,7 +167,7 @@ namespace MWInput ogre.getRoot()->addFrameListener(this); // Set up the mouse handler and tell it about the player camera - mouse = MouseLookEventPtr(new MouseLookEvent(player.getCamera())); + mouse = MouseLookEventPtr(new MouseLookEvent(player.getRenderer()->getCamera())); // This event handler pumps events into MyGUI guiEvents = EventInjectorPtr(new EventInjector(windows.getGui())); @@ -277,7 +280,7 @@ namespace MWInput { // Start mouse-looking again. TODO: This should also allow // for other ways to disable mouselook, like paralyzation. - mouse->setCamera(player.getCamera()); + mouse->setCamera(player.getRenderer()->getCamera()); // Disable GUI events guiEvents->enabled = false; @@ -286,7 +289,7 @@ namespace MWInput }; MWInputManager::MWInputManager(OEngine::Render::OgreRenderer &ogre, - MWRender::PlayerPos &player, + MWWorld::Player &player, MWGui::WindowManager &windows, bool debug, OMW::Engine& engine) @@ -300,7 +303,7 @@ namespace MWInput } void MWInputManager::setGuiMode(MWGui::GuiMode mode) - { + { impl->setGuiMode(mode); } } diff --git a/apps/openmw/mwinput/inputmanager.hpp b/apps/openmw/mwinput/inputmanager.hpp index 0e0c4650f..6b8034c8b 100644 --- a/apps/openmw/mwinput/inputmanager.hpp +++ b/apps/openmw/mwinput/inputmanager.hpp @@ -11,9 +11,9 @@ namespace OEngine } } -namespace MWRender +namespace MWWorld { - class PlayerPos; + class Player; } namespace MWGui @@ -42,7 +42,7 @@ namespace MWInput public: MWInputManager(OEngine::Render::OgreRenderer &_ogre, - MWRender::PlayerPos &_player, + MWWorld::Player&_player, MWGui::WindowManager &_windows, bool debug, OMW::Engine& engine); diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 23c0fe3b4..05219d6aa 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -8,12 +8,13 @@ #include "../mwworld/class.hpp" #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" +#include "../mwworld/player.hpp" namespace MWMechanics { void MechanicsManager::buildPlayer() { - MWWorld::Ptr ptr = mEnvironment.mWorld->getPlayerPos().getPlayer(); + MWWorld::Ptr ptr = mEnvironment.mWorld->getPlayer().getPlayer(); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr); @@ -33,9 +34,9 @@ namespace MWMechanics { const ESM::Race *race = mEnvironment.mWorld->getStore().races.find ( - mEnvironment.mWorld->getPlayerPos().getRace()); + mEnvironment.mWorld->getPlayer().getRace()); - bool male = mEnvironment.mWorld->getPlayerPos().isMale(); + bool male = mEnvironment.mWorld->getPlayer().isMale(); for (int i=0; i<8; ++i) { @@ -75,11 +76,11 @@ namespace MWMechanics } // birthsign - if (!mEnvironment.mWorld->getPlayerPos().getBirthsign().empty()) + if (!mEnvironment.mWorld->getPlayer().getBirthsign().empty()) { const ESM::BirthSign *sign = mEnvironment.mWorld->getStore().birthSigns.find ( - mEnvironment.mWorld->getPlayerPos().getBirthsign()); + mEnvironment.mWorld->getPlayer().getBirthsign()); for (std::vector::const_iterator iter (sign->powers.list.begin()); iter!=sign->powers.list.end(); ++iter) @@ -91,7 +92,7 @@ namespace MWMechanics // class if (mClassSelected) { - const ESM::Class& class_ = mEnvironment.mWorld->getPlayerPos().getClass(); + const ESM::Class& class_ = mEnvironment.mWorld->getPlayer().getClass(); for (int i=0; i<2; ++i) { @@ -330,12 +331,12 @@ namespace MWMechanics if (mUpdatePlayer) { // basic player profile; should not change anymore after the creation phase is finished. - mEnvironment.mWindowManager->setValue ("name", mEnvironment.mWorld->getPlayerPos().getName()); + mEnvironment.mWindowManager->setValue ("name", mEnvironment.mWorld->getPlayer().getName()); mEnvironment.mWindowManager->setValue ("race", - mEnvironment.mWorld->getStore().races.find (mEnvironment.mWorld->getPlayerPos(). + mEnvironment.mWorld->getStore().races.find (mEnvironment.mWorld->getPlayer(). getRace())->name); mEnvironment.mWindowManager->setValue ("class", - mEnvironment.mWorld->getPlayerPos().getClass().name); + mEnvironment.mWorld->getPlayer().getClass().name); mUpdatePlayer = false; MWGui::WindowManager::SkillList majorSkills (5); @@ -343,8 +344,8 @@ namespace MWMechanics for (int i=0; i<5; ++i) { - minorSkills[i] = mEnvironment.mWorld->getPlayerPos().getClass().data.skills[i][0]; - majorSkills[i] = mEnvironment.mWorld->getPlayerPos().getClass().data.skills[i][1]; + minorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][0]; + majorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][1]; } mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills); @@ -353,14 +354,14 @@ namespace MWMechanics void MechanicsManager::setPlayerName (const std::string& name) { - mEnvironment.mWorld->getPlayerPos().setName (name); + mEnvironment.mWorld->getPlayer().setName (name); mUpdatePlayer = true; } void MechanicsManager::setPlayerRace (const std::string& race, bool male) { - mEnvironment.mWorld->getPlayerPos().setGender (male); - mEnvironment.mWorld->getPlayerPos().setRace (race); + mEnvironment.mWorld->getPlayer().setGender (male); + mEnvironment.mWorld->getPlayer().setRace (race); mRaceSelected = true; buildPlayer(); mUpdatePlayer = true; @@ -368,14 +369,14 @@ namespace MWMechanics void MechanicsManager::setPlayerBirthsign (const std::string& id) { - mEnvironment.mWorld->getPlayerPos().setBirthsign (id); + mEnvironment.mWorld->getPlayer().setBirthsign (id); buildPlayer(); mUpdatePlayer = true; } void MechanicsManager::setPlayerClass (const std::string& id) { - mEnvironment.mWorld->getPlayerPos().setClass (*mEnvironment.mWorld->getStore().classes.find (id)); + mEnvironment.mWorld->getPlayer().setClass (*mEnvironment.mWorld->getStore().classes.find (id)); mClassSelected = true; buildPlayer(); mUpdatePlayer = true; @@ -383,7 +384,7 @@ namespace MWMechanics void MechanicsManager::setPlayerClass (const ESM::Class& class_) { - mEnvironment.mWorld->getPlayerPos().setClass (class_); + mEnvironment.mWorld->getPlayer().setClass (class_); mClassSelected = true; buildPlayer(); mUpdatePlayer = true; diff --git a/apps/openmw/mwrender/mwscene.cpp b/apps/openmw/mwrender/mwscene.cpp index 133607797..5fff2c295 100644 --- a/apps/openmw/mwrender/mwscene.cpp +++ b/apps/openmw/mwrender/mwscene.cpp @@ -13,6 +13,8 @@ #include "../mwworld/ptr.hpp" #include +#include "player.hpp" + using namespace MWRender; using namespace Ogre; @@ -38,6 +40,13 @@ MWScene::MWScene(OEngine::Render::OgreRenderer &_rend) //used to obtain ingame information of ogre objects (which are faced or selected) mRaySceneQuery = rend.getScene()->createRayQuery(Ray()); + + mPlayer = new MWRender::Player (getCamera()); +} + +MWScene::~MWScene() +{ + delete mPlayer; } std::pair MWScene::getFacedHandle (MWWorld::World& world) diff --git a/apps/openmw/mwrender/mwscene.hpp b/apps/openmw/mwrender/mwscene.hpp index 9d2a51bae..b4c8357cf 100644 --- a/apps/openmw/mwrender/mwscene.hpp +++ b/apps/openmw/mwrender/mwscene.hpp @@ -20,36 +20,41 @@ namespace MWWorld namespace MWRender { - /** Class responsible for Morrowind-specific interfaces to OGRE. + class Player; - This might be refactored partially into a non-mw specific - counterpart in ogre/ at some point. - */ - class MWScene - { - OEngine::Render::OgreRenderer &rend; + /// \brief 3D-scene (rendering and physics) - // Root node for all objects added to the scene. This is rotated so - // that the OGRE coordinate system matches that used internally in - // Morrowind. - Ogre::SceneNode *mwRoot; - Ogre::RaySceneQuery *mRaySceneQuery; + class MWScene + { + OEngine::Render::OgreRenderer &rend; - public: - MWScene(OEngine::Render::OgreRenderer &_rend); + /// Root node for all objects added to the scene. This is rotated so + /// that the OGRE coordinate system matches that used internally in + /// Morrowind. + Ogre::SceneNode *mwRoot; + Ogre::RaySceneQuery *mRaySceneQuery; - Ogre::Camera *getCamera() { return rend.getCamera(); } - Ogre::SceneNode *getRoot() { return mwRoot; } - Ogre::SceneManager *getMgr() { return rend.getScene(); } - Ogre::Viewport *getViewport() { return rend.getViewport(); } - Ogre::RaySceneQuery *getRaySceneQuery() { return mRaySceneQuery; } + MWRender::Player *mPlayer; - //gets the handle of the object the player is looking at - //pair - //name is empty and distance = -1 if there is no object which - //can be faced - std::pair getFacedHandle (MWWorld::World& world); - }; + public: + + MWScene (OEngine::Render::OgreRenderer &_rend); + + ~MWScene(); + + Ogre::Camera *getCamera() { return rend.getCamera(); } + Ogre::SceneNode *getRoot() { return mwRoot; } + Ogre::SceneManager *getMgr() { return rend.getScene(); } + Ogre::Viewport *getViewport() { return rend.getViewport(); } + Ogre::RaySceneQuery *getRaySceneQuery() { return mRaySceneQuery; } + MWRender::Player *getPlayer() { return mPlayer; } + + /// Gets the handle of the object the player is looking at + /// pair + /// name is empty and distance = -1 if there is no object which + /// can be faced + std::pair getFacedHandle (MWWorld::World& world); + }; } #endif diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp new file mode 100644 index 000000000..badc77bda --- /dev/null +++ b/apps/openmw/mwrender/player.cpp @@ -0,0 +1,8 @@ + +#include "player.hpp" + +namespace MWRender +{ + Player::Player (Ogre::Camera *camera) : mCamera (camera) + {} +} diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp new file mode 100644 index 000000000..a8f8d24fe --- /dev/null +++ b/apps/openmw/mwrender/player.hpp @@ -0,0 +1,24 @@ +#ifndef GAME_MWRENDER_PLAYER_H +#define GAME_MWRENDER_PLAYER_H + +namespace Ogre +{ + class Camera; +} + +namespace MWRender +{ + /// \brief Player character rendering and camera control + class Player + { + Ogre::Camera *mCamera; + + public: + + Player (Ogre::Camera *camera); + + Ogre::Camera *getCamera() { return mCamera; } + }; +} + +#endif diff --git a/apps/openmw/mwrender/playerpos.cpp b/apps/openmw/mwrender/playerpos.cpp deleted file mode 100644 index a1410e57b..000000000 --- a/apps/openmw/mwrender/playerpos.cpp +++ /dev/null @@ -1,41 +0,0 @@ - -#include "playerpos.hpp" - -#include "../mwworld/world.hpp" - -namespace MWRender -{ - PlayerPos::PlayerPos (Ogre::Camera *cam, const ESM::NPC *player, MWWorld::World& world) : - mCellStore (0), camera(cam), mWorld (world), mClass (0) - { - mPlayer.base = player; - mName = player->name; - mMale = !(player->flags & ESM::NPC::Female); - mRace = player->race; - mPlayer.ref.pos.pos[0] = mPlayer.ref.pos.pos[1] = mPlayer.ref.pos.pos[2] = 0; - mClass = new ESM::Class (*world.getStore().classes.find (player->cls)); - } - - PlayerPos::~PlayerPos() - { - delete mClass; - } - - void PlayerPos::setPos(float x, float y, float z, bool updateCamera) - { - mWorld.moveObject (getPlayer(), x, y, z); - - if (updateCamera) - camera->setPosition (Ogre::Vector3 ( - mPlayer.ref.pos.pos[0], - mPlayer.ref.pos.pos[2], - -mPlayer.ref.pos.pos[1])); - } - - void PlayerPos::setClass (const ESM::Class& class_) - { - ESM::Class *new_class = new ESM::Class (class_); - delete mClass; - mClass = new_class; - } -} diff --git a/apps/openmw/mwrender/playerpos.hpp b/apps/openmw/mwrender/playerpos.hpp deleted file mode 100644 index b694a72c3..000000000 --- a/apps/openmw/mwrender/playerpos.hpp +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef _MWRENDER_PLAYERPOS_H -#define _MWRENDER_PLAYERPOS_H - -#include "OgreCamera.h" - -#include - -#include "../mwworld/refdata.hpp" -#include "../mwworld/ptr.hpp" - -namespace MWWorld -{ - class World; -} - -namespace MWRender -{ - // This class keeps track of the player position. It takes care of - // camera movement, sound listener updates, and collision handling - // (to be done). - class PlayerPos - { - ESMS::LiveCellRef mPlayer; - MWWorld::Ptr::CellStore *mCellStore; - Ogre::Camera *camera; - MWWorld::World& mWorld; - std::string mName; - bool mMale; - std::string mRace; - std::string mBirthsign; - ESM::Class *mClass; - - public: - - PlayerPos(Ogre::Camera *cam, const ESM::NPC *player, MWWorld::World& world); - - ~PlayerPos(); - - // Set the player position. Uses Morrowind coordinates. - void setPos(float _x, float _y, float _z, bool updateCamera = false); - - void setCell (MWWorld::Ptr::CellStore *cellStore) - { - mCellStore = cellStore; - } - - Ogre::Camera *getCamera() { return camera; } - - // Move the player relative to her own position and - // orientation. After the call, the new position is returned. - void moveRel(float &relX, float &relY, float &relZ) - { - using namespace Ogre; - - // Move camera relative to its own direction - camera->moveRelative(Vector3(relX,0,relZ)); - - // Up/down movement is always done relative the world axis. - camera->move(Vector3(0,relY,0)); - - // Get new camera position, converting back to MW coords. - Vector3 pos = camera->getPosition(); - relX = pos[0]; - relY = -pos[2]; - relZ = pos[1]; - - // TODO: Collision detection must be used to find the REAL new - // position. - - // Set the position - setPos(relX, relY, relZ); - } - - MWWorld::Ptr getPlayer() - { - MWWorld::Ptr ptr (&mPlayer, mCellStore); - return ptr; - } - - void setName (const std::string& name) - { - mName = name; - } - - void setGender (bool male) - { - mMale = male; - } - - void setRace (const std::string& race) - { - mRace = race; - } - - void setBirthsign (const std::string& birthsign) - { - mBirthsign = birthsign; - } - - void setClass (const ESM::Class& class_); - - std::string getName() const - { - return mName; - } - - bool isMale() const - { - return mMale; - } - - std::string getRace() const - { - return mRace; - } - - std::string getBirthsign() const - { - return mBirthsign; - } - - const ESM::Class& getClass() const - { - return *mClass; - } - }; -} -#endif diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index cd36eac9e..6d74ae45a 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -8,6 +8,7 @@ #include #include "interpretercontext.hpp" +#include "ref.hpp" #include @@ -15,46 +16,14 @@ namespace MWScript { namespace Ai { + template class OpAiTravel : public Interpreter::Opcode1 { public: virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - MWWorld::Ptr ptr = context.getReference(); - - Interpreter::Type_Float x = runtime[0].mInteger; - runtime.pop(); - - Interpreter::Type_Float y = runtime[0].mInteger; - runtime.pop(); - - Interpreter::Type_Float z = runtime[0].mInteger; - runtime.pop(); - - // discard additional arguments (reset), because we have no idea what they mean. - for (unsigned int i=0; i (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Float x = runtime[0].mInteger; runtime.pop(); @@ -72,56 +41,14 @@ namespace MWScript } }; + template class OpAiEscort : public Interpreter::Opcode1 { public: virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - MWWorld::Ptr ptr = context.getReference(); - - std::string actor = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - Interpreter::Type_Float duration = runtime[0].mInteger; - runtime.pop(); - - Interpreter::Type_Float x = runtime[0].mInteger; - runtime.pop(); - - Interpreter::Type_Float y = runtime[0].mInteger; - runtime.pop(); - - Interpreter::Type_Float z = runtime[0].mInteger; - runtime.pop(); - - // discard additional arguments (reset), because we have no idea what they mean. - for (unsigned int i=0; i (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWWorld::Ptr ptr = R()(runtime); std::string actor = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -146,16 +73,14 @@ namespace MWScript } }; + template class OpGetAiPackageDone : public Interpreter::Opcode0 { public: virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - MWWorld::Ptr ptr = context.getReference(); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = 0; @@ -163,25 +88,6 @@ namespace MWScript } }; - class OpGetAiPackageDoneExplicit : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - - Interpreter::Type_Integer value = 0; - - runtime.push (value); - } - }; const int opcodeAiTravel = 0x20000; @@ -204,12 +110,13 @@ namespace MWScript void installOpcodes (Interpreter::Interpreter& interpreter) { - interpreter.installSegment3 (opcodeAiTravel, new OpAiTravel); - interpreter.installSegment3 (opcodeAiTravelExplicit, new OpAiTravelExplicit); - interpreter.installSegment3 (opcodeAiEscort, new OpAiEscort); - interpreter.installSegment3 (opcodeAiEscortExplicit, new OpAiEscortExplicit); - interpreter.installSegment5 (opcodeGetAiPackageDone, new OpGetAiPackageDone); - interpreter.installSegment5 (opcodeGetAiPackageDoneExplicit, new OpGetAiPackageDoneExplicit); + interpreter.installSegment3 (opcodeAiTravel, new OpAiTravel); + interpreter.installSegment3 (opcodeAiTravelExplicit, new OpAiTravel); + interpreter.installSegment3 (opcodeAiEscort, new OpAiEscort); + interpreter.installSegment3 (opcodeAiEscortExplicit, new OpAiEscort); + interpreter.installSegment5 (opcodeGetAiPackageDone, new OpGetAiPackageDone); + interpreter.installSegment5 (opcodeGetAiPackageDoneExplicit, + new OpGetAiPackageDone); } } } diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 1121d8eff..aef48ddec 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -14,17 +14,21 @@ #include "../mwworld/containerutil.hpp" #include "interpretercontext.hpp" +#include "ref.hpp" namespace MWScript { namespace Container { + template class OpAddItem : public Interpreter::Opcode0 { public: virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context = static_cast (runtime.getContext()); @@ -37,40 +41,6 @@ namespace MWScript if (count<0) throw std::runtime_error ("second argument for AddItem must be non-negative"); - MWWorld::Ptr ptr = context.getReference(); - - MWWorld::ManualRef ref (context.getWorld().getStore(), item); - - ref.getPtr().getRefData().setCount (count); - - MWWorld::Class::get (ref.getPtr()).insertIntoContainer (ref.getPtr(), - MWWorld::Class::get (ptr).getContainerStore (ptr)); - } - }; - - class OpAddItemExplicit : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - std::string item = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - Interpreter::Type_Integer count = runtime[0].mInteger; - runtime.pop(); - - if (count<0) - throw std::runtime_error ("second argument for AddItem must be non-negative"); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - MWWorld::ManualRef ref (context.getWorld().getStore(), item); ref.getPtr().getRefData().setCount (count); @@ -80,55 +50,21 @@ namespace MWScript } }; + template class OpGetItemCount : public Interpreter::Opcode0 { public: virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context = static_cast (runtime.getContext()); std::string item = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - MWWorld::Ptr ptr = context.getReference(); - - std::vector list; - - MWWorld::listItemsInContainer (item, - MWWorld::Class::get (ptr).getContainerStore (ptr), - context.getWorld().getStore(), list); - - Interpreter::Type_Integer sum = 0; - - for (std::vector::iterator iter (list.begin()); iter!=list.end(); - ++iter) - { - sum += iter->getRefData().getCount(); - } - - runtime.push (sum); - } - }; - - class OpGetItemCountExplicit : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - std::string item = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - std::vector list; MWWorld::listItemsInContainer (item, @@ -147,12 +83,15 @@ namespace MWScript } }; + template class OpRemoveItem : public Interpreter::Opcode0 { public: virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context = static_cast (runtime.getContext()); @@ -165,58 +104,6 @@ namespace MWScript if (count<0) throw std::runtime_error ("second argument for RemoveItem must be non-negative"); - MWWorld::Ptr ptr = context.getReference(); - - std::vector list; - - MWWorld::listItemsInContainer (item, - MWWorld::Class::get (ptr).getContainerStore (ptr), - context.getWorld().getStore(), list); - - for (std::vector::iterator iter (list.begin()); - iter!=list.end() && count; - ++iter) - { - if (iter->getRefData().getCount()<=count) - { - count -= iter->getRefData().getCount(); - iter->getRefData().setCount (0); - } - else - { - iter->getRefData().setCount (iter->getRefData().getCount()-count); - count = 0; - } - } - - // To be fully compatible with original Morrowind, we would need to check if - // count is >= 0 here and throw an exception. But let's be tollerant instead. - } - }; - - class OpRemoveItemExplicit : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - std::string item = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - Interpreter::Type_Integer count = runtime[0].mInteger; - runtime.pop(); - - if (count<0) - throw std::runtime_error ("second argument for RemoveItem must be non-negative"); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - std::vector list; MWWorld::listItemsInContainer (item, @@ -262,12 +149,12 @@ namespace MWScript void installOpcodes (Interpreter::Interpreter& interpreter) { - interpreter.installSegment5 (opcodeAddItem, new OpAddItem); - interpreter.installSegment5 (opcodeAddItemExplicit, new OpAddItemExplicit); - interpreter.installSegment5 (opcodeGetItemCount, new OpGetItemCount); - interpreter.installSegment5 (opcodeGetItemCountExplicit, new OpGetItemCountExplicit); - interpreter.installSegment5 (opcodeRemoveItem, new OpRemoveItem); - interpreter.installSegment5 (opcodeRemoveItemExplicit, new OpRemoveItemExplicit); + interpreter.installSegment5 (opcodeAddItem, new OpAddItem); + interpreter.installSegment5 (opcodeAddItemExplicit, new OpAddItem); + interpreter.installSegment5 (opcodeGetItemCount, new OpGetItemCount); + interpreter.installSegment5 (opcodeGetItemCountExplicit, new OpGetItemCount); + interpreter.installSegment5 (opcodeRemoveItem, new OpRemoveItem); + interpreter.installSegment5 (opcodeRemoveItemExplicit, new OpRemoveItem); } } } diff --git a/apps/openmw/mwscript/controlextensions.cpp b/apps/openmw/mwscript/controlextensions.cpp index e38ee7c2d..a560a28c6 100644 --- a/apps/openmw/mwscript/controlextensions.cpp +++ b/apps/openmw/mwscript/controlextensions.cpp @@ -7,6 +7,8 @@ #include #include +#include "../mwworld/player.hpp" + #include "interpretercontext.hpp" #include @@ -35,10 +37,32 @@ namespace MWScript } }; + class OpSetCollision : public Interpreter::Opcode0 + { + bool mEnable; + + public: + + OpSetCollision (bool enable) + : mEnable (enable) + {} + + virtual void execute (Interpreter::Runtime& runtime) + { + InterpreterContext& context + = static_cast (runtime.getContext()); + + context.getWorld().getPlayer().setCollisionMode (mEnable); + } + + }; + const int numberOfControls = 7; const int opcodeEnable = 0x200007e; const int opcodeDisable = 0x2000085; + const int opcodeEnableCollision = 0x2000130; + const int opcodeDisableCollision = 0x2000131; const char *controls[numberOfControls] = { @@ -56,6 +80,9 @@ namespace MWScript extensions.registerInstruction (enable + controls[i], "", opcodeEnable+i); extensions.registerInstruction (disable + controls[i], "", opcodeDisable+i); } + + extensions.registerInstruction ("enablecollision", "", opcodeEnableCollision); + extensions.registerInstruction ("disablecollision", "", opcodeDisableCollision); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -65,6 +92,9 @@ namespace MWScript interpreter.installSegment5 (opcodeEnable+i, new OpSetControl (controls[i], true)); interpreter.installSegment5 (opcodeDisable+i, new OpSetControl (controls[i], false)); } + + interpreter.installSegment5 (opcodeEnableCollision, new OpSetCollision (true)); + interpreter.installSegment5 (opcodeDisableCollision, new OpSetCollision (false)); } } } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 2a859c57f..b77f53221 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -101,4 +101,6 @@ op 0x20000c4-0x20000de: SetSkill op 0x20000df-0x20000f9: SetSkill, explicit reference op 0x20000fa-0x2000114: ModSkill op 0x2000115-0x200012f: ModSKill, explicit reference +op 0x2000130: EnableCollision +op 0x2000131: DisableCollision opcodes 0x2000130-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 9cb65dcd7..a04065f9c 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -7,10 +7,11 @@ #include #include -#include "interpretercontext.hpp" - #include "../mwworld/class.hpp" +#include "interpretercontext.hpp" +#include "ref.hpp" + namespace MWScript { namespace Misc @@ -55,42 +56,14 @@ namespace MWScript } }; + template class OpLock : public Interpreter::Opcode1 { public: virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - MWWorld::Ptr ptr = context.getReference(); - - Interpreter::Type_Integer lockLevel = 100; - - if (arg0==1) - { - lockLevel = runtime[0].mInteger; - runtime.pop(); - } - - MWWorld::Class::get (ptr).lock (ptr, lockLevel); - } - }; - - class OpLockExplicit : public Interpreter::Opcode1 - { - public: - - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) - { - InterpreterContext& context = - static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer lockLevel = 100; @@ -104,34 +77,14 @@ namespace MWScript } }; + template class OpUnlock : public Interpreter::Opcode0 { public: virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - MWWorld::Ptr ptr = context.getReference(); - - MWWorld::Class::get (ptr).unlock (ptr); - } - }; - - class OpUnlockExplicit : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - InterpreterContext& context = - static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWWorld::Ptr ptr = R()(runtime); MWWorld::Class::get (ptr).unlock (ptr); } @@ -160,10 +113,10 @@ namespace MWScript interpreter.installSegment5 (opcodeXBox, new OpXBox); interpreter.installSegment5 (opcodeOnActivate, new OpOnActivate); interpreter.installSegment5 (opcodeActivate, new OpActivate); - interpreter.installSegment3 (opcodeLock, new OpLock); - interpreter.installSegment3 (opcodeLockExplicit, new OpLockExplicit); - interpreter.installSegment5 (opcodeUnlock, new OpUnlock); - interpreter.installSegment5 (opcodeUnlockExplicit, new OpUnlockExplicit); + interpreter.installSegment3 (opcodeLock, new OpLock); + interpreter.installSegment3 (opcodeLockExplicit, new OpLock); + interpreter.installSegment5 (opcodeUnlock, new OpUnlock); + interpreter.installSegment5 (opcodeUnlockExplicit, new OpUnlock); } } } diff --git a/apps/openmw/mwscript/ref.hpp b/apps/openmw/mwscript/ref.hpp new file mode 100644 index 000000000..5ca1ea4d6 --- /dev/null +++ b/apps/openmw/mwscript/ref.hpp @@ -0,0 +1,41 @@ +#ifndef GAME_MWSCRIPT_REF_H +#define GAME_MWSCRIPT_REF_H + +#include + +#include + +#include "../mwworld/ptr.hpp" +#include "../mwworld/world.hpp" + +#include "interpretercontext.hpp" + +namespace MWScript +{ + struct ExplicitRef + { + MWWorld::Ptr operator() (Interpreter::Runtime& runtime) const + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + return context.getWorld().getPtr (id, false); + } + }; + + struct ImplicitRef + { + MWWorld::Ptr operator() (Interpreter::Runtime& runtime) const + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + return context.getReference(); + } + }; +} + +#endif diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index 58554ef16..d5cc41b76 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -7,22 +7,26 @@ #include #include -#include "interpretercontext.hpp" - #include "../mwworld/world.hpp" #include "../mwsound/soundmanager.hpp" +#include "interpretercontext.hpp" +#include "ref.hpp" + namespace MWScript { namespace Sound { + template class OpSay : public Interpreter::Opcode0 { public: - + virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context = static_cast (runtime.getContext()); @@ -32,296 +36,173 @@ namespace MWScript std::string text = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - context.getSoundManager().say (context.getReference(), file); + context.getSoundManager().say (ptr, file); context.messageBox (text); - } - }; - + } + }; + + template class OpSayDone : public Interpreter::Opcode0 { public: - + virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - - runtime.push (context.getSoundManager().sayDone (context.getReference())); - } - }; - + + runtime.push (context.getSoundManager().sayDone (ptr)); + } + }; + class OpStreamMusic : public Interpreter::Opcode0 { public: - + virtual void execute (Interpreter::Runtime& runtime) { MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - + context.getSoundManager().streamMusic (sound); - } - }; + } + }; class OpPlaySound : public Interpreter::Opcode0 { public: - + virtual void execute (Interpreter::Runtime& runtime) { MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - + context.getSoundManager().playSound (sound, 1.0, 1.0); - } - }; - + } + }; + class OpPlaySoundVP : public Interpreter::Opcode0 { public: - + virtual void execute (Interpreter::Runtime& runtime) { MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - + Interpreter::Type_Float volume = runtime[0].mFloat; runtime.pop(); Interpreter::Type_Float pitch = runtime[0].mFloat; runtime.pop(); - + context.getSoundManager().playSound (sound, volume, pitch); - } - }; - + } + }; + + template class OpPlaySound3D : public Interpreter::Opcode0 { bool mLoop; - + public: - + OpPlaySound3D (bool loop) : mLoop (loop) {} - + virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - - context.getSoundManager().playSound3D (context.getReference(), sound, - 1.0, 1.0, mLoop); - } - }; - + + context.getSoundManager().playSound3D (ptr, sound, 1.0, 1.0, mLoop); + } + }; + + template class OpPlaySoundVP3D : public Interpreter::Opcode0 { bool mLoop; - + public: - + OpPlaySoundVP3D (bool loop) : mLoop (loop) {} - + virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - + Interpreter::Type_Float volume = runtime[0].mFloat; runtime.pop(); Interpreter::Type_Float pitch = runtime[0].mFloat; runtime.pop(); - - context.getSoundManager().playSound3D (context.getReference(), sound, volume, - pitch, mLoop); - } - }; + context.getSoundManager().playSound3D (ptr, sound, volume, pitch, mLoop); + } + }; + + template class OpStopSound : public Interpreter::Opcode0 { public: - + virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - - context.getSoundManager().stopSound3D (context.getReference(), sound); - } - }; - + + context.getSoundManager().stopSound3D (ptr, sound); + } + }; + + template class OpGetSoundPlaying : public Interpreter::Opcode0 { public: - + virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - + int index = runtime[0].mInteger; runtime.pop(); - + runtime.push (context.getSoundManager().getSoundPlaying ( - context.getReference(), runtime.getStringLiteral (index))); - } + ptr, runtime.getStringLiteral (index))); + } }; - - class OpSayExplicit : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - std::string file = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - std::string text = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - context.getSoundManager().say (context.getWorld().getPtr (id, true), - file); - } - }; - - class OpSayDoneExplicit : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - runtime.push (context.getSoundManager().sayDone ( - context.getWorld().getPtr (id, true))); - } - }; - - class OpPlaySound3DExplicit : public Interpreter::Opcode0 - { - bool mLoop; - - public: - - OpPlaySound3DExplicit (bool loop) : mLoop (loop) {} - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - std::string sound = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - context.getSoundManager().playSound3D ( - context.getWorld().getPtr (id, true), sound, 1.0, 1.0, mLoop); - } - }; - - class OpPlaySoundVP3DExplicit : public Interpreter::Opcode0 - { - bool mLoop; - - public: - - OpPlaySoundVP3DExplicit (bool loop) : mLoop (loop) {} - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - std::string sound = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - Interpreter::Type_Float volume = runtime[0].mFloat; - runtime.pop(); - - Interpreter::Type_Float pitch = runtime[0].mFloat; - runtime.pop(); - - context.getSoundManager().playSound3D ( - context.getWorld().getPtr (id, true), sound, volume, pitch, mLoop); - - } - }; - - class OpStopSoundExplicit : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - std::string sound = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - context.getSoundManager().stopSound3D ( - context.getWorld().getPtr (id, true), sound); - } - }; - - class OpGetSoundPlayingExplicit : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - std::string id = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - - int index = runtime[0].mInteger; - runtime.pop(); - - runtime.push (context.getSoundManager().getSoundPlaying ( - context.getWorld().getPtr (id, true), - runtime.getStringLiteral (index))); - } - }; - const int opcodeSay = 0x2000001; const int opcodeSayDone = 0x2000002; const int opcodeStreamMusic = 0x2000003; @@ -342,7 +223,7 @@ namespace MWScript const int opcodePlayLoopSound3DVPExplicit = 0x200001e; const int opcodeStopSoundExplicit = 0x200001f; const int opcodeGetSoundPlayingExplicit = 0x2000020; - + void registerExtensions (Compiler::Extensions& extensions) { extensions.registerInstruction ("say", "SS", opcodeSay, opcodeSayExplicit); @@ -361,37 +242,37 @@ namespace MWScript extensions.registerInstruction ("stopsound", "c", opcodeStopSound, opcodeStopSoundExplicit); extensions.registerFunction ("getsoundplaying", 'l', "c", opcodeGetSoundPlaying, - opcodeGetSoundPlayingExplicit); + opcodeGetSoundPlayingExplicit); } - + void installOpcodes (Interpreter::Interpreter& interpreter) { - interpreter.installSegment5 (opcodeSay, new OpSay); - interpreter.installSegment5 (opcodeSayDone, new OpSayDone); + interpreter.installSegment5 (opcodeSay, new OpSay); + interpreter.installSegment5 (opcodeSayDone, new OpSayDone); interpreter.installSegment5 (opcodeStreamMusic, new OpStreamMusic); interpreter.installSegment5 (opcodePlaySound, new OpPlaySound); interpreter.installSegment5 (opcodePlaySoundVP, new OpPlaySoundVP); - interpreter.installSegment5 (opcodePlaySound3D, new OpPlaySound3D (false)); - interpreter.installSegment5 (opcodePlaySound3DVP, new OpPlaySoundVP3D (false)); - interpreter.installSegment5 (opcodePlayLoopSound3D, new OpPlaySound3D (true)); - interpreter.installSegment5 (opcodePlayLoopSound3DVP, new OpPlaySoundVP3D (true)); - interpreter.installSegment5 (opcodeStopSound, new OpStopSound); - interpreter.installSegment5 (opcodeGetSoundPlaying, new OpGetSoundPlaying); - - interpreter.installSegment5 (opcodeSayExplicit, new OpSayExplicit); - interpreter.installSegment5 (opcodeSayDoneExplicit, new OpSayDoneExplicit); - interpreter.installSegment5 (opcodePlaySound3DExplicit, - new OpPlaySound3DExplicit (false)); - interpreter.installSegment5 (opcodePlaySound3DVPExplicit, - new OpPlaySoundVP3DExplicit (false)); - interpreter.installSegment5 (opcodePlayLoopSound3DExplicit, - new OpPlaySound3DExplicit (true)); - interpreter.installSegment5 (opcodePlayLoopSound3DVPExplicit, - new OpPlaySoundVP3DExplicit (true)); - interpreter.installSegment5 (opcodeStopSoundExplicit, new OpStopSoundExplicit); - interpreter.installSegment5 (opcodeGetSoundPlayingExplicit, - new OpGetSoundPlayingExplicit); - } - } -} + interpreter.installSegment5 (opcodePlaySound3D, new OpPlaySound3D (false)); + interpreter.installSegment5 (opcodePlaySound3DVP, new OpPlaySoundVP3D (false)); + interpreter.installSegment5 (opcodePlayLoopSound3D, new OpPlaySound3D (true)); + interpreter.installSegment5 (opcodePlayLoopSound3DVP, + new OpPlaySoundVP3D (true)); + interpreter.installSegment5 (opcodeStopSound, new OpStopSound); + interpreter.installSegment5 (opcodeGetSoundPlaying, new OpGetSoundPlaying); + interpreter.installSegment5 (opcodeSayExplicit, new OpSay); + interpreter.installSegment5 (opcodeSayDoneExplicit, new OpSayDone); + interpreter.installSegment5 (opcodePlaySound3DExplicit, + new OpPlaySound3D (false)); + interpreter.installSegment5 (opcodePlaySound3DVPExplicit, + new OpPlaySoundVP3D (false)); + interpreter.installSegment5 (opcodePlayLoopSound3DExplicit, + new OpPlaySound3D (true)); + interpreter.installSegment5 (opcodePlayLoopSound3DVPExplicit, + new OpPlaySoundVP3D (true)); + interpreter.installSegment5 (opcodeStopSoundExplicit, new OpStopSound); + interpreter.installSegment5 (opcodeGetSoundPlayingExplicit, + new OpGetSoundPlaying); + } + } +} diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 17635667c..ca82830d9 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -12,11 +12,13 @@ #include "../mwmechanics/creaturestats.hpp" #include "interpretercontext.hpp" +#include "ref.hpp" namespace MWScript { namespace Stats { + template class OpGetAttribute : public Interpreter::Opcode0 { int mIndex; @@ -27,36 +29,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - MWWorld::Ptr ptr = context.getReference(); - - Interpreter::Type_Integer value = - MWWorld::Class::get (ptr).getCreatureStats (ptr).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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. @@ -66,6 +39,7 @@ namespace MWScript } }; + template class OpSetAttribute : public Interpreter::Opcode0 { int mIndex; @@ -76,45 +50,17 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Ptr ptr = context.getReference(); - - MWWorld::Class::get (ptr).getCreatureStats (ptr).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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. setModified (value, 0); } }; + template class OpModAttribute : public Interpreter::Opcode0 { int mIndex; @@ -125,14 +71,11 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Ptr ptr = context.getReference(); - value += MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. getModified(); @@ -141,36 +84,7 @@ namespace MWScript } }; - 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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - - value += - MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. - getModified(); - - MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. - setModified (value, 0, 100); - } - }; - + template class OpGetDynamic : public Interpreter::Opcode0 { int mIndex; @@ -181,46 +95,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - MWWorld::Ptr ptr = context.getReference(); - - if (mIndex==0 && MWWorld::Class::get (ptr).hasItemHealth (ptr)) - { - // health is a special case - Interpreter::Type_Integer value = - MWWorld::Class::get (ptr).getItemMaxHealth (ptr); - runtime.push (value); - - return; - } - - Interpreter::Type_Integer value = - MWWorld::Class::get (ptr).getCreatureStats (ptr).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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWWorld::Ptr ptr = R()(runtime); if (mIndex==0 && MWWorld::Class::get (ptr).hasItemHealth (ptr)) { @@ -240,6 +115,7 @@ namespace MWScript } }; + template class OpSetDynamic : public Interpreter::Opcode0 { int mIndex; @@ -250,45 +126,17 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Ptr ptr = context.getReference(); - - MWWorld::Class::get (ptr).getCreatureStats (ptr).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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - MWWorld::Class::get (ptr).getCreatureStats (ptr).mDynamic[mIndex]. setModified (value, 0); } }; + template class OpModDynamic : public Interpreter::Opcode0 { int mIndex; @@ -299,14 +147,11 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer diff = runtime[0].mInteger; runtime.pop(); - MWWorld::Ptr ptr = context.getReference(); - MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); @@ -318,40 +163,7 @@ namespace MWScript } }; - 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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - - MWMechanics::CreatureStats& stats = - MWWorld::Class::get (ptr).getCreatureStats (ptr); - - Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); - - stats.mDynamic[mIndex].setModified ( - diff + stats.mDynamic[mIndex].getModified(), 0); - - stats.mDynamic[mIndex].setCurrent (diff + current); - } - }; - - + template class OpModCurrentDynamic : public Interpreter::Opcode0 { int mIndex; @@ -362,14 +174,11 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer diff = runtime[0].mInteger; runtime.pop(); - MWWorld::Ptr ptr = context.getReference(); - MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); @@ -378,36 +187,7 @@ namespace MWScript } }; - 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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - - MWMechanics::CreatureStats& stats = - MWWorld::Class::get (ptr).getCreatureStats (ptr); - - Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); - - stats.mDynamic[mIndex].setCurrent (diff + current); - } - }; - + template class OpGetDynamicGetRatio : public Interpreter::Opcode0 { int mIndex; @@ -418,10 +198,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - MWWorld::Ptr ptr = context.getReference(); + MWWorld::Ptr ptr = R()(runtime); MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); @@ -436,38 +213,7 @@ namespace MWScript } }; - 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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - - MWMechanics::CreatureStats& stats = - MWWorld::Class::get (ptr).getCreatureStats (ptr); - - 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); - } - }; - + template class OpGetSkill : public Interpreter::Opcode0 { int mIndex; @@ -478,36 +224,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - MWWorld::Ptr ptr = context.getReference(); - - Interpreter::Type_Integer value = - MWWorld::Class::get (ptr).getNpcStats (ptr).mSkill[mIndex]. - getModified(); - - runtime.push (value); - } - }; - - class OpGetSkillExplicit : public Interpreter::Opcode0 - { - int mIndex; - - public: - - OpGetSkillExplicit (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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = MWWorld::Class::get (ptr).getNpcStats (ptr).mSkill[mIndex]. @@ -517,6 +234,7 @@ namespace MWScript } }; + template class OpSetSkill : public Interpreter::Opcode0 { int mIndex; @@ -527,45 +245,17 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Ptr ptr = context.getReference(); - - MWWorld::Class::get (ptr).getNpcStats (ptr).mSkill[mIndex]. - setModified (value, 0); - } - }; - - class OpSetSkillExplicit : public Interpreter::Opcode0 - { - int mIndex; - - public: - - OpSetSkillExplicit (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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - MWWorld::Class::get (ptr).getNpcStats (ptr).mSkill[mIndex]. setModified (value, 0); } }; + template class OpModSkill : public Interpreter::Opcode0 { int mIndex; @@ -576,14 +266,11 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Ptr ptr = context.getReference(); - value += MWWorld::Class::get (ptr).getNpcStats (ptr).mSkill[mIndex]. getModified(); @@ -592,36 +279,6 @@ namespace MWScript } }; - class OpModSkillExplicit : public Interpreter::Opcode0 - { - int mIndex; - - public: - - OpModSkillExplicit (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(); - - MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); - - value += - MWWorld::Class::get (ptr).getNpcStats (ptr).mSkill[mIndex]. - getModified(); - - MWWorld::Class::get (ptr).getNpcStats (ptr).mSkill[mIndex]. - setModified (value, 0, 100); - } - }; - const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -729,53 +386,54 @@ namespace MWScript { for (int i=0; i (i)); interpreter.installSegment5 (opcodeGetAttributeExplicit+i, - new OpGetAttributeExplicit (i)); + new OpGetAttribute (i)); - interpreter.installSegment5 (opcodeSetAttribute+i, new OpSetAttribute (i)); + interpreter.installSegment5 (opcodeSetAttribute+i, new OpSetAttribute (i)); interpreter.installSegment5 (opcodeSetAttributeExplicit+i, - new OpSetAttributeExplicit (i)); + new OpSetAttribute (i)); - interpreter.installSegment5 (opcodeModAttribute+i, new OpModAttribute (i)); + interpreter.installSegment5 (opcodeModAttribute+i, new OpModAttribute (i)); interpreter.installSegment5 (opcodeModAttributeExplicit+i, - new OpModAttributeExplicit (i)); + new OpModAttribute (i)); } for (int i=0; i (i)); interpreter.installSegment5 (opcodeGetDynamicExplicit+i, - new OpGetDynamicExplicit (i)); + new OpGetDynamic (i)); - interpreter.installSegment5 (opcodeSetDynamic+i, new OpSetDynamic (i)); + interpreter.installSegment5 (opcodeSetDynamic+i, new OpSetDynamic (i)); interpreter.installSegment5 (opcodeSetDynamicExplicit+i, - new OpSetDynamicExplicit (i)); + new OpSetDynamic (i)); - interpreter.installSegment5 (opcodeModDynamic+i, new OpModDynamic (i)); + interpreter.installSegment5 (opcodeModDynamic+i, new OpModDynamic (i)); interpreter.installSegment5 (opcodeModDynamicExplicit+i, - new OpModDynamicExplicit (i)); + new OpModDynamic (i)); - interpreter.installSegment5 (opcodeModCurrentDynamic+i, new OpModCurrentDynamic (i)); + interpreter.installSegment5 (opcodeModCurrentDynamic+i, + new OpModCurrentDynamic (i)); interpreter.installSegment5 (opcodeModCurrentDynamicExplicit+i, - new OpModCurrentDynamicExplicit (i)); + new OpModCurrentDynamic (i)); interpreter.installSegment5 (opcodeGetDynamicGetRatio+i, - new OpGetDynamicGetRatio (i)); + new OpGetDynamicGetRatio (i)); interpreter.installSegment5 (opcodeGetDynamicGetRatioExplicit+i, - new OpGetDynamicGetRatioExplicit (i)); + new OpGetDynamicGetRatio (i)); } for (int i=0; i (i)); + interpreter.installSegment5 (opcodeGetSkillExplicit+i, new OpGetSkill (i)); - interpreter.installSegment5 (opcodeSetSkill+i, new OpSetSkill (i)); - interpreter.installSegment5 (opcodeSetSkillExplicit+i, new OpSetSkillExplicit (i)); + interpreter.installSegment5 (opcodeSetSkill+i, new OpSetSkill (i)); + interpreter.installSegment5 (opcodeSetSkillExplicit+i, new OpSetSkill (i)); - interpreter.installSegment5 (opcodeModSkill+i, new OpModSkill (i)); - interpreter.installSegment5 (opcodeModSkillExplicit+i, new OpModSkillExplicit (i)); + interpreter.installSegment5 (opcodeModSkill+i, new OpModSkill (i)); + interpreter.installSegment5 (opcodeModSkillExplicit+i, new OpModSkill (i)); } } } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp new file mode 100644 index 000000000..cc7abccac --- /dev/null +++ b/apps/openmw/mwworld/player.cpp @@ -0,0 +1,64 @@ + +#include "player.hpp" + +#include "../mwrender/player.hpp" + +#include "world.hpp" + +namespace MWWorld +{ + Player::Player (MWRender::Player *renderer, const ESM::NPC *player, MWWorld::World& world) : + mCellStore (0), mRenderer (renderer), mWorld (world), mClass (0), mCollisionMode (true) + { + mPlayer.base = player; + mName = player->name; + mMale = !(player->flags & ESM::NPC::Female); + mRace = player->race; + mPlayer.ref.pos.pos[0] = mPlayer.ref.pos.pos[1] = mPlayer.ref.pos.pos[2] = 0; + mClass = new ESM::Class (*world.getStore().classes.find (player->cls)); + } + + Player::~Player() + { + delete mClass; + } + + void Player::setPos(float x, float y, float z, bool updateCamera) + { + mWorld.moveObject (getPlayer(), x, y, z); + + if (updateCamera) + mRenderer->getCamera()->setPosition (Ogre::Vector3 ( + mPlayer.ref.pos.pos[0], + mPlayer.ref.pos.pos[2], + -mPlayer.ref.pos.pos[1])); + } + + void Player::moveRel (float &relX, float &relY, float &relZ) + { + // Move camera relative to its own direction + mRenderer->getCamera()->moveRelative (Ogre::Vector3(relX,0,relZ)); + + // Up/down movement is always done relative the world axis. + mRenderer->getCamera()->move (Ogre::Vector3(0,relY,0)); + + // Get new camera position, converting back to MW coords. + Ogre::Vector3 pos = mRenderer->getCamera()->getPosition(); + relX = pos[0]; + relY = -pos[2]; + relZ = pos[1]; + + // TODO: Collision detection must be used to find the REAL new + // position, if mCollisionMode==true + + // Set the position + setPos(relX, relY, relZ); + } + + void Player::setClass (const ESM::Class& class_) + { + ESM::Class *new_class = new ESM::Class (class_); + delete mClass; + mClass = new_class; + } +} diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp new file mode 100644 index 000000000..b54afad56 --- /dev/null +++ b/apps/openmw/mwworld/player.hpp @@ -0,0 +1,113 @@ +#ifndef GAME_MWWORLD_PLAYER_H +#define GAME_MWWORLD_PLAYER_H + +#include "OgreCamera.h" + +#include + +#include "../mwworld/refdata.hpp" +#include "../mwworld/ptr.hpp" + +namespace MWRender +{ + class Player; +} + +namespace MWWorld +{ + class World; + + /// \brief NPC object representing the player and additional player data + class Player + { + ESMS::LiveCellRef mPlayer; + MWWorld::Ptr::CellStore *mCellStore; + MWRender::Player *mRenderer; + MWWorld::World& mWorld; + std::string mName; + bool mMale; + std::string mRace; + std::string mBirthsign; + ESM::Class *mClass; + bool mCollisionMode; + + public: + + Player(MWRender::Player *renderer, const ESM::NPC *player, MWWorld::World& world); + + ~Player(); + + /// Set the player position. Uses Morrowind coordinates. + void setPos(float _x, float _y, float _z, bool updateCamera = false); + + void setCell (MWWorld::Ptr::CellStore *cellStore) + { + mCellStore = cellStore; + } + + /// Move the player relative to her own position and + /// orientation. After the call, the new position is returned. + void moveRel (float &relX, float &relY, float &relZ); + + MWWorld::Ptr getPlayer() + { + MWWorld::Ptr ptr (&mPlayer, mCellStore); + return ptr; + } + + MWRender::Player *getRenderer() { return mRenderer; } + + void setName (const std::string& name) + { + mName = name; + } + + void setGender (bool male) + { + mMale = male; + } + + void setRace (const std::string& race) + { + mRace = race; + } + + void setBirthsign (const std::string& birthsign) + { + mBirthsign = birthsign; + } + + void setClass (const ESM::Class& class_); + + std::string getName() const + { + return mName; + } + + bool isMale() const + { + return mMale; + } + + std::string getRace() const + { + return mRace; + } + + std::string getBirthsign() const + { + return mBirthsign; + } + + const ESM::Class& getClass() const + { + return *mClass; + } + + void setCollisionMode (bool enable) + { + mCollisionMode = enable; + } + }; +} +#endif diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 445455443..8dfc8c966 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -17,7 +17,7 @@ #include "ptr.hpp" #include "environment.hpp" #include "class.hpp" - +#include "player.hpp" #include "refdata.hpp" #include "globals.hpp" @@ -296,12 +296,12 @@ namespace MWWorld void World::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position) { - mPlayerPos->setPos (position.pos[0], position.pos[1], position.pos[2], true); - mPlayerPos->setCell (cell); + mPlayer->setPos (position.pos[0], position.pos[1], position.pos[2], true); + mPlayer->setCell (cell); // TODO orientation - mEnvironment.mMechanicsManager->addActor (mPlayerPos->getPlayer()); - mEnvironment.mMechanicsManager->watchActor (mPlayerPos->getPlayer()); + mEnvironment.mMechanicsManager->addActor (mPlayer->getPlayer()); + mEnvironment.mMechanicsManager->watchActor (mPlayer->getPlayer()); } @@ -317,7 +317,7 @@ namespace MWWorld World::World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir, const std::string& master, bool newGame, Environment& environment) - : mSkyManager (0), mScene (renderer), mPlayerPos (0), mCurrentCell (0), mGlobalVariables (0), + : mSkyManager (0), mScene (renderer), mPlayer (0), mCurrentCell (0), mGlobalVariables (0), mSky (false), mCellChanged (false), mEnvironment (environment) { boost::filesystem::path masterPath (dataDir); @@ -329,7 +329,7 @@ namespace MWWorld mEsm.open (masterPath.file_string()); mStore.load (mEsm); - mPlayerPos = new MWRender::PlayerPos (mScene.getCamera(), mStore.npcs.find ("player"), *this); + mPlayer = new MWWorld::Player (mScene.getPlayer(), mStore.npcs.find ("player"), *this); // global variables mGlobalVariables = new Globals (mStore); @@ -354,14 +354,14 @@ namespace MWWorld iter!=mBufferedCells.end(); ++iter) delete iter->second; - delete mPlayerPos; + delete mPlayer; delete mSkyManager; delete mGlobalVariables; } - MWRender::PlayerPos& World::getPlayerPos() + MWWorld::Player& World::getPlayer() { - return *mPlayerPos; + return *mPlayer; } ESMS::ESMStore& World::getStore() @@ -394,7 +394,7 @@ namespace MWWorld // the player is always in an active cell. if (name=="player") { - return mPlayerPos->getPlayer(); + return mPlayer->getPlayer(); } // active cells @@ -763,7 +763,7 @@ namespace MWWorld ptr.getCellRef().pos.pos[1] = y; ptr.getCellRef().pos.pos[2] = z; - if (ptr==mPlayerPos->getPlayer()) + if (ptr==mPlayer->getPlayer()) { if (mCurrentCell) { @@ -777,7 +777,7 @@ namespace MWWorld if (mCurrentCell->cell->data.gridX!=cellX || mCurrentCell->cell->data.gridY!=cellY) { - changeCell (cellX, cellY, mPlayerPos->getPlayer().getCellRef().pos); + changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos); } } } @@ -800,8 +800,6 @@ namespace MWWorld } } - - void World::positionToIndex (float x, float y, int &cellX, int &cellY) const { const int cellSize = 8192; diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 832d10b88..4e9e32ecc 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -8,7 +8,6 @@ #include -#include "../mwrender/playerpos.hpp" #include "../mwrender/mwscene.hpp" #include "refdata.hpp" @@ -34,12 +33,13 @@ namespace MWRender namespace MWWorld { class Environment; + class Player; /// \brief The game world and its visual representation class World { - + public: typedef std::list > ScriptList; @@ -49,7 +49,7 @@ namespace MWWorld MWRender::SkyManager* mSkyManager; MWRender::MWScene mScene; - MWRender::PlayerPos *mPlayerPos; + MWWorld::Player *mPlayer; Ptr::CellStore *mCurrentCell; // the cell, the player is in CellRenderCollection mActiveCells; CellRenderCollection mBufferedCells; // loaded, but not active (buffering not implementd yet) @@ -94,7 +94,7 @@ namespace MWWorld ~World(); - MWRender::PlayerPos& getPlayerPos(); + MWWorld::Player& getPlayer(); ESMS::ESMStore& getStore();