implemented coc instruction

pull/7/head
Marc Zinnschlag 15 years ago
parent 2d8fbc6e55
commit 0e641f1246

@ -56,6 +56,8 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
mEnvironment.mWorld->advanceTime (
mEnvironment.mFrameDuration*mEnvironment.mWorld->getTimeScaleFactor()/3600);
mEnvironment.mWorld->markCellAsUnchanged();
return true;
}

@ -18,6 +18,9 @@ namespace MWRender
/// memory.
virtual void hide() = 0;
/// Destroy all rendering objects connected with this cell.
virtual void destroy() = 0;
/// Make the reference with the given handle visible.
virtual void enable (const std::string& handle) = 0;

@ -91,7 +91,7 @@ namespace MWRender
virtual void hide();
/// Destroy all rendering objects connected with this cell.
void destroy(); // comment by Zini: shouldn't this go into the destructor?
virtual void destroy(); // comment by Zini: shouldn't this go into the destructor?
/// Switch through lighting modes.
void toggleLight();

@ -22,16 +22,22 @@ namespace MWRender
camera(cam)
{
mPlayer.base = player;
mPlayer.ref.pos.pos[0] = mPlayer.ref.pos.pos[1] = mPlayer.ref.pos.pos[2];
mPlayer.ref.pos.pos[0] = mPlayer.ref.pos.pos[1] = mPlayer.ref.pos.pos[2] = 0;
}
// Set the player position. Uses Morrowind coordinates.
void setPos(float _x, float _y, float _z)
void setPos(float _x, float _y, float _z, bool updateCamera = false)
{
mPlayer.ref.pos.pos[0] = _x;
mPlayer.ref.pos.pos[1] = _y;
mPlayer.ref.pos.pos[2] = _z;
if (updateCamera)
camera->setPosition (Ogre::Vector3 (
mPlayer.ref.pos.pos[0],
mPlayer.ref.pos.pos[2],
mPlayer.ref.pos.pos[1]));
// TODO: Update sound listener
}

@ -27,17 +27,40 @@ namespace MWScript
runtime.push (context.getWorld().hasCellChanged() ? 1 : 0);
}
};
class OpCOC : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context
= static_cast<InterpreterContext&> (runtime.getContext());
std::string cell = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
ESM::Position pos;
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
context.getWorld().changeCell (cell, pos);
}
};
const int opcodeCellChanged = 0x2000000;
const int opcodeCOC = 0x2000026;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerFunction ("cellchanged", 'l', "", opcodeCellChanged);
extensions.registerInstruction ("coc", "S", opcodeCOC);
extensions.registerInstruction ("centeroncell", "S", opcodeCOC);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (opcodeCellChanged, new OpCellChanged);
interpreter.installSegment5 (opcodeCOC, new OpCOC);
}
}
}

@ -59,5 +59,6 @@ op 0x2000022: TurnMoonWhite
op 0x2000023: TurnMoonRed
op 0x2000024: GetMasserPhase
op 0x2000025: GetSecundaPhase
opcodes 0x2000026-0x3ffffff unused
op 0x2000026: COC
opcodes 0x2000027-0x3ffffff unused

@ -166,7 +166,7 @@ namespace MWWorld
World::World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
const std::string& master, const std::string& startCell, bool newGame)
: mSkyManager (0), mScene (renderer), mPlayerPos (0), mCurrentCell (0), mGlobalVariables (0),
mSky (false)
mSky (false), mCellChanged (false)
{
boost::filesystem::path masterPath (dataDir);
masterPath /= master;
@ -240,8 +240,7 @@ namespace MWWorld
bool World::hasCellChanged() const
{
// Cell change not implemented yet.
return false;
return mCellChanged;
}
Globals::Data& World::getGlobalVariable (const std::string& name)
@ -425,4 +424,51 @@ namespace MWWorld
{
return mGlobalVariables->getInt ("timescale");
}
void World::changeCell (const std::string& cellName, const ESM::Position& position)
{
// Load cell.
mInteriors[cellName].loadInt (cellName, mStore, mEsm);
// remove active
CellRenderCollection::iterator active = mActiveCells.begin();
if (active!=mActiveCells.end())
{
active->second->destroy();
delete active->second;
mActiveCells.erase (active);
}
mLocalScripts.clear(); // FIXME won't work with exteriors
insertInteriorScripts (mInteriors[cellName]);
mPlayerPos->setPos (position.pos[0], position.pos[1], position.pos[2]);
// TODO orientation
// This connects the cell data with the rendering scene.
std::pair<CellRenderCollection::iterator, bool> result =
mActiveCells.insert (std::make_pair (&mInteriors[cellName],
new MWRender::InteriorCellRender (mInteriors[cellName], mScene)));
if (result.second)
{
// Load the cell and insert it into the renderer
result.first->second->show();
}
if (mSky)
{
toggleSky();
// TODO set weather
toggleSky();
}
mCellChanged = true;
}
void World::markCellAsUnchanged()
{
mCellChanged = false;
}
}

@ -15,6 +15,11 @@
#include "ptr.hpp"
#include "globals.hpp"
namespace ESM
{
struct Position;
}
namespace Render
{
class OgreRenderer;
@ -52,6 +57,7 @@ namespace MWWorld
ScriptList mLocalScripts;
MWWorld::Globals *mGlobalVariables;
bool mSky;
bool mCellChanged;
// not implemented
World (const World&);
@ -112,6 +118,11 @@ namespace MWWorld
void setMoonColour (bool red);
float getTimeScaleFactor() const;
void changeCell (const std::string& cellName, const ESM::Position& position);
///< works only for interior cells currently.
void markCellAsUnchanged();
};
}

Loading…
Cancel
Save