forked from mirror/openmw-tes3mp
Merge branch 'movement' of git://github.com/zinnschlag/openmw.git into collisions
This commit is contained in:
commit
1dc452ec91
48 changed files with 578 additions and 235 deletions
|
@ -145,6 +145,7 @@ set(GAMEWORLD_HEADER
|
||||||
mwworld/containerutil.hpp
|
mwworld/containerutil.hpp
|
||||||
mwworld/player.hpp
|
mwworld/player.hpp
|
||||||
mwworld/doingphysics.hpp
|
mwworld/doingphysics.hpp
|
||||||
|
mwworld/cellfunctors.hpp
|
||||||
)
|
)
|
||||||
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
|
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
|
||||||
|
|
||||||
|
@ -206,6 +207,7 @@ set(GAMEMECHANICS_HEADER
|
||||||
mwmechanics/stat.hpp
|
mwmechanics/stat.hpp
|
||||||
mwmechanics/creaturestats.hpp
|
mwmechanics/creaturestats.hpp
|
||||||
mwmechanics/magiceffects.hpp
|
mwmechanics/magiceffects.hpp
|
||||||
|
mwmechanics/movement.hpp
|
||||||
)
|
)
|
||||||
source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER})
|
source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER})
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
#include "components/esm/records.hpp"
|
#include "components/esm/records.hpp"
|
||||||
#include <components/esm_store/cell_store.hpp>
|
#include <components/esm_store/cell_store.hpp>
|
||||||
#include <components/misc/fileops.hpp>
|
#include <components/misc/fileops.hpp>
|
||||||
|
@ -158,7 +160,8 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
|
||||||
mEnvironment.mWorld->markCellAsUnchanged();
|
mEnvironment.mWorld->markCellAsUnchanged();
|
||||||
|
|
||||||
// update actors
|
// update actors
|
||||||
mEnvironment.mMechanicsManager->update();
|
std::vector<std::pair<std::string, Ogre::Vector3> > movement;
|
||||||
|
mEnvironment.mMechanicsManager->update (movement);
|
||||||
|
|
||||||
if (focusFrameCounter++ == focusUpdateFrame)
|
if (focusFrameCounter++ == focusUpdateFrame)
|
||||||
{
|
{
|
||||||
|
@ -179,6 +182,8 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
|
||||||
|
|
||||||
focusFrameCounter = 0;
|
focusFrameCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -388,7 +393,7 @@ void OMW::Engine::go()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pos.pos[0] = pos.pos[1] = 0;
|
pos.pos[0] = pos.pos[1] = 0;
|
||||||
mEnvironment.mWorld->changeCell (mCellName, pos);
|
mEnvironment.mWorld->changeToInteriorCell (mCellName, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up the input system
|
// Sets up the input system
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertActorPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace MWClass
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
|
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
|
|
||||||
// Extract the color and convert to floating point
|
// Extract the color and convert to floating point
|
||||||
const int color = ref->base->data.color;
|
const int color = ref->base->data.color;
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,8 +256,9 @@ namespace MWClass
|
||||||
cellRender.insertMesh (headModel, Ogre::Vector3( 0, 0, 5), axis, Ogre::Radian(0), npcName + "head", neckandup, neckNumbers);
|
cellRender.insertMesh (headModel, Ogre::Vector3( 0, 0, 5), axis, Ogre::Radian(0), npcName + "head", neckandup, neckNumbers);
|
||||||
neckandup[neckNumbers++] = npcName + "head";
|
neckandup[neckNumbers++] = npcName + "head";
|
||||||
cellRender.insertMesh (hairModel, Ogre::Vector3( 0, -1, 0), axis, Ogre::Radian(0), npcName + "hair", neckandup, neckNumbers);
|
cellRender.insertMesh (hairModel, Ogre::Vector3( 0, -1, 0), axis, Ogre::Radian(0), npcName + "hair", neckandup, neckNumbers);
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
|
||||||
|
|
||||||
|
cellRender.insertActorPhysics();
|
||||||
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Npc::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
|
void Npc::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
|
||||||
|
@ -392,7 +393,8 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
case Run:
|
case Run:
|
||||||
|
|
||||||
throw std::runtime_error ("run stance not manually setable for NPCs");
|
stats.mRun = set;
|
||||||
|
break;
|
||||||
|
|
||||||
case Sneak:
|
case Sneak:
|
||||||
|
|
||||||
|
@ -414,7 +416,10 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
case Run:
|
case Run:
|
||||||
|
|
||||||
return ignoreForce ? false : stats.mForceRun;
|
if (!ignoreForce && stats.mForceRun)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return stats.mRun;
|
||||||
|
|
||||||
case Sneak:
|
case Sneak:
|
||||||
|
|
||||||
|
@ -436,6 +441,35 @@ namespace MWClass
|
||||||
return getStance (ptr, Run) ? 600 : 300; // TODO calculate these values from stats
|
return getStance (ptr, Run) ? 600 : 300; // TODO calculate these values from stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
if (!ptr.getRefData().getMovement().get())
|
||||||
|
{
|
||||||
|
boost::shared_ptr<MWMechanics::Movement> movement (
|
||||||
|
new MWMechanics::Movement);
|
||||||
|
|
||||||
|
ptr.getRefData().getMovement() = movement;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *ptr.getRefData().getMovement();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
Ogre::Vector3 vector (0, 0, 0);
|
||||||
|
|
||||||
|
if (ptr.getRefData().getMovement().get())
|
||||||
|
{
|
||||||
|
vector.x = - ptr.getRefData().getMovement()->mLeftRight * 200;
|
||||||
|
vector.z = - ptr.getRefData().getMovement()->mForwardBackward * 200;
|
||||||
|
|
||||||
|
if (getStance (ptr, Run, false))
|
||||||
|
vector *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
|
|
||||||
void Npc::registerSelf()
|
void Npc::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Npc);
|
boost::shared_ptr<Class> instance (new Npc);
|
||||||
|
|
|
@ -56,6 +56,13 @@ namespace MWClass
|
||||||
virtual float getSpeed (const MWWorld::Ptr& ptr) const;
|
virtual float getSpeed (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return movement speed.
|
///< Return movement speed.
|
||||||
|
|
||||||
|
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return desired movement.
|
||||||
|
|
||||||
|
virtual Ogre::Vector3 getMovementVector (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return desired movement vector (determined based on movement settings,
|
||||||
|
/// stance and stats).
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||||
cellRender.insertMesh ("meshes\\" + model);
|
cellRender.insertMesh ("meshes\\" + model);
|
||||||
|
cellRender.insertObjectPhysics();
|
||||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,6 @@ namespace MWInput
|
||||||
|
|
||||||
A_MoveLeft, // Move player left / right
|
A_MoveLeft, // Move player left / right
|
||||||
A_MoveRight,
|
A_MoveRight,
|
||||||
A_MoveUp, // Move up / down
|
|
||||||
A_MoveDown,
|
|
||||||
A_MoveForward, // Forward / Backward
|
A_MoveForward, // Forward / Backward
|
||||||
A_MoveBackward,
|
A_MoveBackward,
|
||||||
|
|
||||||
|
@ -143,17 +141,12 @@ namespace MWInput
|
||||||
|
|
||||||
void toggleAutoMove()
|
void toggleAutoMove()
|
||||||
{
|
{
|
||||||
if (player.getAutoMove() == false)
|
player.setAutoMove (!player.getAutoMove());
|
||||||
{
|
|
||||||
player.setAutoMove(true);
|
|
||||||
} else {
|
|
||||||
player.setAutoMove(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleWalking()
|
void toggleWalking()
|
||||||
{
|
{
|
||||||
player.setisWalking(true);
|
player.toggleRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit program now button (which is disabled in GUI mode)
|
// Exit program now button (which is disabled in GUI mode)
|
||||||
|
@ -262,10 +255,6 @@ namespace MWInput
|
||||||
poller.bind(A_MoveRight, KC_D);
|
poller.bind(A_MoveRight, KC_D);
|
||||||
poller.bind(A_MoveForward, KC_W);
|
poller.bind(A_MoveForward, KC_W);
|
||||||
poller.bind(A_MoveBackward, KC_S);
|
poller.bind(A_MoveBackward, KC_S);
|
||||||
|
|
||||||
// Use shift and ctrl for up and down
|
|
||||||
poller.bind(A_MoveUp, KC_LSHIFT);
|
|
||||||
poller.bind(A_MoveDown, KC_LCONTROL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: Used to check for movement keys
|
//NOTE: Used to check for movement keys
|
||||||
|
@ -285,48 +274,33 @@ namespace MWInput
|
||||||
// Disable movement in Gui mode
|
// Disable movement in Gui mode
|
||||||
if (windows.isGuiMode()) return true;
|
if (windows.isGuiMode()) return true;
|
||||||
|
|
||||||
float speed = 300 * evt.timeSinceLastFrame; //placeholder player speed?
|
// Configure player movement according to keyboard input. Actual movement will
|
||||||
//float TESTwalkSpeed = 100 * evt.timeSinceLastFrame; //How about another?
|
// be done in the physics system.
|
||||||
|
|
||||||
float moveX = 0, moveY = 0, moveZ = 0;
|
|
||||||
|
|
||||||
//execute Automove - condition checked in function
|
|
||||||
player.executeAutoMove((float)evt.timeSinceLastFrame); //or since last frame?
|
|
||||||
|
|
||||||
//Poll and execute movement keys - will disable automove if pressed.
|
|
||||||
if (poller.isDown(A_MoveLeft))
|
if (poller.isDown(A_MoveLeft))
|
||||||
{
|
{
|
||||||
player.setAutoMove (false);
|
player.setAutoMove (false);
|
||||||
moveX -= speed;
|
player.setLeftRight (1);
|
||||||
}
|
}
|
||||||
|
else if (poller.isDown(A_MoveRight))
|
||||||
if(poller.isDown(A_MoveRight))
|
|
||||||
{
|
{
|
||||||
player.setAutoMove (false);
|
player.setAutoMove (false);
|
||||||
moveX += speed;
|
player.setLeftRight (-1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
player.setLeftRight (0);
|
||||||
|
|
||||||
if (poller.isDown(A_MoveForward))
|
if (poller.isDown(A_MoveForward))
|
||||||
{
|
{
|
||||||
player.setAutoMove (false);
|
player.setAutoMove (false);
|
||||||
moveZ -= speed;
|
player.setForwardBackward (1);
|
||||||
}
|
}
|
||||||
|
else if (poller.isDown(A_MoveBackward))
|
||||||
if(poller.isDown(A_MoveBackward))
|
|
||||||
{
|
{
|
||||||
player.setAutoMove (false);
|
player.setAutoMove (false);
|
||||||
moveZ += speed;
|
player.setForwardBackward (-1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
player.setForwardBackward (0);
|
||||||
// TODO: These should be enabled for floating modes (like
|
|
||||||
// swimming and levitation) and disabled for everything else.
|
|
||||||
if(poller.isDown(A_MoveUp)) moveY += speed;
|
|
||||||
if(poller.isDown(A_MoveDown)) moveY -= speed;
|
|
||||||
|
|
||||||
if(moveX != 0 || moveY != 0 || moveZ != 0)
|
|
||||||
player.moveRel(moveX, moveY, moveZ);
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,11 +234,17 @@ namespace MWMechanics
|
||||||
|
|
||||||
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
|
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
|
if (ptr==mWatched)
|
||||||
|
mWatched = MWWorld::Ptr();
|
||||||
|
|
||||||
mActors.erase (ptr);
|
mActors.erase (ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
||||||
{
|
{
|
||||||
|
if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
|
||||||
|
mWatched = MWWorld::Ptr();
|
||||||
|
|
||||||
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
|
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
|
||||||
|
|
||||||
while (iter!=mActors.end())
|
while (iter!=mActors.end())
|
||||||
|
@ -255,7 +261,7 @@ namespace MWMechanics
|
||||||
mWatched = ptr;
|
mWatched = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::update()
|
void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement)
|
||||||
{
|
{
|
||||||
if (!mWatched.isEmpty())
|
if (!mWatched.isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -350,6 +356,15 @@ namespace MWMechanics
|
||||||
|
|
||||||
mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills);
|
mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
|
||||||
|
|
||||||
|
if (vector!=Ogre::Vector3::ZERO)
|
||||||
|
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::setPlayerName (const std::string& name)
|
void MechanicsManager::setPlayerName (const std::string& name)
|
||||||
|
|
|
@ -2,12 +2,19 @@
|
||||||
#define GAME_MWMECHANICS_MECHANICSMANAGER_H
|
#define GAME_MWMECHANICS_MECHANICSMANAGER_H
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
#include "npcstats.hpp"
|
#include "npcstats.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Vector3;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
class Environment;
|
class Environment;
|
||||||
|
@ -53,8 +60,8 @@ namespace MWMechanics
|
||||||
///< On each update look for changes in a previously registered actor and update the
|
///< On each update look for changes in a previously registered actor and update the
|
||||||
/// GUI accordingly.
|
/// GUI accordingly.
|
||||||
|
|
||||||
void update();
|
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement);
|
||||||
///< Update actor stats
|
///< Update actor stats and store desired velocity vectors in \a movement
|
||||||
|
|
||||||
void setPlayerName (const std::string& name);
|
void setPlayerName (const std::string& name);
|
||||||
///< Set player name.
|
///< Set player name.
|
||||||
|
|
16
apps/openmw/mwmechanics/movement.hpp
Normal file
16
apps/openmw/mwmechanics/movement.hpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef GAME_MWMECHANICS_MOVEMENT_H
|
||||||
|
#define GAME_MWMECHANICS_MOVEMENT_H
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
/// Desired movement for an actor
|
||||||
|
struct Movement
|
||||||
|
{
|
||||||
|
signed char mLeftRight; // 1: wants to move left, -1: wants to move right
|
||||||
|
signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward
|
||||||
|
|
||||||
|
Movement() : mLeftRight (0), mForwardBackward (0) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,10 +21,12 @@ namespace MWMechanics
|
||||||
|
|
||||||
bool mForceRun;
|
bool mForceRun;
|
||||||
bool mForceSneak;
|
bool mForceSneak;
|
||||||
|
bool mRun;
|
||||||
bool mSneak;
|
bool mSneak;
|
||||||
bool mCombat;
|
bool mCombat;
|
||||||
|
|
||||||
NpcStats() : mForceRun (false), mForceSneak (false), mSneak (false), mCombat (false) {}
|
NpcStats() : mForceRun (false), mForceSneak (false), mRun (false), mSneak (false),
|
||||||
|
mCombat (false) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,9 @@ namespace MWRender
|
||||||
|
|
||||||
virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements) = 0;
|
virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements) = 0;
|
||||||
|
|
||||||
|
virtual void insertObjectPhysics() = 0;
|
||||||
|
|
||||||
|
virtual void insertActorPhysics() = 0;
|
||||||
|
|
||||||
/// insert a light related to the most recent insertBegin call.
|
/// insert a light related to the most recent insertBegin call.
|
||||||
virtual void insertLight(float r, float g, float b, float radius) = 0;
|
virtual void insertLight(float r, float g, float b, float radius) = 0;
|
||||||
|
|
|
@ -58,6 +58,8 @@ void ExteriorCellRender::insertBegin (ESM::CellRef &ref)
|
||||||
|
|
||||||
// Rotates first around z, then y, then x
|
// Rotates first around z, then y, then x
|
||||||
mInsert->setOrientation(xr*yr*zr);
|
mInsert->setOrientation(xr*yr*zr);
|
||||||
|
|
||||||
|
mInsertMesh.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -202,6 +204,22 @@ void ExteriorCellRender::insertMesh(const std::string &mesh)
|
||||||
NIFLoader::load(mesh);
|
NIFLoader::load(mesh);
|
||||||
MovableObject *ent = mScene.getMgr()->createEntity(mesh);
|
MovableObject *ent = mScene.getMgr()->createEntity(mesh);
|
||||||
mInsert->attachObject(ent);
|
mInsert->attachObject(ent);
|
||||||
|
|
||||||
|
if (mInsertMesh.empty())
|
||||||
|
mInsertMesh = mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExteriorCellRender::insertObjectPhysics()
|
||||||
|
{
|
||||||
|
if (!mInsertMesh.empty())
|
||||||
|
mScene.addObject (mInsert->getName(), mInsertMesh, mInsert->getOrientation(),
|
||||||
|
mInsert->getScale().x, mInsert->getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExteriorCellRender::insertActorPhysics()
|
||||||
|
{
|
||||||
|
if (!mInsertMesh.empty())
|
||||||
|
mScene.addActor (mInsert->getName(), mInsertMesh, mInsert->getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert a light related to the most recent insertBegin call.
|
// insert a light related to the most recent insertBegin call.
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace MWRender
|
||||||
Ogre::SceneNode *mBase;
|
Ogre::SceneNode *mBase;
|
||||||
|
|
||||||
Ogre::SceneNode *mInsert;
|
Ogre::SceneNode *mInsert;
|
||||||
|
std::string mInsertMesh;
|
||||||
Ogre::SceneNode *mNpcPart;
|
Ogre::SceneNode *mNpcPart;
|
||||||
|
|
||||||
// 0 normal, 1 more bright, 2 max
|
// 0 normal, 1 more bright, 2 max
|
||||||
|
@ -72,6 +73,10 @@ namespace MWRender
|
||||||
virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements);
|
virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements);
|
||||||
virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements);
|
virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements);
|
||||||
|
|
||||||
|
virtual void insertObjectPhysics();
|
||||||
|
|
||||||
|
virtual void insertActorPhysics();
|
||||||
|
|
||||||
/// insert a light related to the most recent insertBegin call.
|
/// insert a light related to the most recent insertBegin call.
|
||||||
virtual void insertLight(float r, float g, float b, float radius);
|
virtual void insertLight(float r, float g, float b, float radius);
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,8 @@ void InteriorCellRender::insertBegin (ESM::CellRef &ref)
|
||||||
|
|
||||||
// Rotates first around z, then y, then x
|
// Rotates first around z, then y, then x
|
||||||
insert->setOrientation(xr*yr*zr);
|
insert->setOrientation(xr*yr*zr);
|
||||||
|
|
||||||
|
mInsertMesh.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert a mesh related to the most recent insertBegin call.
|
// insert a mesh related to the most recent insertBegin call.
|
||||||
|
@ -185,6 +187,22 @@ void InteriorCellRender::insertMesh(const std::string &mesh)
|
||||||
NIFLoader::load(mesh);
|
NIFLoader::load(mesh);
|
||||||
MovableObject *ent = scene.getMgr()->createEntity(mesh);
|
MovableObject *ent = scene.getMgr()->createEntity(mesh);
|
||||||
insert->attachObject(ent);
|
insert->attachObject(ent);
|
||||||
|
|
||||||
|
if (mInsertMesh.empty())
|
||||||
|
mInsertMesh = mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InteriorCellRender::insertObjectPhysics()
|
||||||
|
{
|
||||||
|
if (!mInsertMesh.empty())
|
||||||
|
scene.addObject (insert->getName(), mInsertMesh, insert->getOrientation(),
|
||||||
|
insert->getScale().x, insert->getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InteriorCellRender::insertActorPhysics()
|
||||||
|
{
|
||||||
|
if (!mInsertMesh.empty())
|
||||||
|
scene.addActor (insert->getName(), mInsertMesh, insert->getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert a light related to the most recent insertBegin call.
|
// insert a light related to the most recent insertBegin call.
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace MWRender
|
||||||
Ogre::SceneNode *base;
|
Ogre::SceneNode *base;
|
||||||
|
|
||||||
Ogre::SceneNode *insert;
|
Ogre::SceneNode *insert;
|
||||||
|
std::string mInsertMesh;
|
||||||
Ogre::SceneNode *npcPart;
|
Ogre::SceneNode *npcPart;
|
||||||
|
|
||||||
// 0 normal, 1 more bright, 2 max
|
// 0 normal, 1 more bright, 2 max
|
||||||
|
@ -69,6 +70,11 @@ namespace MWRender
|
||||||
virtual void insertMesh(const std::string &mesh);
|
virtual void insertMesh(const std::string &mesh);
|
||||||
virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements);
|
virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements);
|
||||||
virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst);
|
virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst);
|
||||||
|
|
||||||
|
virtual void insertObjectPhysics();
|
||||||
|
|
||||||
|
virtual void insertActorPhysics();
|
||||||
|
|
||||||
/// insert a light related to the most recent insertBegin call.
|
/// insert a light related to the most recent insertBegin call.
|
||||||
virtual void insertLight(float r, float g, float b, float radius);
|
virtual void insertLight(float r, float g, float b, float radius);
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,10 @@ MWScene::MWScene(OEngine::Render::OgreRenderer &_rend)
|
||||||
//used to obtain ingame information of ogre objects (which are faced or selected)
|
//used to obtain ingame information of ogre objects (which are faced or selected)
|
||||||
mRaySceneQuery = rend.getScene()->createRayQuery(Ray());
|
mRaySceneQuery = rend.getScene()->createRayQuery(Ray());
|
||||||
|
|
||||||
mPlayer = new MWRender::Player (getCamera());
|
Ogre::SceneNode *playerNode = mwRoot->createChildSceneNode();
|
||||||
|
playerNode->attachObject (getCamera());
|
||||||
|
|
||||||
|
mPlayer = new MWRender::Player (getCamera(), playerNode->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
MWScene::~MWScene()
|
MWScene::~MWScene()
|
||||||
|
@ -99,16 +102,24 @@ std::pair<std::string, float> MWScene::getFacedHandle (MWWorld::World& world)
|
||||||
return std::pair<std::string, float>(handle, distance);
|
return std::pair<std::string, float>(handle, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWScene::doPhysics (float duration, MWWorld::World& world)
|
void MWScene::doPhysics (float duration, MWWorld::World& world,
|
||||||
|
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
|
||||||
{
|
{
|
||||||
// stop changes to world from being reported back to the physics system
|
// stop changes to world from being reported back to the physics system
|
||||||
MWWorld::DoingPhysics scopeGuard;
|
MWWorld::DoingPhysics scopeGuard;
|
||||||
|
|
||||||
}
|
// move object directly for now -> TODO replace with physics
|
||||||
|
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
|
||||||
void MWScene::setMovement (const std::vector<std::string, Ogre::Vector3>& actors)
|
iter!=actors.end(); ++iter)
|
||||||
{
|
{
|
||||||
|
MWWorld::Ptr ptr = world.getPtrViaHandle (iter->first);
|
||||||
|
|
||||||
|
Ogre::SceneNode *sceneNode = rend.getScene()->getSceneNode (iter->first);
|
||||||
|
|
||||||
|
Ogre::Vector3 newPos = sceneNode->getPosition() + sceneNode->getOrientation() * iter->second;
|
||||||
|
|
||||||
|
world.moveObject (ptr, newPos.x, newPos.y, newPos.z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWScene::addObject (const std::string& handle, const std::string& mesh,
|
void MWScene::addObject (const std::string& handle, const std::string& mesh,
|
||||||
|
@ -128,8 +139,9 @@ void MWScene::removeObject (const std::string& handle)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWScene::moveObject (const std::string& handle, const Ogre::Vector3& position)
|
void MWScene::moveObject (const std::string& handle, const Ogre::Vector3& position, bool updatePhysics)
|
||||||
{
|
{
|
||||||
|
rend.getScene()->getSceneNode (handle)->setPosition (position);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <openengine/ogre/renderer.hpp>
|
#include <openengine/ogre/renderer.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
|
@ -60,11 +61,8 @@ namespace MWRender
|
||||||
std::pair<std::string, float> getFacedHandle (MWWorld::World& world);
|
std::pair<std::string, float> getFacedHandle (MWWorld::World& world);
|
||||||
|
|
||||||
/// Run physics simulation and modify \a world accordingly.
|
/// Run physics simulation and modify \a world accordingly.
|
||||||
void doPhysics (float duration, MWWorld::World& world);
|
void doPhysics (float duration, MWWorld::World& world,
|
||||||
|
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
|
||||||
/// Inform phyiscs system about desired velocity vectors for actors
|
|
||||||
/// (in Morrowind coordinates).
|
|
||||||
void setMovement (const std::vector<std::string, Ogre::Vector3>& actors);
|
|
||||||
|
|
||||||
/// Add object to physics system.
|
/// Add object to physics system.
|
||||||
void addObject (const std::string& handle, const std::string& mesh,
|
void addObject (const std::string& handle, const std::string& mesh,
|
||||||
|
@ -78,7 +76,7 @@ namespace MWRender
|
||||||
void removeObject (const std::string& handle);
|
void removeObject (const std::string& handle);
|
||||||
|
|
||||||
/// Move object.
|
/// Move object.
|
||||||
void moveObject (const std::string& handle, const Ogre::Vector3& position);
|
void moveObject (const std::string& handle, const Ogre::Vector3& position, bool updatePhysics);
|
||||||
|
|
||||||
/// Change object's orientation.
|
/// Change object's orientation.
|
||||||
void rotateObject (const std::string& handle, const Ogre::Quaternion& rotation);
|
void rotateObject (const std::string& handle, const Ogre::Quaternion& rotation);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
Player::Player (Ogre::Camera *camera) : mCamera (camera)
|
Player::Player (Ogre::Camera *camera, const std::string& handle)
|
||||||
|
: mCamera (camera), mHandle (handle)
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef GAME_MWRENDER_PLAYER_H
|
#ifndef GAME_MWRENDER_PLAYER_H
|
||||||
#define GAME_MWRENDER_PLAYER_H
|
#define GAME_MWRENDER_PLAYER_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class Camera;
|
class Camera;
|
||||||
|
@ -12,12 +14,15 @@ namespace MWRender
|
||||||
class Player
|
class Player
|
||||||
{
|
{
|
||||||
Ogre::Camera *mCamera;
|
Ogre::Camera *mCamera;
|
||||||
|
std::string mHandle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Player (Ogre::Camera *camera);
|
Player (Ogre::Camera *camera, const std::string& handle);
|
||||||
|
|
||||||
Ogre::Camera *getCamera() { return mCamera; }
|
Ogre::Camera *getCamera() { return mCamera; }
|
||||||
|
|
||||||
|
std::string getHandle() const { return mHandle; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace MWScript
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pos.pos[0] = pos.pos[1] = 0;
|
pos.pos[0] = pos.pos[1] = 0;
|
||||||
context.getWorld().changeCell (cell, pos);
|
context.getWorld().changeToInteriorCell (cell, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,6 @@ namespace MWWorld
|
||||||
if (mCellName.empty())
|
if (mCellName.empty())
|
||||||
environment.mWorld->changeToExteriorCell (mPosition);
|
environment.mWorld->changeToExteriorCell (mPosition);
|
||||||
else
|
else
|
||||||
environment.mWorld->changeCell (mCellName, mPosition);
|
environment.mWorld->changeToInteriorCell (mCellName, mPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
31
apps/openmw/mwworld/cellfunctors.hpp
Normal file
31
apps/openmw/mwworld/cellfunctors.hpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef GAME_MWWORLD_CELLFUNCTORS_H
|
||||||
|
#define GAME_MWWORLD_CELLFUNCTORS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "refdata.hpp"
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class CellRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
/// List all (Ogre-)handles.
|
||||||
|
struct ListHandles
|
||||||
|
{
|
||||||
|
std::vector<std::string> mHandles;
|
||||||
|
|
||||||
|
bool operator() (ESM::CellRef& ref, RefData& data)
|
||||||
|
{
|
||||||
|
std::string handle = data.getHandle();
|
||||||
|
if (!handle.empty())
|
||||||
|
mHandles.push_back (handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
#include "ptr.hpp"
|
#include "ptr.hpp"
|
||||||
#include "nullaction.hpp"
|
#include "nullaction.hpp"
|
||||||
|
|
||||||
|
@ -112,6 +114,16 @@ namespace MWWorld
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error ("movement settings not supported by class");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 Class::getMovementVector (const Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return Ogre::Vector3 (0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
const Class& Class::get (const std::string& key)
|
const Class& Class::get (const std::string& key)
|
||||||
{
|
{
|
||||||
std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key);
|
std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key);
|
||||||
|
|
|
@ -10,6 +10,11 @@
|
||||||
#include "containerstore.hpp"
|
#include "containerstore.hpp"
|
||||||
#include "refdata.hpp"
|
#include "refdata.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Vector3;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class CellRenderImp;
|
class CellRenderImp;
|
||||||
|
@ -19,6 +24,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
struct CreatureStats;
|
struct CreatureStats;
|
||||||
struct NpcStats;
|
struct NpcStats;
|
||||||
|
struct Movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
|
@ -126,6 +132,13 @@ namespace MWWorld
|
||||||
virtual float getSpeed (const Ptr& ptr) const;
|
virtual float getSpeed (const Ptr& ptr) const;
|
||||||
///< Return movement speed.
|
///< Return movement speed.
|
||||||
|
|
||||||
|
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
|
||||||
|
///< Return desired movement.
|
||||||
|
|
||||||
|
virtual Ogre::Vector3 getMovementVector (const Ptr& ptr) const;
|
||||||
|
///< Return desired movement vector (determined based on movement settings,
|
||||||
|
/// stance and stats).
|
||||||
|
|
||||||
static const Class& get (const std::string& key);
|
static const Class& get (const std::string& key);
|
||||||
///< If there is no class for this \a key, an exception is thrown.
|
///< If there is no class for this \a key, an exception is thrown.
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
int DoingPhysics::sCounter = 0;
|
int DoingPhysics::sCounter = 0;
|
||||||
|
int DoingPhysics::sSuppress = 0;
|
||||||
|
|
||||||
DoingPhysics::DoingPhysics()
|
DoingPhysics::DoingPhysics()
|
||||||
{
|
{
|
||||||
|
@ -17,6 +18,16 @@ namespace MWWorld
|
||||||
|
|
||||||
bool DoingPhysics::isDoingPhysics()
|
bool DoingPhysics::isDoingPhysics()
|
||||||
{
|
{
|
||||||
return sCounter>0;
|
return sCounter>0 || sSuppress>0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SuppressDoingPhysics::SuppressDoingPhysics()
|
||||||
|
{
|
||||||
|
++DoingPhysics::sSuppress;
|
||||||
|
}
|
||||||
|
|
||||||
|
SuppressDoingPhysics::~SuppressDoingPhysics()
|
||||||
|
{
|
||||||
|
--DoingPhysics::sSuppress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,13 @@
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
///< Scope guard for blocking physics updates during physics simulation.
|
class SuppressDoingPhysics;
|
||||||
|
|
||||||
|
/// Scope guard for blocking physics updates during physics simulation.
|
||||||
class DoingPhysics
|
class DoingPhysics
|
||||||
{
|
{
|
||||||
static int sCounter;
|
static int sCounter;
|
||||||
|
static int sSuppress;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -20,6 +23,23 @@ namespace MWWorld
|
||||||
~DoingPhysics();
|
~DoingPhysics();
|
||||||
|
|
||||||
static bool isDoingPhysics();
|
static bool isDoingPhysics();
|
||||||
|
|
||||||
|
friend class SuppressDoingPhysics;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Scope guard for temporarily lifting the block issues by DoingPhysics
|
||||||
|
class SuppressDoingPhysics
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
SuppressDoingPhysics (const SuppressDoingPhysics&);
|
||||||
|
SuppressDoingPhysics& operator= (const SuppressDoingPhysics&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SuppressDoingPhysics();
|
||||||
|
|
||||||
|
~SuppressDoingPhysics();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,20 +4,21 @@
|
||||||
#include "../mwrender/player.hpp"
|
#include "../mwrender/player.hpp"
|
||||||
|
|
||||||
#include "world.hpp"
|
#include "world.hpp"
|
||||||
|
#include "class.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
Player::Player (MWRender::Player *renderer, const ESM::NPC *player, MWWorld::World& world) :
|
Player::Player (MWRender::Player *renderer, const ESM::NPC *player, MWWorld::World& world) :
|
||||||
mCellStore (0), mRenderer (renderer), mWorld (world), mClass (0), mCollisionMode (true)
|
mCellStore (0), mRenderer (renderer), mWorld (world), mClass (0), mCollisionMode (true),
|
||||||
|
mAutoMove (false), mForwardBackward (0)
|
||||||
{
|
{
|
||||||
mPlayer.base = player;
|
mPlayer.base = player;
|
||||||
mName = player->name;
|
mName = player->name;
|
||||||
mMale = !(player->flags & ESM::NPC::Female);
|
mMale = !(player->flags & ESM::NPC::Female);
|
||||||
mRace = player->race;
|
mRace = player->race;
|
||||||
mPlayer.ref.pos.pos[0] = mPlayer.ref.pos.pos[1] = mPlayer.ref.pos.pos[2] = 0;
|
mPlayer.ref.pos.pos[0] = mPlayer.ref.pos.pos[1] = mPlayer.ref.pos.pos[2] = 0;
|
||||||
|
mPlayer.mData.setHandle (renderer->getHandle());
|
||||||
mClass = new ESM::Class (*world.getStore().classes.find (player->cls));
|
mClass = new ESM::Class (*world.getStore().classes.find (player->cls));
|
||||||
mAutoMove = false;
|
|
||||||
misWalking = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Player::~Player()
|
Player::~Player()
|
||||||
|
@ -64,4 +65,45 @@ namespace MWWorld
|
||||||
mClass = new_class;
|
mClass = new_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::setAutoMove (bool enable)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
|
||||||
|
mAutoMove = enable;
|
||||||
|
|
||||||
|
int value = mForwardBackward;
|
||||||
|
|
||||||
|
if (mAutoMove)
|
||||||
|
value = 1;
|
||||||
|
|
||||||
|
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::setLeftRight (int value)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
|
||||||
|
MWWorld::Class::get (ptr).getMovementSettings (ptr).mLeftRight = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::setForwardBackward (int value)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
|
||||||
|
mForwardBackward = value;
|
||||||
|
|
||||||
|
if (mAutoMove)
|
||||||
|
value = 1;
|
||||||
|
|
||||||
|
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::toggleRunning()
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
|
||||||
|
bool running = MWWorld::Class::get (ptr).getStance (ptr, MWWorld::Class::Run, true);
|
||||||
|
|
||||||
|
MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Run, !running);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,8 @@ namespace MWWorld
|
||||||
std::string mBirthsign;
|
std::string mBirthsign;
|
||||||
ESM::Class *mClass;
|
ESM::Class *mClass;
|
||||||
bool mCollisionMode;
|
bool mCollisionMode;
|
||||||
|
|
||||||
bool mAutoMove;
|
bool mAutoMove;
|
||||||
bool misWalking;//Testing...
|
int mForwardBackward;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -117,33 +116,13 @@ namespace MWWorld
|
||||||
return mAutoMove;
|
return mAutoMove;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAutoMove(bool setMe)
|
void setAutoMove (bool enable);
|
||||||
{
|
|
||||||
mAutoMove = setMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
//NOTE: we don't have speed being calculated yet, so for now this function only requires a frame duration.
|
void setLeftRight (int value);
|
||||||
/// <param name="duration">float value representing time since last call</param>
|
|
||||||
void executeAutoMove(float duration)
|
|
||||||
{
|
|
||||||
float X_Val = 0.0f;
|
|
||||||
float Y_Val = 0.0f;
|
|
||||||
float Z_Val = 300.0f * duration * -1.0f;
|
|
||||||
if (mAutoMove == true)
|
|
||||||
{
|
|
||||||
moveRel(X_Val, Y_Val, Z_Val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getisWalking()
|
void setForwardBackward (int value);
|
||||||
{
|
|
||||||
return misWalking;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setisWalking(bool setMe)
|
void toggleRunning();
|
||||||
{
|
|
||||||
misWalking = setMe;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
#include "../mwmechanics/movement.hpp"
|
||||||
|
|
||||||
#include "containerstore.hpp"
|
#include "containerstore.hpp"
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ namespace MWWorld
|
||||||
// are never copied outside of container operations.
|
// are never copied outside of container operations.
|
||||||
boost::shared_ptr<MWMechanics::CreatureStats> mCreatureStats;
|
boost::shared_ptr<MWMechanics::CreatureStats> mCreatureStats;
|
||||||
boost::shared_ptr<MWMechanics::NpcStats> mNpcStats;
|
boost::shared_ptr<MWMechanics::NpcStats> mNpcStats;
|
||||||
|
boost::shared_ptr<MWMechanics::Movement> mMovement;
|
||||||
|
|
||||||
boost::shared_ptr<ContainerStore<RefData> > mContainerStore;
|
boost::shared_ptr<ContainerStore<RefData> > mContainerStore;
|
||||||
|
|
||||||
|
@ -102,6 +104,11 @@ namespace MWWorld
|
||||||
return mNpcStats;
|
return mNpcStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<MWMechanics::Movement>& getMovement()
|
||||||
|
{
|
||||||
|
return mMovement;
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<ContainerStore<RefData> >& getContainerStore()
|
boost::shared_ptr<ContainerStore<RefData> >& getContainerStore()
|
||||||
{
|
{
|
||||||
return mContainerStore;
|
return mContainerStore;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "refdata.hpp"
|
#include "refdata.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
#include "doingphysics.hpp"
|
#include "doingphysics.hpp"
|
||||||
|
#include "cellfunctors.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -271,6 +272,15 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::unloadCell (CellRenderCollection::iterator iter)
|
void World::unloadCell (CellRenderCollection::iterator iter)
|
||||||
{
|
{
|
||||||
|
ListHandles functor;
|
||||||
|
iter->first->forEach (functor);
|
||||||
|
|
||||||
|
{ // silence annoying g++ warning
|
||||||
|
for (std::vector<std::string>::const_iterator iter (functor.mHandles.begin());
|
||||||
|
iter!=functor.mHandles.end(); ++iter)
|
||||||
|
mScene.removeObject (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
removeScripts (iter->first);
|
removeScripts (iter->first);
|
||||||
mEnvironment.mMechanicsManager->dropActors (iter->first);
|
mEnvironment.mMechanicsManager->dropActors (iter->first);
|
||||||
iter->second->destroy();
|
iter->second->destroy();
|
||||||
|
@ -295,9 +305,12 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position)
|
void World::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
||||||
|
bool adjustPlayerPos)
|
||||||
{
|
{
|
||||||
|
if (adjustPlayerPos)
|
||||||
mPlayer->setPos (position.pos[0], position.pos[1], position.pos[2], true);
|
mPlayer->setPos (position.pos[0], position.pos[1], position.pos[2], true);
|
||||||
|
|
||||||
mPlayer->setCell (cell);
|
mPlayer->setCell (cell);
|
||||||
// TODO orientation
|
// TODO orientation
|
||||||
|
|
||||||
|
@ -316,8 +329,87 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos)
|
||||||
|
{
|
||||||
|
SuppressDoingPhysics scopeGuard;
|
||||||
|
|
||||||
|
// remove active
|
||||||
|
mEnvironment.mMechanicsManager->removeActor (mPlayer->getPlayer());
|
||||||
|
|
||||||
|
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||||
|
|
||||||
|
while (active!=mActiveCells.end())
|
||||||
|
{
|
||||||
|
if (!(active->first->cell->data.flags & ESM::Cell::Interior))
|
||||||
|
{
|
||||||
|
if (std::abs (X-active->first->cell->data.gridX)<=1 &&
|
||||||
|
std::abs (Y-active->first->cell->data.gridY)<=1)
|
||||||
|
{
|
||||||
|
// keep cells within the new 3x3 grid
|
||||||
|
++active;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unloadCell (active++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load cells
|
||||||
|
for (int x=X-1; x<=X+1; ++x)
|
||||||
|
for (int y=Y-1; y<=Y+1; ++y)
|
||||||
|
{
|
||||||
|
CellRenderCollection::iterator iter = mActiveCells.begin();
|
||||||
|
|
||||||
|
while (iter!=mActiveCells.end())
|
||||||
|
{
|
||||||
|
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
||||||
|
|
||||||
|
if (x==iter->first->cell->data.gridX &&
|
||||||
|
y==iter->first->cell->data.gridY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter==mActiveCells.end())
|
||||||
|
{
|
||||||
|
mExteriors[std::make_pair (x, y)].loadExt (x, y, mStore, mEsm);
|
||||||
|
Ptr::CellStore *cell = &mExteriors[std::make_pair (x, y)];
|
||||||
|
|
||||||
|
loadCell (cell, new MWRender::ExteriorCellRender (*cell, mEnvironment, mScene));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find current cell
|
||||||
|
CellRenderCollection::iterator iter = mActiveCells.begin();
|
||||||
|
|
||||||
|
while (iter!=mActiveCells.end())
|
||||||
|
{
|
||||||
|
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
||||||
|
|
||||||
|
if (X==iter->first->cell->data.gridX &&
|
||||||
|
Y==iter->first->cell->data.gridY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (iter!=mActiveCells.end());
|
||||||
|
|
||||||
|
mCurrentCell = iter->first;
|
||||||
|
|
||||||
|
// adjust player
|
||||||
|
playerCellChange (&mExteriors[std::make_pair (X, Y)], position, adjustPlayerPos);
|
||||||
|
|
||||||
|
// Sky system
|
||||||
|
adjustSky();
|
||||||
|
|
||||||
|
mCellChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
World::World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
World::World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
||||||
const std::string& master, const boost::filesystem::path& resDir, bool newGame, Environment& environment)
|
const std::string& master, const boost::filesystem::path& resDir,
|
||||||
|
bool newGame, Environment& environment)
|
||||||
: mSkyManager (0), mScene (renderer), mPlayer (0), mCurrentCell (0), mGlobalVariables (0),
|
: mSkyManager (0), mScene (renderer), mPlayer (0), mCurrentCell (0), mGlobalVariables (0),
|
||||||
mSky (false), mCellChanged (false), mEnvironment (environment)
|
mSky (false), mCellChanged (false), mEnvironment (environment)
|
||||||
{
|
{
|
||||||
|
@ -331,6 +423,7 @@ namespace MWWorld
|
||||||
mStore.load (mEsm);
|
mStore.load (mEsm);
|
||||||
|
|
||||||
mPlayer = new MWWorld::Player (mScene.getPlayer(), mStore.npcs.find ("player"), *this);
|
mPlayer = new MWWorld::Player (mScene.getPlayer(), mStore.npcs.find ("player"), *this);
|
||||||
|
mScene.addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0));
|
||||||
|
|
||||||
// global variables
|
// global variables
|
||||||
mGlobalVariables = new Globals (mStore);
|
mGlobalVariables = new Globals (mStore);
|
||||||
|
@ -418,7 +511,8 @@ namespace MWWorld
|
||||||
|
|
||||||
Ptr World::getPtrViaHandle (const std::string& handle)
|
Ptr World::getPtrViaHandle (const std::string& handle)
|
||||||
{
|
{
|
||||||
// TODO player
|
if (mPlayer->getPlayer().getRefData().getHandle()==handle)
|
||||||
|
return mPlayer->getPlayer();
|
||||||
|
|
||||||
for (CellRenderCollection::iterator iter (mActiveCells.begin());
|
for (CellRenderCollection::iterator iter (mActiveCells.begin());
|
||||||
iter!=mActiveCells.end(); ++iter)
|
iter!=mActiveCells.end(); ++iter)
|
||||||
|
@ -587,8 +681,10 @@ namespace MWWorld
|
||||||
return mGlobalVariables->getInt ("timescale");
|
return mGlobalVariables->getInt ("timescale");
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeCell (const std::string& cellName, const ESM::Position& position)
|
void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
|
||||||
{
|
{
|
||||||
|
SuppressDoingPhysics scopeGuard;
|
||||||
|
|
||||||
// remove active
|
// remove active
|
||||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||||
|
|
||||||
|
@ -614,81 +710,6 @@ namespace MWWorld
|
||||||
//currentRegion->name = "";
|
//currentRegion->name = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeCell (int X, int Y, const ESM::Position& position)
|
|
||||||
{
|
|
||||||
// remove active
|
|
||||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
|
||||||
|
|
||||||
while (active!=mActiveCells.end())
|
|
||||||
{
|
|
||||||
if (!(active->first->cell->data.flags & ESM::Cell::Interior))
|
|
||||||
{
|
|
||||||
if (std::abs (X-active->first->cell->data.gridX)<=1 &&
|
|
||||||
std::abs (Y-active->first->cell->data.gridY)<=1)
|
|
||||||
{
|
|
||||||
// keep cells within the new 3x3 grid
|
|
||||||
++active;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unloadCell (active++);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load cells
|
|
||||||
for (int x=X-1; x<=X+1; ++x)
|
|
||||||
for (int y=Y-1; y<=Y+1; ++y)
|
|
||||||
{
|
|
||||||
CellRenderCollection::iterator iter = mActiveCells.begin();
|
|
||||||
|
|
||||||
while (iter!=mActiveCells.end())
|
|
||||||
{
|
|
||||||
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
|
||||||
|
|
||||||
if (x==iter->first->cell->data.gridX &&
|
|
||||||
y==iter->first->cell->data.gridY)
|
|
||||||
break;
|
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iter==mActiveCells.end())
|
|
||||||
{
|
|
||||||
mExteriors[std::make_pair (x, y)].loadExt (x, y, mStore, mEsm);
|
|
||||||
Ptr::CellStore *cell = &mExteriors[std::make_pair (x, y)];
|
|
||||||
|
|
||||||
loadCell (cell, new MWRender::ExteriorCellRender (*cell, mEnvironment, mScene));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find current cell
|
|
||||||
CellRenderCollection::iterator iter = mActiveCells.begin();
|
|
||||||
|
|
||||||
while (iter!=mActiveCells.end())
|
|
||||||
{
|
|
||||||
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
|
||||||
|
|
||||||
if (X==iter->first->cell->data.gridX &&
|
|
||||||
Y==iter->first->cell->data.gridY)
|
|
||||||
break;
|
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert (iter!=mActiveCells.end());
|
|
||||||
|
|
||||||
mCurrentCell = iter->first;
|
|
||||||
|
|
||||||
// adjust player
|
|
||||||
playerCellChange (&mExteriors[std::make_pair (X, Y)], position);
|
|
||||||
|
|
||||||
// Sky system
|
|
||||||
adjustSky();
|
|
||||||
|
|
||||||
mCellChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void World::changeToExteriorCell (const ESM::Position& position)
|
void World::changeToExteriorCell (const ESM::Position& position)
|
||||||
{
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
@ -696,7 +717,7 @@ namespace MWWorld
|
||||||
|
|
||||||
positionToIndex (position.pos[0], position.pos[1], x, y);
|
positionToIndex (position.pos[0], position.pos[1], x, y);
|
||||||
|
|
||||||
changeCell (x, y, position);
|
changeCell (x, y, position, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::Cell *World::getExterior (const std::string& cellName) const
|
const ESM::Cell *World::getExterior (const std::string& cellName) const
|
||||||
|
@ -722,6 +743,7 @@ namespace MWWorld
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::markCellAsUnchanged()
|
void World::markCellAsUnchanged()
|
||||||
{
|
{
|
||||||
mCellChanged = false;
|
mCellChanged = false;
|
||||||
|
@ -781,15 +803,16 @@ namespace MWWorld
|
||||||
|
|
||||||
if (mCurrentCell->cell->data.gridX!=cellX || mCurrentCell->cell->data.gridY!=cellY)
|
if (mCurrentCell->cell->data.gridX!=cellX || mCurrentCell->cell->data.gridY!=cellY)
|
||||||
{
|
{
|
||||||
changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos);
|
changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (!DoingPhysics::isDoingPhysics())
|
|
||||||
mScene.moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mScene.moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z),
|
||||||
|
!DoingPhysics::isDoingPhysics());
|
||||||
|
|
||||||
// TODO cell change for non-player ref
|
// TODO cell change for non-player ref
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,4 +844,10 @@ namespace MWWorld
|
||||||
if (y<0)
|
if (y<0)
|
||||||
--cellY;
|
--cellY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
|
||||||
|
float duration)
|
||||||
|
{
|
||||||
|
mScene.doPhysics (duration, *this, actors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
#include "ptr.hpp"
|
#include "ptr.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Vector3;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct Position;
|
struct Position;
|
||||||
|
@ -83,14 +88,19 @@ namespace MWWorld
|
||||||
|
|
||||||
void loadCell (Ptr::CellStore *cell, MWRender::CellRender *render);
|
void loadCell (Ptr::CellStore *cell, MWRender::CellRender *render);
|
||||||
|
|
||||||
void playerCellChange (Ptr::CellStore *cell, const ESM::Position& position);
|
void playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
||||||
|
bool adjustPlayerPos = true);
|
||||||
|
|
||||||
void adjustSky();
|
void adjustSky();
|
||||||
|
|
||||||
|
void changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos);
|
||||||
|
///< Move from exterior to interior or from interior cell to a different
|
||||||
|
/// interior cell.
|
||||||
public:
|
public:
|
||||||
|
|
||||||
World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
||||||
const std::string& master, const boost::filesystem::path& resDir, bool newGame, Environment& environment);
|
const std::string& master, const boost::filesystem::path& resDir, bool newGame,
|
||||||
|
Environment& environment);
|
||||||
|
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
|
@ -138,12 +148,11 @@ namespace MWWorld
|
||||||
|
|
||||||
float getTimeScaleFactor() const;
|
float getTimeScaleFactor() const;
|
||||||
|
|
||||||
void changeCell (const std::string& cellName, const ESM::Position& position);
|
void changeToInteriorCell (const std::string& cellName, const ESM::Position& position);
|
||||||
///< works only for interior cells currently.
|
///< Move to interior cell.
|
||||||
|
|
||||||
void changeCell (int X, int Y, const ESM::Position& position);
|
|
||||||
|
|
||||||
void changeToExteriorCell (const ESM::Position& position);
|
void changeToExteriorCell (const ESM::Position& position);
|
||||||
|
///< Move to exterior cell.
|
||||||
|
|
||||||
const ESM::Cell *getExterior (const std::string& cellName) const;
|
const ESM::Cell *getExterior (const std::string& cellName) const;
|
||||||
///< Return a cell matching the given name or a 0-pointer, if there is no such cell.
|
///< Return a cell matching the given name or a 0-pointer, if there is no such cell.
|
||||||
|
@ -162,6 +171,10 @@ namespace MWWorld
|
||||||
|
|
||||||
void positionToIndex (float x, float y, int &cellX, int &cellY) const;
|
void positionToIndex (float x, float y, int &cellX, int &cellY) const;
|
||||||
///< Convert position to cell numbers
|
///< Convert position to cell numbers
|
||||||
|
|
||||||
|
void doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
|
||||||
|
float duration);
|
||||||
|
///< Run physics simulation and modify \a world accordingly.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,48 @@ namespace ESMS
|
||||||
loadRefs(store, esm);
|
loadRefs(store, esm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Call functor (ref) for each reference. functor must return a bool. Returning
|
||||||
|
/// false will abort the iteration.
|
||||||
|
/// \return Iteration completed?
|
||||||
|
template<class Functor>
|
||||||
|
bool forEach (Functor& functor)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
forEachImp (functor, activators) &&
|
||||||
|
forEachImp (functor, potions) &&
|
||||||
|
forEachImp (functor, appas) &&
|
||||||
|
forEachImp (functor, armors) &&
|
||||||
|
forEachImp (functor, books) &&
|
||||||
|
forEachImp (functor, clothes) &&
|
||||||
|
forEachImp (functor, containers) &&
|
||||||
|
forEachImp (functor, creatures) &&
|
||||||
|
forEachImp (functor, doors) &&
|
||||||
|
forEachImp (functor, ingreds) &&
|
||||||
|
forEachImp (functor, creatureLists) &&
|
||||||
|
forEachImp (functor, itemLists) &&
|
||||||
|
forEachImp (functor, lights) &&
|
||||||
|
forEachImp (functor, lockpicks) &&
|
||||||
|
forEachImp (functor, miscItems) &&
|
||||||
|
forEachImp (functor, npcs) &&
|
||||||
|
forEachImp (functor, probes) &&
|
||||||
|
forEachImp (functor, repairs) &&
|
||||||
|
forEachImp (functor, statics) &&
|
||||||
|
forEachImp (functor, weapons);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
template<class Functor, class List>
|
||||||
|
bool forEachImp (Functor& functor, List& list)
|
||||||
|
{
|
||||||
|
for (typename List::List::iterator iter (list.list.begin()); iter!=list.list.end();
|
||||||
|
++iter)
|
||||||
|
if (!functor (iter->ref, iter->mData))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void loadRefs(const ESMStore &store, ESMReader &esm)
|
void loadRefs(const ESMStore &store, ESMReader &esm)
|
||||||
{
|
{
|
||||||
assert (cell);
|
assert (cell);
|
||||||
|
|
Loading…
Reference in a new issue