1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-20 19:41:36 +00:00

Merge remote-tracking branch 'upstream/master' into osx_fix

Conflicts:
	CMakeLists.txt
This commit is contained in:
Nikolay Kasyanov 2012-07-31 01:06:18 +04:00
commit defab0e4b5
114 changed files with 2959 additions and 3583 deletions

2
.gitmodules vendored
View file

@ -1,3 +1,3 @@
[submodule "extern/shiny"] [submodule "extern/shiny"]
path = extern/shiny path = extern/shiny
url = git@github.com:scrawl/shiny.git url = git://github.com/scrawl/shiny.git

View file

@ -189,6 +189,9 @@ if (UNIX AND NOT APPLE)
find_package (Threads) find_package (Threads)
endif() endif()
# find boost without components so we can use Boost_VERSION
find_package(Boost REQUIRED)
set(BOOST_COMPONENTS system filesystem program_options thread) set(BOOST_COMPONENTS system filesystem program_options thread)
if (Boost_VERSION LESS 104900) if (Boost_VERSION LESS 104900)
@ -256,14 +259,13 @@ endif (APPLE)
# Set up Ogre plugin folder & debug suffix # Set up Ogre plugin folder & debug suffix
if (DEFINED CMAKE_BUILD_TYPE) # Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt)
# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) if (DEFINED CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE)
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE) add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d")
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d") else()
else() add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="")
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="")
endif()
endif() endif()
add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}") add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}")
add_definitions(-DOGRE_PLUGIN_DIR_DBG="${OGRE_PLUGIN_DIR_DBG}") add_definitions(-DOGRE_PLUGIN_DIR_DBG="${OGRE_PLUGIN_DIR_DBG}")
if (APPLE AND OPENMW_OSX_DEPLOYMENT) if (APPLE AND OPENMW_OSX_DEPLOYMENT)

View file

@ -39,7 +39,7 @@ add_openmw_dir (mwscript
locals scriptmanager compilercontext interpretercontext cellextensions miscextensions locals scriptmanager compilercontext interpretercontext cellextensions miscextensions
guiextensions soundextensions skyextensions statsextensions containerextensions guiextensions soundextensions skyextensions statsextensions containerextensions
aiextensions controlextensions extensions globalscripts ref dialogueextensions aiextensions controlextensions extensions globalscripts ref dialogueextensions
animationextensions transformationextensions animationextensions transformationextensions consoleextensions userextensions
) )
add_openmw_dir (mwsound add_openmw_dir (mwsound

View file

@ -56,11 +56,8 @@ void OMW::Engine::executeLocalScripts()
localScripts.setIgnore (MWWorld::Ptr()); localScripts.setIgnore (MWWorld::Ptr());
} }
void OMW::Engine::setAnimationVerbose(bool animverbose){ void OMW::Engine::setAnimationVerbose(bool animverbose)
if(animverbose){ {
NifOgre::NIFLoader::getSingletonPtr()->setOutputAnimFiles(true);
NifOgre::NIFLoader::getSingletonPtr()->setVerbosePath(mCfgMgr.getLogPath().string());
}
} }
bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
@ -132,6 +129,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
, mCompileAll (false) , mCompileAll (false)
, mScriptContext (0) , mScriptContext (0)
, mFSStrict (false) , mFSStrict (false)
, mScriptConsoleMode (false)
, mCfgMgr(configurationManager) , mCfgMgr(configurationManager)
{ {
std::srand ( std::time(NULL) ); std::srand ( std::time(NULL) );
@ -329,7 +327,8 @@ void OMW::Engine::go()
MWScript::registerExtensions (mExtensions); MWScript::registerExtensions (mExtensions);
mEnvironment.setWindowManager (new MWGui::WindowManager( mEnvironment.setWindowManager (new MWGui::WindowManager(
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"))); mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
mScriptConsoleMode));
// Create sound system // Create sound system
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
@ -391,6 +390,9 @@ void OMW::Engine::go()
<< std::endl; << std::endl;
} }
if (!mStartupScript.empty())
MWBase::Environment::get().getWindowManager()->executeInConsole (mStartupScript);
// Start the main rendering loop // Start the main rendering loop
mOgre->start(); mOgre->start();
@ -493,3 +495,13 @@ void OMW::Engine::setFallbackValues(std::map<std::string,std::string> fallbackMa
{ {
mFallbackMap = fallbackMap; mFallbackMap = fallbackMap;
} }
void OMW::Engine::setScriptConsoleMode (bool enabled)
{
mScriptConsoleMode = enabled;
}
void OMW::Engine::setStartupScript (const std::string& path)
{
mStartupScript = path;
}

View file

@ -73,6 +73,8 @@ namespace OMW
bool mCompileAll; bool mCompileAll;
std::string mFocusName; std::string mFocusName;
std::map<std::string,std::string> mFallbackMap; std::map<std::string,std::string> mFallbackMap;
bool mScriptConsoleMode;
std::string mStartupScript;
Compiler::Extensions mExtensions; Compiler::Extensions mExtensions;
Compiler::Context *mScriptContext; Compiler::Context *mScriptContext;
@ -158,6 +160,12 @@ namespace OMW
void setFallbackValues(std::map<std::string,std::string> map); void setFallbackValues(std::map<std::string,std::string> map);
/// Enable console-only script functionality
void setScriptConsoleMode (bool enabled);
/// Set path for a script that is run on startup in the console.
void setStartupScript (const std::string& path);
private: private:
Files::ConfigurationManager& mCfgMgr; Files::ConfigurationManager& mCfgMgr;
}; };

View file

@ -124,12 +124,20 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
("script-verbose", bpo::value<bool>()->implicit_value(true) ("script-verbose", bpo::value<bool>()->implicit_value(true)
->default_value(false), "verbose script output") ->default_value(false), "verbose script output")
("new-game", bpo::value<bool>()->implicit_value(true)
->default_value(false), "activate char gen/new game mechanics")
("script-all", bpo::value<bool>()->implicit_value(true) ("script-all", bpo::value<bool>()->implicit_value(true)
->default_value(false), "compile all scripts (excluding dialogue scripts) at startup") ->default_value(false), "compile all scripts (excluding dialogue scripts) at startup")
("script-console", bpo::value<bool>()->implicit_value(true)
->default_value(false), "enable console-only script functionality")
("script-run", bpo::value<std::string>()->default_value(""),
"select a file that is executed in the console on startup\n\n"
"Note: The file contains a list of script lines, but not a complete scripts. "
"That means no begin/end and no variable declarations.")
("new-game", bpo::value<bool>()->implicit_value(true)
->default_value(false), "activate char gen/new game mechanics")
("fs-strict", bpo::value<bool>()->implicit_value(true) ("fs-strict", bpo::value<bool>()->implicit_value(true)
->default_value(false), "strict file system handling (no case folding)") ->default_value(false), "strict file system handling (no case folding)")
@ -249,6 +257,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.setCompileAll(variables["script-all"].as<bool>()); engine.setCompileAll(variables["script-all"].as<bool>());
engine.setAnimationVerbose(variables["anim-verbose"].as<bool>()); engine.setAnimationVerbose(variables["anim-verbose"].as<bool>());
engine.setFallbackValues(variables["fallback"].as<FallbackMap>().mMap); engine.setFallbackValues(variables["fallback"].as<FallbackMap>().mMap);
engine.setScriptConsoleMode (variables["script-console"].as<bool>());
engine.setStartupScript (variables["script-run"].as<std::string>());
return true; return true;
} }

View file

@ -54,6 +54,14 @@ namespace MWBase
World& operator= (const World&); World& operator= (const World&);
///< not implemented ///< not implemented
protected:
virtual void
placeObject(
const MWWorld::Ptr &ptr,
MWWorld::CellStore &cell,
const ESM::Position &pos) = 0;
public: public:
enum RenderMode enum RenderMode

View file

@ -19,32 +19,33 @@ namespace MWClass
{ {
void Activator::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Activator::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Activator> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Activator>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Activator::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Activator> *ref = MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>(); ptr.get<ESM::Activator>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Activator::getName (const MWWorld::Ptr& ptr) const std::string Activator::getName (const MWWorld::Ptr& ptr) const
@ -93,4 +94,14 @@ namespace MWClass
return info; return info;
} }
MWWorld::Ptr
Activator::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
return MWWorld::Ptr(&cell.activators.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,10 @@ namespace MWClass
{ {
class Activator : public MWWorld::Class class Activator : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -28,6 +32,8 @@ namespace MWClass
///< Return name of the script attached to ptr ///< Return name of the script attached to ptr
static void registerSelf(); static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -22,34 +22,35 @@
namespace MWClass namespace MWClass
{ {
void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Apparatus> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Apparatus>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Apparatus::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Apparatus> *ref = MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Apparatus::getName (const MWWorld::Ptr& ptr) const std::string Apparatus::getName (const MWWorld::Ptr& ptr) const
@ -148,4 +149,13 @@ namespace MWClass
{ {
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionAlchemy()); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionAlchemy());
} }
MWWorld::Ptr
Apparatus::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return MWWorld::Ptr(&cell.appas.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,10 @@ namespace MWClass
{ {
class Apparatus : public MWWorld::Class class Apparatus : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -48,6 +52,8 @@ namespace MWClass
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -27,31 +27,33 @@ namespace MWClass
{ {
void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Armor> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Armor>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Armor::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Armor::getName (const MWWorld::Ptr& ptr) const std::string Armor::getName (const MWWorld::Ptr& ptr) const
@ -274,4 +276,13 @@ namespace MWClass
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
} }
MWWorld::Ptr
Armor::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return MWWorld::Ptr(&cell.armors.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Armor : public MWWorld::Class class Armor : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -66,6 +69,7 @@ namespace MWClass
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -23,32 +23,33 @@ namespace MWClass
{ {
void Book::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Book::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Book> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Book>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Book::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Book::getName (const MWWorld::Ptr& ptr) const std::string Book::getName (const MWWorld::Ptr& ptr) const
@ -156,4 +157,12 @@ namespace MWClass
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr));
} }
MWWorld::Ptr
Book::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return MWWorld::Ptr(&cell.books.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Book : public MWWorld::Class class Book : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -50,6 +53,8 @@ namespace MWClass
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const; virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -25,32 +25,33 @@ namespace MWClass
{ {
void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Clothing> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Clothing>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Clothing::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Clothing::getName (const MWWorld::Ptr& ptr) const std::string Clothing::getName (const MWWorld::Ptr& ptr) const
@ -226,4 +227,13 @@ namespace MWClass
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
} }
MWWorld::Ptr
Clothing::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return MWWorld::Ptr(&cell.clothes.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Clothing : public MWWorld::Class class Clothing : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -59,6 +62,8 @@ namespace MWClass
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -54,32 +54,33 @@ namespace MWClass
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Container> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Container>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Container::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Container> *ref = MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
boost::shared_ptr<MWWorld::Action> Container::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Container::activate (const MWWorld::Ptr& ptr,
@ -206,4 +207,13 @@ namespace MWClass
{ {
ptr.getCellRef().lockLevel = 0; ptr.getCellRef().lockLevel = 0;
} }
MWWorld::Ptr
Container::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return MWWorld::Ptr(&cell.containers.insert(*ref), &cell);
}
} }

View file

@ -9,6 +9,10 @@ namespace MWClass
{ {
void ensureCustomData (const MWWorld::Ptr& ptr) const; void ensureCustomData (const MWWorld::Ptr& ptr) const;
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -51,6 +55,8 @@ namespace MWClass
///< Unlock object ///< Unlock object
static void registerSelf(); static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -86,17 +86,25 @@ namespace MWClass
} }
void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()){
physics.insertActorPhysics(ptr, model);
}
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
}
std::string Creature::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Creature> *ref = MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>(); ptr.get<ESM::Creature>();
assert (ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertActorPhysics(ptr, "meshes\\" + model);
} }
return "";
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
} }
std::string Creature::getName (const MWWorld::Ptr& ptr) const std::string Creature::getName (const MWWorld::Ptr& ptr) const
@ -187,4 +195,13 @@ namespace MWClass
return weight; return weight;
} }
MWWorld::Ptr
Creature::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return MWWorld::Ptr(&cell.creatures.insert(*ref), &cell);
}
} }

View file

@ -11,6 +11,9 @@ namespace MWClass
{ {
void ensureCustomData (const MWWorld::Ptr& ptr) const; void ensureCustomData (const MWWorld::Ptr& ptr) const;
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual std::string getId (const MWWorld::Ptr& ptr) const; virtual std::string getId (const MWWorld::Ptr& ptr) const;
@ -54,6 +57,8 @@ namespace MWClass
/// effects). Throws an exception, if the object can't hold other objects. /// effects). Throws an exception, if the object can't hold other objects.
static void registerSelf(); static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -25,30 +25,33 @@ namespace MWClass
{ {
void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Door> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Door>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
MWWorld::LiveCellRef<ESM::Door> *ref = const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Door::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Door::getName (const MWWorld::Ptr& ptr) const std::string Door::getName (const MWWorld::Ptr& ptr) const
@ -94,18 +97,18 @@ namespace MWClass
if (ref->ref.teleport) if (ref->ref.teleport)
{ {
// teleport door // teleport door
/// \todo remove this if clause once ActionTeleport can also support other actors
if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor) if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor)
{ {
// the player is using the door // the player is using the door
// The reason this is not 3D is that it would get interrupted when you teleport // The reason this is not 3D is that it would get interrupted when you teleport
MWBase::Environment::get().getSoundManager()->playSound(openSound, 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound(openSound, 1.0, 1.0);
return boost::shared_ptr<MWWorld::Action> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTeleportPlayer (ref->ref.destCell, ref->ref.doorDest)); new MWWorld::ActionTeleport (ref->ref.destCell, ref->ref.doorDest));
} }
else else
{ {
// another NPC or a creature is using the door // another NPC or a creature is using the door
// TODO return action for teleporting other NPC/creature
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction); return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
} }
} }
@ -206,4 +209,13 @@ namespace MWClass
return info; return info;
} }
MWWorld::Ptr
Door::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
return MWWorld::Ptr(&cell.doors.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Door : public MWWorld::Class class Door : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -38,6 +41,8 @@ namespace MWClass
///< Return name of the script attached to ptr ///< Return name of the script attached to ptr
static void registerSelf(); static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -23,30 +23,33 @@ namespace MWClass
{ {
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Ingredient> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Ingredient>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Ingredient::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Ingredient> *ref = MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Ingredient::getName (const MWWorld::Ptr& ptr) const std::string Ingredient::getName (const MWWorld::Ptr& ptr) const
@ -153,4 +156,13 @@ namespace MWClass
return info; return info;
} }
MWWorld::Ptr
Ingredient::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return MWWorld::Ptr(&cell.ingreds.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Ingredient : public MWWorld::Class class Ingredient : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -44,6 +47,8 @@ namespace MWClass
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon. ///< Return name of inventory icon.
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -28,8 +28,8 @@ namespace MWClass
{ {
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
assert (ref->base != NULL); assert (ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
@ -50,20 +50,31 @@ namespace MWClass
{ {
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
assert (ref->base != NULL); assert (ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
if(!model.empty()){ if(!model.empty()) {
physics.insertObjectPhysics(ptr, "meshes\\" + model); physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
if (!ref->base->sound.empty()) {
if (!ref->base->sound.empty()) MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->base->sound, 1.0, 1.0, MWSound::Play_Loop);
{
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, ref->base->sound, 1.0, 1.0, MWSound::Play_Loop);
} }
} }
std::string Light::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty()) {
return "meshes\\" + model;
}
return "";
}
std::string Light::getName (const MWWorld::Ptr& ptr) const std::string Light::getName (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
@ -185,4 +196,13 @@ namespace MWClass
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
} }
MWWorld::Ptr
Light::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return MWWorld::Ptr(&cell.lights.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Light : public MWWorld::Class class Light : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -52,6 +55,8 @@ namespace MWClass
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -25,34 +25,34 @@ namespace MWClass
{ {
void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Tool>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Tool>(); if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
const std::string &model = ref->base->model;
assert (ref->base != NULL);
if(!model.empty()){
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
} }
std::string Lockpick::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
assert(ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty()) {
return "meshes\\" + model;
}
return "";
}
std::string Lockpick::getName (const MWWorld::Ptr& ptr) const std::string Lockpick::getName (const MWWorld::Ptr& ptr) const
{ {
@ -165,4 +165,13 @@ namespace MWClass
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
} }
MWWorld::Ptr
Lockpick::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return MWWorld::Ptr(&cell.lockpicks.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Lockpick : public MWWorld::Class class Lockpick : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -52,6 +55,8 @@ namespace MWClass
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -12,6 +12,7 @@
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp" #include "../mwworld/physicssystem.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwgui/window_manager.hpp" #include "../mwgui/window_manager.hpp"
#include "../mwgui/tooltips.hpp" #include "../mwgui/tooltips.hpp"
@ -27,32 +28,33 @@ namespace MWClass
{ {
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Miscellaneous>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Miscellaneous::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Miscellaneous::getName (const MWWorld::Ptr& ptr) const std::string Miscellaneous::getName (const MWWorld::Ptr& ptr) const
@ -182,4 +184,39 @@ namespace MWClass
return info; return info;
} }
MWWorld::Ptr
Miscellaneous::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::Ptr newPtr;
const ESMS::ESMStore &store =
MWBase::Environment::get().getWorld()->getStore();
if (MWWorld::Class::get(ptr).getName(ptr) == store.gameSettings.search("sGold")->str) {
int goldAmount = ptr.getRefData().getCount();
std::string base = "Gold_001";
if (goldAmount >= 100)
base = "Gold_100";
else if (goldAmount >= 25)
base = "Gold_025";
else if (goldAmount >= 10)
base = "Gold_010";
else if (goldAmount >= 5)
base = "Gold_005";
// Really, I have no idea why moving ref out of conditional
// scope causes list::push_back throwing std::bad_alloc
MWWorld::ManualRef newRef(store, base);
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
newRef.getPtr().get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell);
} else {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell);
}
return newPtr;
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Miscellaneous : public MWWorld::Class class Miscellaneous : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -44,6 +47,8 @@ namespace MWClass
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon. ///< Return name of inventory icon.
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -125,25 +125,29 @@ namespace MWClass
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
physics.insertActorPhysics(ptr, getModel(ptr));
MWBase::Environment::get().getMechanicsManager()->addActor(ptr);
}
std::string Npc::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
assert(ref->base != NULL);
assert (ref->base != NULL);
std::string headID = ref->base->head; std::string headID = ref->base->head;
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); int end = headID.find_last_of("head_") - 4;
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; std::string bodyRaceID = headID.substr(0, end);
std::string smodel = "meshes\\base_anim.nif"; std::string model = "meshes\\base_anim.nif";
if(beast) if (bodyRaceID == "b_n_khajiit_m_" ||
smodel = "meshes\\base_animkna.nif"; bodyRaceID == "b_n_khajiit_f_" ||
physics.insertActorPhysics(ptr, smodel); bodyRaceID == "b_n_argonian_m_" ||
bodyRaceID == "b_n_argonian_f_")
{
MWBase::Environment::get().getMechanicsManager()->addActor (ptr); model = "meshes\\base_animkna.nif";
}
return model;
} }
std::string Npc::getName (const MWWorld::Ptr& ptr) const std::string Npc::getName (const MWWorld::Ptr& ptr) const
@ -376,4 +380,13 @@ namespace MWClass
y = 0; y = 0;
x = 0; x = 0;
} }
MWWorld::Ptr
Npc::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return MWWorld::Ptr(&cell.npcs.insert(*ref), &cell);
}
} }

View file

@ -9,6 +9,9 @@ namespace MWClass
{ {
void ensureCustomData (const MWWorld::Ptr& ptr) const; void ensureCustomData (const MWWorld::Ptr& ptr) const;
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual std::string getId (const MWWorld::Ptr& ptr) const; virtual std::string getId (const MWWorld::Ptr& ptr) const;
@ -88,6 +91,8 @@ namespace MWClass
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const; virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
static void registerSelf(); static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -25,32 +25,33 @@ namespace MWClass
{ {
void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Potion> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Potion>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Potion::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Potion> *ref = MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Potion::getName (const MWWorld::Ptr& ptr) const std::string Potion::getName (const MWWorld::Ptr& ptr) const
@ -156,7 +157,20 @@ namespace MWClass
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
return boost::shared_ptr<MWWorld::Action> ( boost::shared_ptr<MWWorld::Action> action (
new MWWorld::ActionApply (actor, ref->base->mId, actor)); new MWWorld::ActionApply (actor, ref->base->mId));
action->setSound ("Drink");
return action;
}
MWWorld::Ptr
Potion::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return MWWorld::Ptr(&cell.potions.insert(*ref), &cell);
} }
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Potion : public MWWorld::Class class Potion : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -47,6 +50,8 @@ namespace MWClass
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon. ///< Return name of inventory icon.
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -25,34 +25,34 @@ namespace MWClass
{ {
void Probe::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Probe::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Probe> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Probe>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
MWWorld::LiveCellRef<ESM::Probe> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Probe>(); if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
const std::string &model = ref->base->model;
assert (ref->base != NULL);
if(!model.empty()){
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
} }
std::string Probe::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
assert(ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty()) {
return "meshes\\" + model;
}
return "";
}
std::string Probe::getName (const MWWorld::Ptr& ptr) const std::string Probe::getName (const MWWorld::Ptr& ptr) const
{ {
@ -164,4 +164,14 @@ namespace MWClass
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
} }
MWWorld::Ptr
Probe::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return MWWorld::Ptr(&cell.probes.insert(*ref), &cell);
}
} }

View file

@ -7,9 +7,12 @@ namespace MWClass
{ {
class Probe : public MWWorld::Class class Probe : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
@ -52,6 +55,8 @@ namespace MWClass
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -23,32 +23,33 @@ namespace MWClass
{ {
void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Repair> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Repair>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Repair::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Repair::getName (const MWWorld::Ptr& ptr) const std::string Repair::getName (const MWWorld::Ptr& ptr) const
@ -145,4 +146,13 @@ namespace MWClass
return info; return info;
} }
MWWorld::Ptr
Repair::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return MWWorld::Ptr(&cell.repairs.insert(*ref), &cell);
}
} }

View file

@ -7,9 +7,12 @@ namespace MWClass
{ {
class Repair : public MWWorld::Class class Repair : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
@ -44,6 +47,8 @@ namespace MWClass
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon. ///< Return name of inventory icon.
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -13,31 +13,33 @@ namespace MWClass
{ {
void Static::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Static::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Static> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Static>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), true); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), true);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Static::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Static> *ref = MWWorld::LiveCellRef<ESM::Static> *ref =
ptr.get<ESM::Static>(); ptr.get<ESM::Static>();
assert(ref->base != NULL);
assert (ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Static::getName (const MWWorld::Ptr& ptr) const std::string Static::getName (const MWWorld::Ptr& ptr) const
@ -51,4 +53,13 @@ namespace MWClass
registerClass (typeid (ESM::Static).name(), instance); registerClass (typeid (ESM::Static).name(), instance);
} }
MWWorld::Ptr
Static::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Static> *ref =
ptr.get<ESM::Static>();
return MWWorld::Ptr(&cell.statics.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Static : public MWWorld::Class class Static : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -19,6 +22,8 @@ namespace MWClass
/// can return an empty string. /// can return an empty string.
static void registerSelf(); static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -25,32 +25,33 @@ namespace MWClass
{ {
void Weapon::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Weapon::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Weapon> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Weapon>(); if (!model.empty()) {
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, model);
} }
} }
void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
}
std::string Weapon::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
assert(ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
assert (ref->base != NULL); if (!model.empty()) {
if(!model.empty()){ return "meshes\\" + model;
physics.insertObjectPhysics(ptr, "meshes\\" + model);
} }
return "";
} }
std::string Weapon::getName (const MWWorld::Ptr& ptr) const std::string Weapon::getName (const MWWorld::Ptr& ptr) const
@ -364,4 +365,13 @@ namespace MWClass
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
} }
MWWorld::Ptr
Weapon::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return MWWorld::Ptr(&cell.weapons.insert(*ref), &cell);
}
} }

View file

@ -7,6 +7,9 @@ namespace MWClass
{ {
class Weapon : public MWWorld::Class class Weapon : public MWWorld::Class
{ {
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
public: public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -66,6 +69,7 @@ namespace MWClass
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
}; };
} }

View file

@ -3,9 +3,11 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwinput/inputmanager.hpp" #include "../mwinput/inputmanager.hpp"
#include "../mwsound/soundmanager.hpp" #include "../mwsound/soundmanager.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/player.hpp"
#include "formatting.hpp" #include "formatting.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
@ -99,7 +101,7 @@ void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack); MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
MWWorld::ActionTake take(mBook); MWWorld::ActionTake take(mBook);
take.execute(); take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
mWindowManager.removeGuiMode(GM_Book); mWindowManager.removeGuiMode(GM_Book);
} }

View file

@ -2,6 +2,7 @@
#include "console.hpp" #include "console.hpp"
#include <algorithm> #include <algorithm>
#include <fstream>
#include <components/esm_store/reclists.hpp> #include <components/esm_store/reclists.hpp>
#include <components/esm_store/store.hpp> #include <components/esm_store/store.hpp>
@ -105,9 +106,10 @@ namespace MWGui
} }
} }
Console::Console(int w, int h, const Compiler::Extensions& extensions) Console::Console(int w, int h, bool consoleOnlyScripts)
: Layout("openmw_console.layout"), : Layout("openmw_console.layout"),
mCompilerContext (MWScript::CompilerContext::Type_Console) mCompilerContext (MWScript::CompilerContext::Type_Console),
mConsoleOnlyScripts (consoleOnlyScripts)
{ {
setCoord(10,10, w-10, h/2); setCoord(10,10, w-10, h/2);
@ -126,7 +128,8 @@ namespace MWGui
history->setVisibleVScroll(true); history->setVisibleVScroll(true);
// compiler // compiler
mCompilerContext.setExtensions (&extensions); MWScript::registerExtensions (mExtensions, mConsoleOnlyScripts);
mCompilerContext.setExtensions (&mExtensions);
} }
void Console::enable() void Console::enable()
@ -173,6 +176,47 @@ namespace MWGui
print("#FF2222" + msg + "\n"); print("#FF2222" + msg + "\n");
} }
void Console::execute (const std::string& command)
{
// Log the command
print("#FFFFFF> " + command + "\n");
Compiler::Locals locals;
Compiler::Output output (locals);
if (compile (command + "\n", output))
{
try
{
ConsoleInterpreterContext interpreterContext (*this, mPtr);
Interpreter::Interpreter interpreter;
MWScript::installOpcodes (interpreter, mConsoleOnlyScripts);
std::vector<Interpreter::Type_Code> code;
output.getCode (code);
interpreter.run (&code[0], code.size(), interpreterContext);
}
catch (const std::exception& error)
{
printError (std::string ("An exception has been thrown: ") + error.what());
}
}
}
void Console::executeFile (const std::string& path)
{
std::ifstream stream (path.c_str());
if (!stream.is_open())
printError ("failed to open file: " + path);
else
{
std::string line;
while (std::getline (stream, line))
execute (line);
}
}
void Console::keyPress(MyGUI::WidgetPtr _sender, void Console::keyPress(MyGUI::WidgetPtr _sender,
MyGUI::KeyCode key, MyGUI::KeyCode key,
MyGUI::Char _char) MyGUI::Char _char)
@ -234,28 +278,7 @@ namespace MWGui
current = command_history.end(); current = command_history.end();
editString.clear(); editString.clear();
// Log the command execute (cm);
print("#FFFFFF> " + cm + "\n");
Compiler::Locals locals;
Compiler::Output output (locals);
if (compile (cm + "\n", output))
{
try
{
ConsoleInterpreterContext interpreterContext (*this, mPtr);
Interpreter::Interpreter interpreter;
MWScript::installOpcodes (interpreter);
std::vector<Interpreter::Type_Code> code;
output.getCode (code);
interpreter.run (&code[0], code.size(), interpreterContext);
}
catch (const std::exception& error)
{
printError (std::string ("An exception has been thrown: ") + error.what());
}
}
command->setCaption(""); command->setCaption("");
} }

View file

@ -11,6 +11,7 @@
#include <components/compiler/scanner.hpp> #include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp> #include <components/compiler/locals.hpp>
#include <components/compiler/output.hpp> #include <components/compiler/output.hpp>
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include "../mwscript/compilercontext.hpp" #include "../mwscript/compilercontext.hpp"
@ -24,8 +25,10 @@ namespace MWGui
{ {
private: private:
Compiler::Extensions mExtensions;
MWScript::CompilerContext mCompilerContext; MWScript::CompilerContext mCompilerContext;
std::vector<std::string> mNames; std::vector<std::string> mNames;
bool mConsoleOnlyScripts;
bool compile (const std::string& cmd, Compiler::Output& output); bool compile (const std::string& cmd, Compiler::Output& output);
@ -62,7 +65,7 @@ namespace MWGui
StringList::iterator current; StringList::iterator current;
std::string editString; std::string editString;
Console(int w, int h, const Compiler::Extensions& extensions); Console(int w, int h, bool consoleOnlyScripts);
void enable(); void enable();
@ -86,6 +89,10 @@ namespace MWGui
/// Error message /// Error message
void printError(const std::string &msg); void printError(const std::string &msg);
void execute (const std::string& command);
void executeFile (const std::string& command);
private: private:
void keyPress(MyGUI::WidgetPtr _sender, void keyPress(MyGUI::WidgetPtr _sender,

View file

@ -175,7 +175,7 @@ namespace MWGui
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr); boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
action->execute(); action->execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
// this is necessary for books/scrolls: if they are already in the player's inventory, // this is necessary for books/scrolls: if they are already in the player's inventory,
// the "Take" button should not be visible. // the "Take" button should not be visible.

View file

@ -1,8 +1,10 @@
#include "scrollwindow.hpp" #include "scrollwindow.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwinput/inputmanager.hpp" #include "../mwinput/inputmanager.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/player.hpp"
#include "../mwsound/soundmanager.hpp" #include "../mwsound/soundmanager.hpp"
#include "formatting.hpp" #include "formatting.hpp"
@ -63,7 +65,7 @@ void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack); MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
MWWorld::ActionTake take(mScroll); MWWorld::ActionTake take(mScroll);
take.execute(); take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
mWindowManager.removeGuiMode(GM_Scroll); mWindowManager.removeGuiMode(GM_Scroll);
} }

View file

@ -41,7 +41,7 @@
using namespace MWGui; using namespace MWGui;
WindowManager::WindowManager( WindowManager::WindowManager(
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath) const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, bool consoleOnlyScripts)
: mGuiManager(NULL) : mGuiManager(NULL)
, mHud(NULL) , mHud(NULL)
, mMap(NULL) , mMap(NULL)
@ -113,7 +113,7 @@ WindowManager::WindowManager(
mMenu = new MainMenu(w,h); mMenu = new MainMenu(w,h);
mMap = new MapWindow(*this); mMap = new MapWindow(*this);
mStatsWindow = new StatsWindow(*this); mStatsWindow = new StatsWindow(*this);
mConsole = new Console(w,h, extensions); mConsole = new Console(w,h, consoleOnlyScripts);
mJournal = new JournalWindow(*this); mJournal = new JournalWindow(*this);
mMessageBoxManager = new MessageBoxManager(this); mMessageBoxManager = new MessageBoxManager(this);
mInventoryWindow = new InventoryWindow(*this,mDragAndDrop); mInventoryWindow = new InventoryWindow(*this,mDragAndDrop);
@ -740,3 +740,8 @@ bool WindowManager::getWorldMouseOver()
{ {
return mHud->getWorldMouseOver(); return mHud->getWorldMouseOver();
} }
void WindowManager::executeInConsole (const std::string& path)
{
mConsole->executeFile (path);
}

View file

@ -94,7 +94,7 @@ namespace MWGui
typedef std::vector<Faction> FactionList; typedef std::vector<Faction> FactionList;
typedef std::vector<int> SkillList; typedef std::vector<int> SkillList;
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath); WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, bool consoleOnlyScripts);
virtual ~WindowManager(); virtual ~WindowManager();
/** /**
@ -237,6 +237,8 @@ namespace MWGui
void processChangedSettings(const Settings::CategorySettingVector& changed); void processChangedSettings(const Settings::CategorySettingVector& changed);
void executeInConsole (const std::string& path);
private: private:
OEngine::GUI::MyGUIManager *mGuiManager; OEngine::GUI::MyGUIManager *mGuiManager;
HUD *mHud; HUD *mHud;

View file

@ -122,15 +122,13 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store){
void Actors::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number){ void Actors::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number){
if(mAllActors.find(ptr) != mAllActors.end()) if(mAllActors.find(ptr) != mAllActors.end())
mAllActors[ptr]->startScript(groupName, mode, number); mAllActors[ptr]->playGroup(groupName, mode, number);
} }
void Actors::skipAnimation (const MWWorld::Ptr& ptr){ void Actors::skipAnimation (const MWWorld::Ptr& ptr){
if(mAllActors.find(ptr) != mAllActors.end()) if(mAllActors.find(ptr) != mAllActors.end())
mAllActors[ptr]->stopScript(); mAllActors[ptr]->skipAnim();
} }
void Actors::update (float duration){ void Actors::update (float duration){
for(std::map<MWWorld::Ptr, Animation*>::iterator iter = mAllActors.begin(); iter != mAllActors.end(); iter++) for(std::map<MWWorld::Ptr, Animation*>::iterator iter = mAllActors.begin(); iter != mAllActors.end(); iter++)
{ iter->second->runAnimation(duration);
(iter->second)->runAnimation(duration);
}
} }

View file

@ -5,498 +5,171 @@
#include <OgreEntity.h> #include <OgreEntity.h>
#include <OgreBone.h> #include <OgreBone.h>
#include <OgreSubMesh.h> #include <OgreSubMesh.h>
#include <OgreSceneManager.h>
namespace MWRender namespace MWRender
{ {
std::map<std::string, int> Animation::sUniqueIDs;
Animation::Animation(OEngine::Render::OgreRenderer& _rend) Animation::Animation(OEngine::Render::OgreRenderer& _rend)
: mInsert(NULL) : mInsert(NULL)
, mRend(_rend) , mRend(_rend)
, mVecRotPos() , mTime(0.0f)
, mTime(0.0f) , mSkipFrame(false)
, mStartTime(0.0f) {
, mStopTime(0.0f) }
, mAnimate(0)
, mRindexI() Animation::~Animation()
, mTindexI() {
, mShapeNumber(0) Ogre::SceneManager *sceneMgr = mInsert->getCreator();
, mShapeIndexI() for(size_t i = 0;i < mEntityList.mEntities.size();i++)
, mShapes(NULL) sceneMgr->destroyEntity(mEntityList.mEntities[i]);
, mTransformations(NULL) mEntityList.mEntities.clear();
, mTextmappings(NULL) }
, mBase(NULL)
struct checklow {
bool operator()(const char &a, const char &b) const
{ {
return ::tolower(a) == ::tolower(b);
} }
};
Animation::~Animation() bool Animation::findGroupTimes(const std::string &groupname, Animation::GroupTimes *times)
{
const std::string &start = groupname+": start";
const std::string &startloop = groupname+": loop start";
const std::string &stop = groupname+": stop";
const std::string &stoploop = groupname+": loop stop";
NifOgre::TextKeyMap::const_iterator iter;
for(iter = mTextKeys.begin();iter != mTextKeys.end();iter++)
{ {
} if(times->mStart >= 0.0f && times->mLoopStart >= 0.0f && times->mLoopStop >= 0.0f && times->mStop >= 0.0f)
return true;
std::string Animation::getUniqueID(std::string mesh) std::string::const_iterator strpos = iter->second.begin();
{ std::string::const_iterator strend = iter->second.end();
int counter;
std::string copy = mesh;
std::transform(copy.begin(), copy.end(), copy.begin(), ::tolower);
if(sUniqueIDs.find(copy) == sUniqueIDs.end()) while(strpos != strend)
{ {
counter = sUniqueIDs[copy] = 0; size_t strlen = strend-strpos;
} std::string::const_iterator striter;
else
{
sUniqueIDs[copy] = sUniqueIDs[copy] + 1;
counter = sUniqueIDs[copy];
}
std::stringstream out; if(start.size() <= strlen &&
((striter=std::mismatch(strpos, strend, start.begin(), checklow()).first) == strend ||
if(counter > 99 && counter < 1000) *striter == '\r' || *striter == '\n'))
out << "0";
else if(counter > 9)
out << "00";
else
out << "000";
out << counter;
return out.str();
}
void Animation::startScript(std::string groupname, int mode, int loops)
{
//If groupname is recognized set animate to true
//Set the start time and stop time
//How many times to loop
if(groupname == "all")
{
mAnimate = loops;
mTime = mStartTime;
}
else if(mTextmappings)
{
std::string startName = groupname + ": loop start";
std::string stopName = groupname + ": loop stop";
bool first = false;
if(loops > 1)
{ {
startName = groupname + ": loop start"; times->mStart = iter->first;
stopName = groupname + ": loop stop"; times->mLoopStart = iter->first;
for(std::map<std::string, float>::iterator iter = mTextmappings->begin(); iter != mTextmappings->end(); iter++)
{
std::string current = iter->first.substr(0, startName.size());
std::transform(current.begin(), current.end(), current.begin(), ::tolower);
std::string current2 = iter->first.substr(0, stopName.size());
std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower);
if(current == startName)
{
mStartTime = iter->second;
mAnimate = loops;
mTime = mStartTime;
first = true;
}
if(current2 == stopName)
{
mStopTime = iter->second;
if(first)
break;
}
}
} }
if(!first) else if(startloop.size() <= strlen &&
((striter=std::mismatch(strpos, strend, startloop.begin(), checklow()).first) == strend ||
*striter == '\r' || *striter == '\n'))
{ {
startName = groupname + ": start"; times->mLoopStart = iter->first;
stopName = groupname + ": stop";
for(std::map<std::string, float>::iterator iter = mTextmappings->begin(); iter != mTextmappings->end(); iter++)
{
std::string current = iter->first.substr(0, startName.size());
std::transform(current.begin(), current.end(), current.begin(), ::tolower);
std::string current2 = iter->first.substr(0, stopName.size());
std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower);
if(current == startName)
{
mStartTime = iter->second;
mAnimate = loops;
mTime = mStartTime;
first = true;
}
if(current2 == stopName)
{
mStopTime = iter->second;
if(first)
break;
}
}
} }
else if(stoploop.size() <= strlen &&
((striter=std::mismatch(strpos, strend, stoploop.begin(), checklow()).first) == strend ||
*striter == '\r' || *striter == '\n'))
{
times->mLoopStop = iter->first;
}
else if(stop.size() <= strlen &&
((striter=std::mismatch(strpos, strend, stop.begin(), checklow()).first) == strend ||
*striter == '\r' || *striter == '\n'))
{
times->mStop = iter->first;
if(times->mLoopStop < 0.0f)
times->mLoopStop = iter->first;
break;
}
strpos = std::find(strpos+1, strend, '\n');
while(strpos != strend && *strpos == '\n')
strpos++;
} }
} }
void Animation::stopScript() return (times->mStart >= 0.0f && times->mLoopStart >= 0.0f && times->mLoopStop >= 0.0f && times->mStop >= 0.0f);
}
void Animation::playGroup(std::string groupname, int mode, int loops)
{
GroupTimes times;
times.mLoops = loops;
if(groupname == "all")
{ {
mAnimate = 0; times.mStart = times.mLoopStart = 0.0f;
} times.mLoopStop = times.mStop = 0.0f;
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel) if(mEntityList.mSkelBase)
{
mShapeNumber = 0;
if (allshapes == NULL || creaturemodel == NULL || skel == NULL)
return;
std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter;
for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++)
{ {
//std::map<unsigned short, PosAndRot> vecPosRot; Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
Ogre::AnimationStateIterator as = aset->getAnimationStateIterator();
Nif::NiTriShapeCopy& copy = *allshapesiter; while(as.hasMoreElements())
std::vector<Ogre::Vector3>* allvertices = &copy.vertices;
//std::set<unsigned int> vertices;
//std::set<unsigned int> normals;
//std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfovector = copy.boneinfo;
std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >* verticesToChange = &copy.vertsToWeights;
//std::cout << "Name " << copy.sname << "\n";
Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0);
Ogre::Real* pReal = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
std::vector<Ogre::Vector3> initialVertices = copy.morph.getInitialVertices();
//Each shape has multiple indices
if(initialVertices.size() )
{ {
if(copy.vertices.size() == initialVertices.size()) Ogre::AnimationState *state = as.getNext();
{ times.mLoopStop = times.mStop = state->getLength();
//Create if it doesn't already exist break;
if(mShapeIndexI.size() == static_cast<std::size_t> (mShapeNumber))
{
std::vector<int> vec;
mShapeIndexI.push_back(vec);
}
if(mTime >= copy.morph.getStartTime() && mTime <= copy.morph.getStopTime())
{
float x;
for (unsigned int i = 0; i < copy.morph.getAdditionalVertices().size(); i++)
{
int j = 0;
if(mShapeIndexI[mShapeNumber].size() <= i)
mShapeIndexI[mShapeNumber].push_back(0);
if(timeIndex(mTime,copy.morph.getRelevantTimes()[i],(mShapeIndexI[mShapeNumber])[i], j, x))
{
int indexI = (mShapeIndexI[mShapeNumber])[i];
std::vector<Ogre::Vector3> relevantData = (copy.morph.getRelevantData()[i]);
float v1 = relevantData[indexI].x;
float v2 = relevantData[j].x;
float t = v1 + (v2 - v1) * x;
if ( t < 0 )
t = 0;
if ( t > 1 )
t = 1;
if( t != 0 && initialVertices.size() == copy.morph.getAdditionalVertices()[i].size())
for (unsigned int v = 0; v < initialVertices.size(); v++)
initialVertices[v] += ((copy.morph.getAdditionalVertices()[i])[v]) * t;
}
}
allvertices = &initialVertices;
}
mShapeNumber++;
}
} }
}
}
else if(!findGroupTimes(groupname, &times))
throw std::runtime_error("Failed to find animation group "+groupname);
if(mode == 0 && mCurGroup.mLoops > 0)
mNextGroup = times;
else
{
mCurGroup = times;
mNextGroup = GroupTimes();
mTime = ((mode==2) ? mCurGroup.mLoopStart : mCurGroup.mStart);
}
}
if(verticesToChange->size() > 0) void Animation::skipAnim()
{
mSkipFrame = true;
}
void Animation::runAnimation(float timepassed)
{
if(mCurGroup.mLoops > 0 && !mSkipFrame)
{
mTime += timepassed;
if(mTime >= mCurGroup.mLoopStop)
{
if(mCurGroup.mLoops > 1)
{ {
mCurGroup.mLoops--;
for(std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >::iterator iter = verticesToChange->begin(); mTime = mTime - mCurGroup.mLoopStop + mCurGroup.mLoopStart;
iter != verticesToChange->end(); iter++)
{
std::vector<Nif::NiSkinData::IndividualWeight> inds = iter->second;
int verIndex = iter->first;
Ogre::Vector3 currentVertex = (*allvertices)[verIndex];
Nif::NiSkinData::BoneInfoCopy* boneinfocopy = &(allshapesiter->boneinfo[inds[0].boneinfocopyindex]);
Ogre::Bone *bonePtr = 0;
Ogre::Vector3 vecPos;
Ogre::Quaternion vecRot;
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot>::iterator result = mVecRotPos.find(boneinfocopy);
if(result == mVecRotPos.end())
{
bonePtr = skel->getBone(boneinfocopy->bonename);
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
PosAndRot both;
both.vecPos = vecPos;
both.vecRot = vecRot;
mVecRotPos[boneinfocopy] = both;
}
else
{
PosAndRot both = result->second;
vecPos = both.vecPos;
vecRot = both.vecRot;
}
Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight;
for(std::size_t i = 1; i < inds.size(); i++)
{
boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]);
result = mVecRotPos.find(boneinfocopy);
if(result == mVecRotPos.end())
{
bonePtr = skel->getBone(boneinfocopy->bonename);
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
PosAndRot both;
both.vecPos = vecPos;
both.vecRot = vecRot;
mVecRotPos[boneinfocopy] = both;
}
else
{
PosAndRot both = result->second;
vecPos = both.vecPos;
vecRot = both.vecRot;
}
absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight;
}
Ogre::Real* addr = (pReal + 3 * verIndex);
*addr = absVertPos.x;
*(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z;
}
} }
else else if(mTime >= mCurGroup.mStop)
{ {
//Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(copy.bonename); if(mNextGroup.mLoops > 0)
Ogre::Quaternion shaperot = copy.trafo.rotation; mTime = mTime - mCurGroup.mStop + mNextGroup.mStart;
Ogre::Vector3 shapetrans = copy.trafo.trans;
float shapescale = copy.trafo.scale;
std::vector<std::string> boneSequence = copy.boneSequence;
Ogre::Vector3 transmult;
Ogre::Quaternion rotmult;
float scale;
if(boneSequence.size() > 0)
{
std::vector<std::string>::iterator boneSequenceIter = boneSequence.begin();
if(skel->hasBone(*boneSequenceIter))
{
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
transmult = bonePtr->getPosition();
rotmult = bonePtr->getOrientation();
scale = bonePtr->getScale().x;
boneSequenceIter++;
for(; boneSequenceIter != boneSequence.end(); boneSequenceIter++)
{
if(skel->hasBone(*boneSequenceIter))
{
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
// Computes C = B + AxC*scale
transmult = transmult + rotmult * bonePtr->getPosition();
rotmult = rotmult * bonePtr->getOrientation();
scale = scale * bonePtr->getScale().x;
}
//std::cout << "Bone:" << *boneSequenceIter << " ";
}
transmult = transmult + rotmult * shapetrans;
rotmult = rotmult * shaperot;
scale = shapescale * scale;
//std::cout << "Position: " << transmult << "Rotation: " << rotmult << "\n";
}
}
else else
{ mTime = mCurGroup.mStop;
transmult = shapetrans; mCurGroup = mNextGroup;
rotmult = shaperot; mNextGroup = GroupTimes();
scale = shapescale;
}
// Computes C = B + AxC*scale
// final_vector = old_vector + old_rotation*new_vector*old_scale/
for(unsigned int i = 0; i < allvertices->size(); i++)
{
Ogre::Vector3 current = transmult + rotmult * (*allvertices)[i];
Ogre::Real* addr = pReal + i * 3;
*addr = current.x;
*(addr+1) = current.y;
*(addr + 2) = current.z;
}/*
for(int i = 0; i < allnormals.size(); i++){
Ogre::Vector3 current =rotmult * allnormals[i];
Ogre::Real* addr = pRealNormal + i * 3;
*addr = current.x;
*(addr+1) = current.y;
*(addr + 2) = current.z;
}*/
} }
vbuf->unlock();
} }
} if(mEntityList.mSkelBase)
bool Animation::timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x )
{
int count;
if ( (count = times.size()) > 0 )
{ {
if ( time <= times[0] ) Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
Ogre::AnimationStateIterator as = aset->getAnimationStateIterator();
while(as.hasMoreElements())
{ {
i = j = 0; Ogre::AnimationState *state = as.getNext();
x = 0.0; state->setTimePosition(mTime);
return true;
}
if ( time >= times[count - 1] )
{
i = j = count - 1;
x = 0.0;
return true;
}
if ( i < 0 || i >= count )
i = 0;
float tI = times[i];
if ( time > tI )
{
j = i + 1;
float tJ;
while ( time >= ( tJ = times[j]) )
{
i = j++;
tI = tJ;
}
x = ( time - tI ) / ( tJ - tI );
return true;
}
else if ( time < tI )
{
j = i - 1;
float tJ;
while ( time <= ( tJ = times[j] ) )
{
i = j--;
tI = tJ;
}
x = ( time - tI ) / ( tJ - tI );
return true;
}
else
{
j = i;
x = 0.0;
return true;
} }
} }
else
return false;
}
void Animation::handleAnimationTransforms()
{
Ogre::SkeletonInstance* skel = mBase->getSkeleton();
Ogre::Bone* b = skel->getRootBone();
b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3)); //This is a trick
skel->_updateTransforms();
//skel->_notifyManualBonesDirty();
mBase->getAllAnimationStates()->_notifyDirty();
//mBase->_updateAnimation();
//mBase->_notifyMoved();
std::vector<Nif::NiKeyframeData>::iterator iter;
int slot = 0;
if(mTransformations)
{
for(iter = mTransformations->begin(); iter != mTransformations->end(); iter++)
{
if(mTime < iter->getStartTime() || mTime < mStartTime || mTime > iter->getStopTime())
{
slot++;
continue;
}
float x;
float x2;
const std::vector<Ogre::Quaternion> & quats = iter->getQuat();
const std::vector<float> & ttime = iter->gettTime();
const std::vector<float> & rtime = iter->getrTime();
int rindexJ = mRindexI[slot];
timeIndex(mTime, rtime, mRindexI[slot], rindexJ, x2);
int tindexJ = mTindexI[slot];
const std::vector<Ogre::Vector3> & translist1 = iter->getTranslist1();
timeIndex(mTime, ttime, mTindexI[slot], tindexJ, x);
Ogre::Vector3 t;
Ogre::Quaternion r;
bool bTrans = translist1.size() > 0;
bool bQuats = quats.size() > 0;
if(skel->hasBone(iter->getBonename()))
{
Ogre::Bone* bone = skel->getBone(iter->getBonename());
if(bTrans)
{
Ogre::Vector3 v1 = translist1[mTindexI[slot]];
Ogre::Vector3 v2 = translist1[tindexJ];
t = (v1 + (v2 - v1) * x);
bone->setPosition(t);
}
if(bQuats)
{
r = Ogre::Quaternion::Slerp(x2, quats[mRindexI[slot]], quats[rindexJ], true);
bone->setOrientation(r);
}
}
slot++;
}
skel->_updateTransforms();
mBase->getAllAnimationStates()->_notifyDirty();
}
} }
mSkipFrame = false;
}
} }

View file

@ -1,6 +1,9 @@
#ifndef _GAME_RENDER_ANIMATION_H #ifndef _GAME_RENDER_ANIMATION_H
#define _GAME_RENDER_ANIMATION_H #define _GAME_RENDER_ANIMATION_H
#include <vector>
#include <components/nifogre/ogre_nif_loader.hpp>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include "../mwworld/actiontalk.hpp" #include "../mwworld/actiontalk.hpp"
#include <components/nif/node.hpp> #include <components/nif/node.hpp>
@ -8,53 +11,47 @@
namespace MWRender{
struct PosAndRot{ namespace MWRender {
Ogre::Quaternion vecRot;
Ogre::Vector3 vecPos;
};
class Animation{ class Animation {
struct GroupTimes {
float mStart;
float mStop;
float mLoopStart;
float mLoopStop;
protected: size_t mLoops;
GroupTimes()
: mStart(-1.0f), mStop(-1.0f), mLoopStart(-1.0f), mLoopStop(-1.0f),
mLoops(0)
{ }
};
protected:
Ogre::SceneNode* mInsert; Ogre::SceneNode* mInsert;
OEngine::Render::OgreRenderer &mRend; OEngine::Render::OgreRenderer &mRend;
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot> mVecRotPos;
static std::map<std::string, int> sUniqueIDs;
float mTime; float mTime;
float mStartTime; GroupTimes mCurGroup;
float mStopTime; GroupTimes mNextGroup;
int mAnimate;
//Represents a rotation index for each bone
std::vector<int>mRindexI;
//Represents a translation index for each bone
std::vector<int>mTindexI;
//Only shapes with morphing data will use a shape number bool mSkipFrame;
int mShapeNumber;
std::vector<std::vector<int> > mShapeIndexI;
//Ogre::SkeletonInstance* skel; NifOgre::EntityList mEntityList;
std::vector<Nif::NiTriShapeCopy>* mShapes; //All the NiTriShapeData for a creature NifOgre::TextKeyMap mTextKeys;
std::vector<Nif::NiKeyframeData>* mTransformations; bool findGroupTimes(const std::string &groupname, GroupTimes *times);
std::map<std::string,float>* mTextmappings;
Ogre::Entity* mBase;
void handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel);
void handleAnimationTransforms();
bool timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x );
std::string getUniqueID(std::string mesh);
public: public:
Animation(OEngine::Render::OgreRenderer& _rend); Animation(OEngine::Render::OgreRenderer& _rend);
virtual void runAnimation(float timepassed) = 0; virtual ~Animation();
void startScript(std::string groupname, int mode, int loops);
void stopScript();
virtual ~Animation();
void playGroup(std::string groupname, int mode, int loops);
void skipAnim();
virtual void runAnimation(float timepassed);
}; };
} }
#endif #endif

View file

@ -24,75 +24,54 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::O
assert (ref->base != NULL); assert (ref->base != NULL);
if(!ref->base->model.empty()) if(!ref->base->model.empty())
{ {
const std::string &mesh = "meshes\\" + ref->base->model; std::string mesh = "meshes\\" + ref->base->model;
std::string meshNumbered = mesh + getUniqueID(mesh) + ">|";
NifOgre::NIFLoader::load(meshNumbered);
mBase = mRend.getScene()->createEntity(meshNumbered);
mBase->setVisibilityFlags(RV_Actors);
bool transparent = false; mEntityList = NifOgre::NIFLoader::createEntities(mInsert, &mTextKeys, mesh);
for (unsigned int i=0; i < mBase->getNumSubEntities(); ++i) for(size_t i = 0;i < mEntityList.mEntities.size();i++)
{ {
Ogre::MaterialPtr mat = mBase->getSubEntity(i)->getMaterial(); Ogre::Entity *ent = mEntityList.mEntities[i];
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); ent->setVisibilityFlags(RV_Actors);
while (techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false) bool transparent = false;
transparent = true; for (unsigned int j=0;j < ent->getNumSubEntities() && !transparent; ++j)
{
Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements() && !transparent)
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements() && !transparent)
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
}
} }
} }
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
} }
mBase->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
std::string meshZero = mesh + "0000>|"; if(mEntityList.mSkelBase)
if((mTransformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero)))
{ {
for(std::size_t init = 0; init < mTransformations->size(); init++) Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
Ogre::AnimationStateIterator as = aset->getAnimationStateIterator();
while(as.hasMoreElements())
{ {
mRindexI.push_back(0); Ogre::AnimationState *state = as.getNext();
mTindexI.push_back(0); state->setEnabled(true);
state->setLoop(false);
} }
mStopTime = mTransformations->begin()->getStopTime();
mStartTime = mTransformations->begin()->getStartTime();
mShapes = (NIFLoader::getSingletonPtr())->getShapes(meshZero);
} }
mTextmappings = NIFLoader::getSingletonPtr()->getTextIndices(meshZero);
mInsert->attachObject(mBase);
} }
} }
void CreatureAnimation::runAnimation(float timepassed) void CreatureAnimation::runAnimation(float timepassed)
{ {
mVecRotPos.clear(); // Placeholder
if(mAnimate > 0)
{
//Add the amount of time passed to time
//Handle the animation transforms dependent on time Animation::runAnimation(timepassed);
//Handle the shapes dependent on animation transforms
mTime += timepassed;
if(mTime >= mStopTime)
{
mAnimate--;
//std::cout << "Stopping the animation\n";
if(mAnimate == 0)
mTime = mStopTime;
else
mTime = mStartTime + (mTime - mStopTime);
}
handleAnimationTransforms();
handleShapes(mShapes, mBase, mBase->getSkeleton());
}
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -14,42 +14,37 @@ class NpcAnimation: public Animation{
private: private:
MWWorld::InventoryStore& mInv; MWWorld::InventoryStore& mInv;
int mStateID; int mStateID;
//Free Parts
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mChest;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mSkirt;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mLhand;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mRhand;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mTail;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mLFreeFoot;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mRFreeFoot;
int mPartslots[27]; //Each part slot is taken by clothing, armor, or is empty int mPartslots[27]; //Each part slot is taken by clothing, armor, or is empty
int mPartPriorities[27]; int mPartPriorities[27];
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> mZero;
//Bounded Parts //Bounded Parts
Ogre::Entity* lclavicle; NifOgre::EntityList lclavicle;
Ogre::Entity* rclavicle; NifOgre::EntityList rclavicle;
Ogre::Entity* rupperArm; NifOgre::EntityList rupperArm;
Ogre::Entity* lupperArm; NifOgre::EntityList lupperArm;
Ogre::Entity* rUpperLeg; NifOgre::EntityList rUpperLeg;
Ogre::Entity* lUpperLeg; NifOgre::EntityList lUpperLeg;
Ogre::Entity* lForearm; NifOgre::EntityList lForearm;
Ogre::Entity* rForearm; NifOgre::EntityList rForearm;
Ogre::Entity* lWrist; NifOgre::EntityList lWrist;
Ogre::Entity* rWrist; NifOgre::EntityList rWrist;
Ogre::Entity* rKnee; NifOgre::EntityList rKnee;
Ogre::Entity* lKnee; NifOgre::EntityList lKnee;
Ogre::Entity* neck; NifOgre::EntityList neck;
Ogre::Entity* rAnkle; NifOgre::EntityList rAnkle;
Ogre::Entity* lAnkle; NifOgre::EntityList lAnkle;
Ogre::Entity* groin; NifOgre::EntityList groin;
Ogre::Entity* lfoot; NifOgre::EntityList skirt;
Ogre::Entity* rfoot; NifOgre::EntityList lfoot;
Ogre::Entity* hair; NifOgre::EntityList rfoot;
Ogre::Entity* head; NifOgre::EntityList hair;
NifOgre::EntityList rHand;
NifOgre::EntityList lHand;
NifOgre::EntityList head;
NifOgre::EntityList chest;
NifOgre::EntityList tail;
Ogre::SceneNode* insert;
bool isBeast; bool isBeast;
bool isFemale; bool isFemale;
std::string headModel; std::string headModel;
@ -73,18 +68,17 @@ private:
public: public:
NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv);
virtual ~NpcAnimation(); virtual ~NpcAnimation();
Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); NifOgre::EntityList insertBoundedPart(const std::string &mesh, const std::string &bonename);
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> insertFreePart(const std::string &mesh, const std::string& suffix);
void insertFootPart(int type, const std::string &mesh);
virtual void runAnimation(float timepassed); virtual void runAnimation(float timepassed);
void updateParts(); void updateParts();
void removeEntities(NifOgre::EntityList &entities);
void removeIndividualPart(int type); void removeIndividualPart(int type);
void reserveIndividualPart(int type, int group, int priority); void reserveIndividualPart(int type, int group, int priority);
bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh);
void removePartGroup(int group); void removePartGroup(int group);
void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts); void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts);
}; };
} }
#endif #endif

View file

@ -92,11 +92,16 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
assert(insert); assert(insert);
NifOgre::NIFLoader::load(mesh); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh); NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(insert, NULL, mesh);
for(size_t i = 0;i < entities.mEntities.size();i++)
{
Ogre::Vector3 extents = ent->getBoundingBox().getSize(); const Ogre::AxisAlignedBox &tmp = entities.mEntities[i]->getBoundingBox();
bounds.merge(Ogre::AxisAlignedBox(insert->_getDerivedPosition() + tmp.getMinimum(),
insert->_getDerivedPosition() + tmp.getMaximum())
);
}
Ogre::Vector3 extents = bounds.getSize();
extents *= insert->getScale(); extents *= insert->getScale();
float size = std::max(std::max(extents.x, extents.y), extents.z); float size = std::max(std::max(extents.x, extents.y), extents.z);
@ -108,42 +113,41 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
if (mBounds.find(ptr.getCell()) == mBounds.end()) if (mBounds.find(ptr.getCell()) == mBounds.end())
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
Ogre::AxisAlignedBox bounds = ent->getBoundingBox();
bounds = Ogre::AxisAlignedBox(
insert->_getDerivedPosition() + bounds.getMinimum(),
insert->_getDerivedPosition() + bounds.getMaximum()
);
bounds.scale(insert->getScale());
mBounds[ptr.getCell()].merge(bounds); mBounds[ptr.getCell()].merge(bounds);
bool transparent = false; bool transparent = false;
for (unsigned int i=0; i<ent->getNumSubEntities(); ++i) for(size_t i = 0;i < entities.mEntities.size();i++)
{ {
Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial(); Ogre::Entity *ent = entities.mEntities[i];
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); for (unsigned int i=0; i<ent->getNumSubEntities(); ++i)
while (techIt.hasMoreElements())
{ {
Ogre::Technique* tech = techIt.getNext(); Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial();
Ogre::Technique::PassIterator passIt = tech->getPassIterator(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (passIt.hasMoreElements()) while (techIt.hasMoreElements())
{ {
Ogre::Pass* pass = passIt.getNext(); Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false) if (pass->getDepthWriteEnabled() == false)
transparent = true; transparent = true;
}
} }
} }
} }
if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent) if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent)
{ {
insert->attachObject(ent); for(size_t i = 0;i < entities.mEntities.size();i++)
{
Ogre::Entity *ent = entities.mEntities[i];
ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
} }
else else
{ {
@ -183,15 +187,20 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
// - there will be too many batches. // - there will be too many batches.
sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500));
sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics);
sg->setCastShadows(true); sg->setCastShadows(true);
sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
mRenderer.getScene()->destroyEntity(ent); for(size_t i = 0;i < entities.mEntities.size();i++)
{
Ogre::Entity *ent = entities.mEntities[i];
insert->detachObject(ent);
sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
mRenderer.getScene()->destroyEntity(ent);
}
} }
} }

View file

@ -72,6 +72,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
else else
lang = sh::Language_CG; lang = sh::Language_CG;
mFactory->setCurrentLanguage (lang); mFactory->setCurrentLanguage (lang);
mFactory->loadAllFiles();
//The fog type must be set before any terrain objects are created as if the //The fog type must be set before any terrain objects are created as if the
//fog type is set to FOG_NONE then the initially created terrain won't have any fog //fog type is set to FOG_NONE then the initially created terrain won't have any fog
@ -110,6 +111,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
sh::Factory::getInstance ().setGlobalSetting ("fog", "true"); sh::Factory::getInstance ().setGlobalSetting ("fog", "true");
sh::Factory::getInstance ().setGlobalSetting ("lighting", "true"); sh::Factory::getInstance ().setGlobalSetting ("lighting", "true");
sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects")); sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects"));
sh::Factory::getInstance ().setGlobalSetting ("terrain_num_lights", Settings::Manager::getString ("num lights", "Terrain"));
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water")); sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water"));
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");

View file

@ -287,6 +287,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
void SkyManager::create() void SkyManager::create()
{ {
assert(!mCreated);
sh::Factory::getInstance().setSharedParameter ("cloudBlendFactor", sh::Factory::getInstance().setSharedParameter ("cloudBlendFactor",
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
sh::Factory::getInstance().setSharedParameter ("cloudOpacity", sh::Factory::getInstance().setSharedParameter ("cloudOpacity",
@ -302,7 +304,7 @@ void SkyManager::create()
sh::Factory::getInstance().setTextureAlias ("cloud_texture_1", ""); sh::Factory::getInstance().setTextureAlias ("cloud_texture_1", "");
sh::Factory::getInstance().setTextureAlias ("cloud_texture_2", ""); sh::Factory::getInstance().setTextureAlias ("cloud_texture_2", "");
// Create overlay used for thunderstorm // Create light used for thunderstorm
mLightning = mSceneMgr->createLight(); mLightning = mSceneMgr->createLight();
mLightning->setType (Ogre::Light::LT_DIRECTIONAL); mLightning->setType (Ogre::Light::LT_DIRECTIONAL);
mLightning->setDirection (Ogre::Vector3(0.3, -0.7, 0.3)); mLightning->setDirection (Ogre::Vector3(0.3, -0.7, 0.3));
@ -324,52 +326,57 @@ void SkyManager::create()
mSunGlare->setVisibilityFlags(RV_NoReflection); mSunGlare->setVisibilityFlags(RV_NoReflection);
// Stars // Stars
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
night1_ent->setVisibilityFlags(RV_Sky);
night1_ent->setCastShadows(false);
mAtmosphereNight = mRootNode->createChildSceneNode(); mAtmosphereNight = mRootNode->createChildSceneNode();
mAtmosphereNight->attachObject(night1_ent); NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(mAtmosphereNight, NULL, "meshes\\sky_night_01.nif");
for(size_t i = 0, matidx = 0;i < entities.mEntities.size();i++)
for (unsigned int i=0; i<night1_ent->getNumSubEntities(); ++i)
{ {
std::string matName = "openmw_stars_" + boost::lexical_cast<std::string>(i); Entity* night1_ent = entities.mEntities[i];
sh::MaterialInstance* m = sh::Factory::getInstance ().createMaterialInstance (matName, "openmw_stars"); night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
night1_ent->setVisibilityFlags(RV_Sky);
night1_ent->setCastShadows(false);
std::string textureName = sh::retrieveValue<sh::StringValue>( for (unsigned int j=0; j<night1_ent->getNumSubEntities(); ++j)
sh::Factory::getInstance().getMaterialInstance(night1_ent->getSubEntity (i)->getMaterialName ())->getProperty("diffuseMap"), NULL).get(); {
std::string matName = "openmw_stars_" + boost::lexical_cast<std::string>(matidx++);
sh::MaterialInstance* m = sh::Factory::getInstance().createMaterialInstance(matName, "openmw_stars");
m->setProperty ("texture", sh::makeProperty<sh::StringValue>(new sh::StringValue(textureName))); std::string textureName = sh::retrieveValue<sh::StringValue>(
sh::Factory::getInstance().getMaterialInstance(night1_ent->getSubEntity(j)->getMaterialName())->getProperty("diffuseMap"), NULL).get();
night1_ent->getSubEntity(i)->setMaterialName (matName); m->setProperty("texture", sh::makeProperty<sh::StringValue>(new sh::StringValue(textureName)));
night1_ent->getSubEntity(j)->setMaterialName(matName);
}
} }
// Atmosphere (day) // Atmosphere (day)
mesh = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif");
Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif");
atmosphere_ent->setCastShadows(false);
ModVertexAlpha(atmosphere_ent, 0);
atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
atmosphere_ent->setVisibilityFlags(RV_Sky);
mAtmosphereDay = mRootNode->createChildSceneNode(); mAtmosphereDay = mRootNode->createChildSceneNode();
mAtmosphereDay->attachObject(atmosphere_ent); entities = NifOgre::NIFLoader::createEntities(mAtmosphereDay, NULL, "meshes\\sky_atmosphere.nif");
atmosphere_ent->getSubEntity (0)->setMaterialName ("openmw_atmosphere"); for(size_t i = 0;i < entities.mEntities.size();i++)
{
Entity* atmosphere_ent = entities.mEntities[i];
atmosphere_ent->setCastShadows(false);
atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
atmosphere_ent->setVisibilityFlags(RV_Sky);
atmosphere_ent->getSubEntity (0)->setMaterialName ("openmw_atmosphere");
ModVertexAlpha(atmosphere_ent, 0);
}
// Clouds // Clouds
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif");
clouds_ent->setVisibilityFlags(RV_Sky);
clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
SceneNode* clouds_node = mRootNode->createChildSceneNode(); SceneNode* clouds_node = mRootNode->createChildSceneNode();
clouds_node->attachObject(clouds_ent); entities = NifOgre::NIFLoader::createEntities(clouds_node, NULL, "meshes\\sky_clouds_01.nif");
clouds_ent->getSubEntity(0)->setMaterialName ("openmw_clouds"); for(size_t i = 0;i < entities.mEntities.size();i++)
clouds_ent->setCastShadows(false); {
Entity* clouds_ent = entities.mEntities[i];
clouds_ent->setVisibilityFlags(RV_Sky);
clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
clouds_ent->getSubEntity(0)->setMaterialName ("openmw_clouds");
clouds_ent->setCastShadows(false);
ModVertexAlpha(clouds_ent, 1); ModVertexAlpha(clouds_ent, 1);
}
mCreated = true; mCreated = true;
} }

View file

@ -1,6 +1,8 @@
#ifndef _GAME_RENDER_SKY_H #ifndef _GAME_RENDER_SKY_H
#define _GAME_RENDER_SKY_H #define _GAME_RENDER_SKY_H
#include <vector>
#include <OgreVector3.h> #include <OgreVector3.h>
#include <OgreString.h> #include <OgreString.h>
#include <OgreMaterial.h> #include <OgreMaterial.h>
@ -9,7 +11,7 @@
#include <extern/shiny/Main/Factory.hpp> #include <extern/shiny/Main/Factory.hpp>
#include "sky.hpp"
#include "../mwworld/weather.hpp" #include "../mwworld/weather.hpp"
namespace Ogre namespace Ogre

View file

@ -0,0 +1,24 @@
#include "consoleextensions.hpp"
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
namespace MWScript
{
namespace Console
{
void registerExtensions (Compiler::Extensions& extensions)
{
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
}
}
}

View file

@ -0,0 +1,25 @@
#ifndef GAME_SCRIPT_CONSOLEEXTENSIONS_H
#define GAME_SCRIPT_CONSOLEEXTENSIONS_H
namespace Compiler
{
class Extensions;
}
namespace Interpreter
{
class Interpreter;
}
namespace MWScript
{
/// \brief Script functionality limited to the console
namespace Console
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
}
}
#endif

View file

@ -169,5 +169,14 @@ op 0x2000164: SetScale
op 0x2000165: SetScale, explicit reference op 0x2000165: SetScale, explicit reference
op 0x2000166: SetAngle op 0x2000166: SetAngle
op 0x2000167: SetAngle, explicit reference op 0x2000167: SetAngle, explicit reference
opcodes 0x2000168-0x3ffffff unused op 0x2000168: GetScale
op 0x2000169: GetScale, explicit reference
op 0x200016a: GetAngle
op 0x200016b: GetAngle, explicit reference
op 0x200016c: user1 (console only, requires --script-console switch)
op 0x200016d: user2 (console only, requires --script-console switch)
op 0x200016e: user3, explicit reference (console only, requires --script-console switch)
op 0x200016f: user3 (implicit reference, console only, requires --script-console switch)
op 0x2000170: user4, explicit reference (console only, requires --script-console switch)
op 0x2000171: user4 (implicit reference, console only, requires --script-console switch)
opcodes 0x2000172-0x3ffffff unused

View file

@ -16,10 +16,12 @@
#include "dialogueextensions.hpp" #include "dialogueextensions.hpp"
#include "animationextensions.hpp" #include "animationextensions.hpp"
#include "transformationextensions.hpp" #include "transformationextensions.hpp"
#include "consoleextensions.hpp"
#include "userextensions.hpp"
namespace MWScript namespace MWScript
{ {
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions, bool consoleOnly)
{ {
Cell::registerExtensions (extensions); Cell::registerExtensions (extensions);
Misc::registerExtensions (extensions); Misc::registerExtensions (extensions);
@ -33,9 +35,15 @@ namespace MWScript
Dialogue::registerExtensions (extensions); Dialogue::registerExtensions (extensions);
Animation::registerExtensions (extensions); Animation::registerExtensions (extensions);
Transformation::registerExtensions (extensions); Transformation::registerExtensions (extensions);
if (consoleOnly)
{
Console::registerExtensions (extensions);
User::registerExtensions (extensions);
}
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly)
{ {
Interpreter::installOpcodes (interpreter); Interpreter::installOpcodes (interpreter);
Cell::installOpcodes (interpreter); Cell::installOpcodes (interpreter);
@ -50,5 +58,11 @@ namespace MWScript
Dialogue::installOpcodes (interpreter); Dialogue::installOpcodes (interpreter);
Animation::installOpcodes (interpreter); Animation::installOpcodes (interpreter);
Transformation::installOpcodes (interpreter); Transformation::installOpcodes (interpreter);
if (consoleOnly)
{
Console::installOpcodes (interpreter);
User::installOpcodes (interpreter);
}
} }
} }

View file

@ -13,9 +13,11 @@ namespace Interpreter
namespace MWScript namespace MWScript
{ {
void registerExtensions (Compiler::Extensions& extensions); void registerExtensions (Compiler::Extensions& extensions, bool consoleOnly = false);
///< \param consoleOnly include console only extensions
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly = false);
///< \param consoleOnly include console only opcodes
} }
#endif #endif

View file

@ -10,6 +10,7 @@
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwgui/window_manager.hpp" #include "../mwgui/window_manager.hpp"
@ -236,7 +237,7 @@ namespace MWScript
if (!mAction.get()) if (!mAction.get())
throw std::runtime_error ("activation failed, because no action to perform"); throw std::runtime_error ("activation failed, because no action to perform");
mAction->execute(); mAction->execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
mActivationHandled = true; mActivationHandled = true;
} }

View file

@ -0,0 +1,91 @@
#include "userextensions.hpp"
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
#include <components/interpreter/context.hpp>
#include "ref.hpp"
namespace MWScript
{
/// Temporary script extensions.
///
/// \attention Do not commit changes to this file to a git repository!
namespace User
{
class OpUser1 : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.getContext().report ("user1: not in use");
}
};
class OpUser2 : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.getContext().report ("user2: not in use");
}
};
template<class R>
class OpUser3 : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
// MWWorld::Ptr ptr = R()(runtime);
runtime.getContext().report ("user3: not in use");
}
};
template<class R>
class OpUser4 : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
// MWWorld::Ptr ptr = R()(runtime);
runtime.getContext().report ("user4: not in use");
}
};
const int opcodeUser1 = 0x200016c;
const int opcodeUser2 = 0x200016d;
const int opcodeUser3 = 0x200016e;
const int opcodeUser3Explicit = 0x200016f;
const int opcodeUser4 = 0x2000170;
const int opcodeUser4Explicit = 0x2000171;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("user1", "", opcodeUser1);
extensions.registerInstruction ("user2", "", opcodeUser2);
extensions.registerInstruction ("user3", "", opcodeUser3, opcodeUser3);
extensions.registerInstruction ("user4", "", opcodeUser4, opcodeUser4);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (opcodeUser1, new OpUser1);
interpreter.installSegment5 (opcodeUser2, new OpUser2);
interpreter.installSegment5 (opcodeUser3, new OpUser3<ImplicitRef>);
interpreter.installSegment5 (opcodeUser3Explicit, new OpUser3<ExplicitRef>);
interpreter.installSegment5 (opcodeUser4, new OpUser4<ImplicitRef>);
interpreter.installSegment5 (opcodeUser4Explicit, new OpUser4<ExplicitRef>);
}
}
}

View file

@ -0,0 +1,25 @@
#ifndef GAME_SCRIPT_USEREXTENSIONS_H
#define GAME_SCRIPT_USEREXTENSIONS_H
namespace Compiler
{
class Extensions;
}
namespace Interpreter
{
class Interpreter;
}
namespace MWScript
{
/// \brief Temporaty script functionality limited to the console
namespace User
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
}
}
#endif

View file

@ -0,0 +1,24 @@
#include "action.hpp"
#include "../mwbase/environment.hpp"
#include "../mwsound/soundmanager.hpp"
MWWorld::Action::Action() {}
MWWorld::Action::~Action() {}
void MWWorld::Action::execute (const Ptr& actor)
{
if (!mSoundId.empty())
MWBase::Environment::get().getSoundManager()->playSound3D (actor, mSoundId, 1.0, 1.0,
MWSound::Play_NoTrack);
executeImp (actor);
}
void MWWorld::Action::setSound (const std::string& id)
{
mSoundId = id;
}

View file

@ -1,22 +1,32 @@
#ifndef GAME_MWWORLD_ACTION_H #ifndef GAME_MWWORLD_ACTION_H
#define GAME_MWWORLD_ACTION_H #define GAME_MWWORLD_ACTION_H
#include <string>
namespace MWWorld namespace MWWorld
{ {
class Ptr;
/// \brief Abstract base for actions /// \brief Abstract base for actions
class Action class Action
{ {
std::string mSoundId;
// not implemented // not implemented
Action (const Action& action); Action (const Action& action);
Action& operator= (const Action& action); Action& operator= (const Action& action);
virtual void executeImp (const Ptr& actor) = 0;
public: public:
Action() {} Action();
virtual ~Action() {} virtual ~Action();
virtual void execute() = 0; void execute (const Ptr& actor);
void setSound (const std::string& id);
}; };
} }

View file

@ -5,7 +5,7 @@
namespace MWWorld namespace MWWorld
{ {
void ActionAlchemy::execute() void ActionAlchemy::executeImp (const Ptr& actor)
{ {
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Alchemy); MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Alchemy);
} }

View file

@ -7,8 +7,7 @@ namespace MWWorld
{ {
class ActionAlchemy : public Action class ActionAlchemy : public Action
{ {
public: virtual void executeImp (const Ptr& actor);
virtual void execute ();
}; };
} }

View file

@ -5,24 +5,24 @@
namespace MWWorld namespace MWWorld
{ {
ActionApply::ActionApply (const Ptr& target, const std::string& id, const Ptr& actor) ActionApply::ActionApply (const Ptr& target, const std::string& id)
: mTarget (target), mId (id), mActor (actor) : mTarget (target), mId (id)
{} {}
void ActionApply::execute() void ActionApply::executeImp (const Ptr& actor)
{ {
MWWorld::Class::get (mTarget).apply (mTarget, mId, mActor); MWWorld::Class::get (mTarget).apply (mTarget, mId, actor);
} }
ActionApplyWithSkill::ActionApplyWithSkill (const Ptr& target, const std::string& id, ActionApplyWithSkill::ActionApplyWithSkill (const Ptr& target, const std::string& id,
const Ptr& actor, int skillIndex, int usageType) int skillIndex, int usageType)
: mTarget (target), mId (id), mActor (actor), mSkillIndex (skillIndex), mUsageType (usageType) : mTarget (target), mId (id), mSkillIndex (skillIndex), mUsageType (usageType)
{} {}
void ActionApplyWithSkill::execute() void ActionApplyWithSkill::executeImp (const Ptr& actor)
{ {
if (MWWorld::Class::get (mTarget).apply (mTarget, mId, mActor) && mUsageType!=-1) if (MWWorld::Class::get (mTarget).apply (mTarget, mId, actor) && mUsageType!=-1)
MWWorld::Class::get (mTarget).skillUsageSucceeded (mActor, mSkillIndex, mUsageType); MWWorld::Class::get (mTarget).skillUsageSucceeded (actor, mSkillIndex, mUsageType);
} }
} }

View file

@ -13,29 +13,27 @@ namespace MWWorld
{ {
Ptr mTarget; Ptr mTarget;
std::string mId; std::string mId;
Ptr mActor;
virtual void executeImp (const Ptr& actor);
public: public:
ActionApply (const Ptr& target, const std::string& id, const Ptr& actor); ActionApply (const Ptr& target, const std::string& id);
virtual void execute();
}; };
class ActionApplyWithSkill : public Action class ActionApplyWithSkill : public Action
{ {
Ptr mTarget; Ptr mTarget;
std::string mId; std::string mId;
Ptr mActor;
int mSkillIndex; int mSkillIndex;
int mUsageType; int mUsageType;
virtual void executeImp (const Ptr& actor);
public: public:
ActionApplyWithSkill (const Ptr& target, const std::string& id, const Ptr& actor, ActionApplyWithSkill (const Ptr& target, const std::string& id,
int skillIndex, int usageType); int skillIndex, int usageType);
virtual void execute();
}; };
} }

View file

@ -13,7 +13,7 @@ namespace MWWorld
{ {
} }
void ActionEquip::execute () void ActionEquip::executeImp (const Ptr& actor)
{ {
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player); MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player);

View file

@ -10,11 +10,11 @@ namespace MWWorld
{ {
Ptr mObject; Ptr mObject;
virtual void executeImp (const Ptr& actor);
public: public:
/// @param item to equip /// @param item to equip
ActionEquip (const Ptr& object); ActionEquip (const Ptr& object);
virtual void execute ();
}; };
} }

View file

@ -15,7 +15,7 @@ namespace MWWorld
mContainer = container; mContainer = container;
} }
void ActionOpen::execute () void ActionOpen::executeImp (const MWWorld::Ptr& actor)
{ {
if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory))
return; return;

View file

@ -12,10 +12,11 @@ namespace MWWorld
{ {
Ptr mContainer; Ptr mContainer;
virtual void executeImp (const MWWorld::Ptr& actor);
public: public:
ActionOpen (const Ptr& container); ActionOpen (const Ptr& container);
///< \param The Container the Player has activated. ///< \param The Container the Player has activated.
virtual void execute ();
}; };
} }

View file

@ -11,7 +11,7 @@ namespace MWWorld
{ {
} }
void ActionRead::execute () void ActionRead::executeImp (const MWWorld::Ptr& actor)
{ {
LiveCellRef<ESM::Book> *ref = mObject.get<ESM::Book>(); LiveCellRef<ESM::Book> *ref = mObject.get<ESM::Book>();

View file

@ -10,11 +10,11 @@ namespace MWWorld
{ {
Ptr mObject; // book or scroll to read Ptr mObject; // book or scroll to read
virtual void executeImp (const MWWorld::Ptr& actor);
public: public:
/// @param book or scroll to read /// @param book or scroll to read
ActionRead (const Ptr& object); ActionRead (const Ptr& object);
virtual void execute ();
}; };
} }

View file

@ -13,7 +13,7 @@ namespace MWWorld
{ {
ActionTake::ActionTake (const MWWorld::Ptr& object) : mObject (object) {} ActionTake::ActionTake (const MWWorld::Ptr& object) : mObject (object) {}
void ActionTake::execute() void ActionTake::executeImp (const Ptr& actor)
{ {
if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory))
return; return;

View file

@ -10,11 +10,11 @@ namespace MWWorld
{ {
MWWorld::Ptr mObject; MWWorld::Ptr mObject;
virtual void executeImp (const Ptr& actor);
public: public:
ActionTake (const MWWorld::Ptr& object); ActionTake (const MWWorld::Ptr& object);
virtual void execute();
}; };
} }

View file

@ -9,7 +9,7 @@ namespace MWWorld
{ {
ActionTalk::ActionTalk (const Ptr& actor) : mActor (actor) {} ActionTalk::ActionTalk (const Ptr& actor) : mActor (actor) {}
void ActionTalk::execute() void ActionTalk::executeImp (const Ptr& actor)
{ {
MWBase::Environment::get().getDialogueManager()->startDialogue (mActor); MWBase::Environment::get().getDialogueManager()->startDialogue (mActor);
} }

View file

@ -10,12 +10,12 @@ namespace MWWorld
{ {
Ptr mActor; Ptr mActor;
virtual void executeImp (const Ptr& actor);
public: public:
ActionTalk (const Ptr& actor); ActionTalk (const Ptr& actor);
///< \param actor The actor the player is talking to ///< \param actor The actor the player is talking to
virtual void execute();
}; };
} }

View file

@ -6,12 +6,12 @@
namespace MWWorld namespace MWWorld
{ {
ActionTeleportPlayer::ActionTeleportPlayer (const std::string& cellName, ActionTeleport::ActionTeleport (const std::string& cellName,
const ESM::Position& position) const ESM::Position& position)
: mCellName (cellName), mPosition (position) : mCellName (cellName), mPosition (position)
{} {}
void ActionTeleportPlayer::execute() void ActionTeleport::executeImp (const Ptr& actor)
{ {
if (mCellName.empty()) if (mCellName.empty())
MWBase::Environment::get().getWorld()->changeToExteriorCell (mPosition); MWBase::Environment::get().getWorld()->changeToExteriorCell (mPosition);

View file

@ -9,17 +9,17 @@
namespace MWWorld namespace MWWorld
{ {
class ActionTeleportPlayer : public Action class ActionTeleport : public Action
{ {
std::string mCellName; std::string mCellName;
ESM::Position mPosition; ESM::Position mPosition;
virtual void executeImp (const Ptr& actor);
public: public:
ActionTeleportPlayer (const std::string& cellName, const ESM::Position& position); ActionTeleport (const std::string& cellName, const ESM::Position& position);
///< If cellName is empty, an exterior cell is asumed. ///< If cellName is empty, an exterior cell is asumed.
virtual void execute();
}; };
} }

View file

@ -1,10 +1,14 @@
#include "cellstore.hpp" #include "cellstore.hpp"
#include <iostream> #include <iostream>
#include <components/esm_store/store.hpp> #include <components/esm_store/store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "ptr.hpp"
namespace MWWorld namespace MWWorld
{ {
CellStore::CellStore (const ESM::Cell *cell_) : cell (cell_), mState (State_Unloaded) CellStore::CellStore (const ESM::Cell *cell_) : cell (cell_), mState (State_Unloaded)

View file

@ -15,6 +15,8 @@ namespace ESMS
namespace MWWorld namespace MWWorld
{ {
class Ptr;
/// A reference to one object (of any type) in a cell. /// A reference to one object (of any type) in a cell.
/// ///
/// Constructing this with a CellRef instance in the constructor means that /// Constructing this with a CellRef instance in the constructor means that
@ -73,6 +75,11 @@ namespace MWWorld
return 0; return 0;
} }
LiveRef &insert(const LiveRef &item) {
list.push_back(item);
return list.back();
}
}; };
/// A storage struct for one single cell reference. /// A storage struct for one single cell reference.
@ -106,9 +113,9 @@ namespace MWWorld
CellRefList<ESM::Ingredient> ingreds; CellRefList<ESM::Ingredient> ingreds;
CellRefList<ESM::CreatureLevList> creatureLists; CellRefList<ESM::CreatureLevList> creatureLists;
CellRefList<ESM::ItemLevList> itemLists; CellRefList<ESM::ItemLevList> itemLists;
CellRefList<ESM::Light> lights; CellRefList<ESM::Light> lights;
CellRefList<ESM::Tool> lockpicks; CellRefList<ESM::Tool> lockpicks;
CellRefList<ESM::Miscellaneous> miscItems; CellRefList<ESM::Miscellaneous> miscItems;
CellRefList<ESM::NPC> npcs; CellRefList<ESM::NPC> npcs;
CellRefList<ESM::Probe> probes; CellRefList<ESM::Probe> probes;
CellRefList<ESM::Repair> repairs; CellRefList<ESM::Repair> repairs;

View file

@ -5,7 +5,10 @@
#include <OgreVector3.h> #include <OgreVector3.h>
#include <components/esm/defs.hpp>
#include "ptr.hpp" #include "ptr.hpp"
#include "refdata.hpp"
#include "nullaction.hpp" #include "nullaction.hpp"
#include "containerstore.hpp" #include "containerstore.hpp"
@ -212,4 +215,32 @@ namespace MWWorld
void Class::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const void Class::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const
{ {
} }
std::string Class::getModel(const MWWorld::Ptr &ptr) const
{
return "";
}
MWWorld::Ptr
Class::copyToCellImpl(const Ptr &ptr, CellStore &cell) const
{
throw std::runtime_error("unable to move class to cell");
}
MWWorld::Ptr
Class::copyToCell(const Ptr &ptr, CellStore &cell) const
{
Ptr newPtr = copyToCellImpl(ptr, cell);
return newPtr;
}
MWWorld::Ptr
Class::copyToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos) const
{
Ptr newPtr = copyToCell(ptr, cell);
newPtr.getRefData().getPosition() = pos;
return newPtr;
}
} }

View file

@ -31,12 +31,18 @@ namespace MWGui
struct ToolTipInfo; struct ToolTipInfo;
} }
namespace ESM
{
struct Position;
}
namespace MWWorld namespace MWWorld
{ {
class Ptr; class Ptr;
class ContainerStore; class ContainerStore;
class InventoryStore; class InventoryStore;
class PhysicsSystem; class PhysicsSystem;
class CellStore;
/// \brief Base class for referenceable esm records /// \brief Base class for referenceable esm records
class Class class Class
@ -51,6 +57,8 @@ namespace MWWorld
Class(); Class();
virtual Ptr copyToCellImpl(const Ptr &ptr, CellStore &cell) const;
public: public:
/// NPC-stances. /// NPC-stances.
@ -204,6 +212,14 @@ namespace MWWorld
virtual void adjustScale(const MWWorld::Ptr& ptr,float& scale) const; virtual void adjustScale(const MWWorld::Ptr& ptr,float& scale) const;
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const; virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual Ptr
copyToCell(const Ptr &ptr, CellStore &cell) const;
virtual Ptr
copyToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos) const;
}; };
} }

View file

@ -8,9 +8,7 @@ namespace MWWorld
/// \brief Action: do nothing /// \brief Action: do nothing
class NullAction : public Action class NullAction : public Action
{ {
public: virtual void executeImp (const Ptr& actor) {}
virtual void execute() {}
}; };
} }

View file

@ -14,6 +14,7 @@
#include "../mwbase/world.hpp" // FIXME #include "../mwbase/world.hpp" // FIXME
#include "ptr.hpp" #include "ptr.hpp"
#include "class.hpp"
using namespace Ogre; using namespace Ogre;
namespace MWWorld namespace MWWorld
@ -121,6 +122,22 @@ namespace MWWorld
return !(result.first == ""); return !(result.first == "");
} }
std::pair<bool, Ogre::Vector3>
PhysicsSystem::castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len)
{
Ogre::Ray ray = Ogre::Ray(orig, dir);
Ogre::Vector3 to = ray.getPoint(len);
btVector3 btFrom = btVector3(orig.x, orig.y, orig.z);
btVector3 btTo = btVector3(to.x, to.y, to.z);
std::pair<std::string, float> test = mEngine->rayTest(btFrom, btTo);
if (test.first == "") {
return std::make_pair(false, Ogre::Vector3());
}
return std::make_pair(true, ray.getPoint(len * test.second));
}
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY) std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY)
{ {
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay( Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
@ -348,21 +365,41 @@ namespace MWWorld
throw std::logic_error ("can't find player"); throw std::logic_error ("can't find player");
} }
void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){ void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
// unused addObject(
//Ogre::Vector3 objPos = node->getPosition(); node->getName(),
model,
node->getOrientation(),
node->getScale().x,
node->getPosition());
}
addObject (node->getName(), model, node->getOrientation(), void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){
node->getScale().x, node->getPosition()); Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
} addActor (node->getName(), model, node->getPosition());
}
void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){ bool PhysicsSystem::getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max)
Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); {
// std::cout << "Adding node with name" << node->getName(); std::string model = MWWorld::Class::get(ptr).getModel(ptr);
addActor (node->getName(), model, node->getPosition()); if (model.empty()) {
} return false;
}
btVector3 btMin, btMax;
float scale = ptr.getCellRef().scale;
mEngine->getObjectAABB(model, scale, btMin, btMax);
min.x = btMin.x();
min.y = btMin.y();
min.z = btMin.z();
max.x = btMax.x();
max.y = btMax.y();
max.z = btMax.z();
return true;
}
} }

View file

@ -54,6 +54,9 @@ namespace MWWorld
// cast ray, return true if it hit something // cast ray, return true if it hit something
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to); bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to);
std::pair<bool, Ogre::Vector3>
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY); std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY);
///< cast ray from the mouse, return true if it hit something and the first result (in OGRE coordinates) ///< cast ray from the mouse, return true if it hit something and the first result (in OGRE coordinates)
@ -65,6 +68,8 @@ namespace MWWorld
void setCurrentWater(bool hasWater, int waterHeight); void setCurrentWater(bool hasWater, int waterHeight);
bool getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max);
private: private:
OEngine::Render::OgreRenderer &mRender; OEngine::Render::OgreRenderer &mRender;
OEngine::Physic::PhysicEngine* mEngine; OEngine::Physic::PhysicEngine* mEngine;

View file

@ -9,8 +9,6 @@
#include "../mwgui/window_manager.hpp" #include "../mwgui/window_manager.hpp"
#include "../mwworld/manualref.hpp" /// FIXME
#include "player.hpp" #include "player.hpp"
#include "localscripts.hpp" #include "localscripts.hpp"
@ -334,137 +332,10 @@ namespace MWWorld
insertCellRefList(mRendering, cell.weapons, cell, *mPhysics); insertCellRefList(mRendering, cell.weapons, cell, *mPhysics);
} }
/// \todo this whole code needs major clean up, and doesn't belong in this class.
void Scene::insertObject (const Ptr& ptr, CellStore* cell)
{
std::string type = ptr.getTypeName();
MWWorld::Ptr newPtr;
// insert into the correct CellRefList
if (type == typeid(ESM::Potion).name())
{
MWWorld::LiveCellRef<ESM::Potion>* ref = ptr.get<ESM::Potion>();
cell->potions.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->potions.list.back(), cell);
}
else if (type == typeid(ESM::Apparatus).name())
{
MWWorld::LiveCellRef<ESM::Apparatus>* ref = ptr.get<ESM::Apparatus>();
cell->appas.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->appas.list.back(), cell);
}
else if (type == typeid(ESM::Armor).name())
{
MWWorld::LiveCellRef<ESM::Armor>* ref = ptr.get<ESM::Armor>();
cell->armors.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->armors.list.back(), cell);
}
else if (type == typeid(ESM::Book).name())
{
MWWorld::LiveCellRef<ESM::Book>* ref = ptr.get<ESM::Book>();
cell->books.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->books.list.back(), cell);
}
else if (type == typeid(ESM::Clothing).name())
{
MWWorld::LiveCellRef<ESM::Clothing>* ref = ptr.get<ESM::Clothing>();
cell->clothes.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->clothes.list.back(), cell);
}
else if (type == typeid(ESM::Ingredient).name())
{
MWWorld::LiveCellRef<ESM::Ingredient>* ref = ptr.get<ESM::Ingredient>();
cell->ingreds.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->ingreds.list.back(), cell);
}
else if (type == typeid(ESM::Light).name())
{
MWWorld::LiveCellRef<ESM::Light>* ref = ptr.get<ESM::Light>();
cell->lights.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->lights.list.back(), cell);
}
else if (type == typeid(ESM::Tool).name())
{
MWWorld::LiveCellRef<ESM::Tool>* ref = ptr.get<ESM::Tool>();
cell->lockpicks.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->lockpicks.list.back(), cell);
}
else if (type == typeid(ESM::Repair).name())
{
MWWorld::LiveCellRef<ESM::Repair>* ref = ptr.get<ESM::Repair>();
cell->repairs.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->repairs.list.back(), cell);
}
else if (type == typeid(ESM::Probe).name())
{
MWWorld::LiveCellRef<ESM::Probe>* ref = ptr.get<ESM::Probe>();
cell->probes.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->probes.list.back(), cell);
}
else if (type == typeid(ESM::Weapon).name())
{
MWWorld::LiveCellRef<ESM::Weapon>* ref = ptr.get<ESM::Weapon>();
cell->weapons.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->weapons.list.back(), cell);
}
else if (type == typeid(ESM::Miscellaneous).name())
{
// if this is gold, we need to fetch the correct mesh depending on the amount of gold.
if (MWWorld::Class::get(ptr).getName(ptr) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
{
int goldAmount = ptr.getRefData().getCount();
std::string base = "Gold_001";
if (goldAmount >= 100)
base = "Gold_100";
else if (goldAmount >= 25)
base = "Gold_025";
else if (goldAmount >= 10)
base = "Gold_010";
else if (goldAmount >= 5)
base = "Gold_005";
MWWorld::ManualRef newRef (MWBase::Environment::get().getWorld()->getStore(), base);
MWWorld::LiveCellRef<ESM::Miscellaneous>* ref = newRef.getPtr().get<ESM::Miscellaneous>();
cell->miscItems.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->miscItems.list.back(), cell);
ESM::Position& p = newPtr.getRefData().getPosition();
p.pos[0] = ptr.getRefData().getPosition().pos[0];
p.pos[1] = ptr.getRefData().getPosition().pos[1];
p.pos[2] = ptr.getRefData().getPosition().pos[2];
}
else
{
MWWorld::LiveCellRef<ESM::Miscellaneous>* ref = ptr.get<ESM::Miscellaneous>();
cell->miscItems.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->miscItems.list.back(), cell);
}
}
else
throw std::runtime_error("Trying to insert object of unhandled type");
newPtr.getRefData().setCount(ptr.getRefData().getCount());
ptr.getRefData().setCount(0);
newPtr.getRefData().enable();
mRendering.addObject(newPtr);
MWWorld::Class::get(newPtr).insertObject(newPtr, *mPhysics);
}
void Scene::addObjectToScene (const Ptr& ptr) void Scene::addObjectToScene (const Ptr& ptr)
{ {
mRendering.addObject (ptr); mRendering.addObject(ptr);
MWWorld::Class::get (ptr).insertObject (ptr, *mPhysics); MWWorld::Class::get(ptr).insertObject(ptr, *mPhysics);
} }
void Scene::removeObjectFromScene (const Ptr& ptr) void Scene::removeObjectFromScene (const Ptr& ptr)
@ -474,4 +345,19 @@ namespace MWWorld
mPhysics->removeObject (ptr.getRefData().getHandle()); mPhysics->removeObject (ptr.getRefData().getHandle());
mRendering.removeObject (ptr); mRendering.removeObject (ptr);
} }
bool Scene::isCellActive(const CellStore &cell)
{
CellStoreCollection::iterator active = mActiveCells.begin();
while (active != mActiveCells.end()) {
if ((*active)->cell->name == cell.cell->name &&
(*active)->cell->data.gridX == cell.cell->data.gridX &&
(*active)->cell->data.gridY == cell.cell->data.gridY)
{
return true;
}
++active;
}
return false;
}
} }

View file

@ -88,10 +88,6 @@ namespace MWWorld
void insertCell (Ptr::CellStore &cell); void insertCell (Ptr::CellStore &cell);
/// this method is only meant for dropping objects into the gameworld from a container
/// and thus only handles object types that can be placed in a container
void insertObject (const Ptr& object, CellStore* cell);
void update (float duration); void update (float duration);
void addObjectToScene (const Ptr& ptr); void addObjectToScene (const Ptr& ptr);
@ -99,6 +95,8 @@ namespace MWWorld
void removeObjectFromScene (const Ptr& ptr); void removeObjectFromScene (const Ptr& ptr);
///< Remove an object from the scene, but not from the world model. ///< Remove an object from the scene, but not from the world model.
bool isCellActive(const CellStore &cell);
}; };
} }

View file

@ -1016,14 +1016,13 @@ namespace MWWorld
else else
cell = getPlayer().getPlayer().getCell(); cell = getPlayer().getPlayer().getCell();
ESM::Position& pos = object.getRefData().getPosition(); ESM::Position pos = getPlayer().getPlayer().getRefData().getPosition();
pos.pos[0] = result.second[0]; pos.pos[0] = result.second[0];
pos.pos[1] = -result.second[2]; pos.pos[1] = -result.second[2];
pos.pos[2] = result.second[1]; pos.pos[2] = result.second[1];
mWorldScene->insertObject(object, cell); placeObject(object, *cell, pos);
object.getRefData().setCount(0);
/// \todo retrieve the bounds of the object and translate it accordingly
return true; return true;
} }
@ -1039,18 +1038,52 @@ namespace MWWorld
return true; return true;
} }
void
World::placeObject(const Ptr &object, CellStore &cell, const ESM::Position &pos)
{
/// \todo add searching correct cell for position specified
MWWorld::Ptr dropped =
MWWorld::Class::get(object).copyToCell(object, cell, pos);
Ogre::Vector3 min, max;
if (mPhysics->getObjectAABB(object, min, max)) {
float *pos = dropped.getRefData().getPosition().pos;
pos[0] -= (min.x + max.x) / 2;
pos[1] -= (min.y + max.y) / 2;
pos[2] -= min.z;
}
if (mWorldScene->isCellActive(cell)) {
if (dropped.getRefData().isEnabled()) {
mWorldScene->addObjectToScene(dropped);
}
std::string script = MWWorld::Class::get(dropped).getScript(dropped);
if (!script.empty()) {
mLocalScripts.add(script, dropped);
}
}
}
void World::dropObjectOnGround (const Ptr& object) void World::dropObjectOnGround (const Ptr& object)
{ {
MWWorld::Ptr::CellStore* cell = getPlayer().getPlayer().getCell(); MWWorld::Ptr::CellStore* cell = getPlayer().getPlayer().getCell();
float* playerPos = getPlayer().getPlayer().getRefData().getPosition().pos; ESM::Position pos =
getPlayer().getPlayer().getRefData().getPosition();
ESM::Position& pos = object.getRefData().getPosition(); Ogre::Vector3 orig =
pos.pos[0] = playerPos[0]; Ogre::Vector3(pos.pos[0], pos.pos[1], pos.pos[2]);
pos.pos[1] = playerPos[1]; Ogre::Vector3 dir = Ogre::Vector3(0, 0, -1);
pos.pos[2] = playerPos[2];
mWorldScene->insertObject(object, cell); float len = (pos.pos[2] >= 0) ? pos.pos[2] : -pos.pos[2];
len += 100.0;
std::pair<bool, Ogre::Vector3> hit =
mPhysics->castRay(orig, dir, len);
pos.pos[2] = hit.second.z;
placeObject(object, *cell, pos);
object.getRefData().setCount(0);
} }
void World::processChangedSettings(const Settings::CategorySettingVector& settings) void World::processChangedSettings(const Settings::CategorySettingVector& settings)

View file

@ -89,6 +89,9 @@ namespace MWWorld
bool moveObjectImp (const Ptr& ptr, float x, float y, float z); bool moveObjectImp (const Ptr& ptr, float x, float y, float z);
///< @return true if the active cell (cell player is in) changed ///< @return true if the active cell (cell player is in) changed
virtual void
placeObject(const Ptr &ptr, CellStore &cell, const ESM::Position &pos);
public: public:
World (OEngine::Render::OgreRenderer& renderer, World (OEngine::Render::OgreRenderer& renderer,

View file

@ -62,28 +62,13 @@ static bool fsstrict = false;
/// An OGRE Archive wrapping a BSAFile archive /// An OGRE Archive wrapping a BSAFile archive
class DirArchive: public Ogre::FileSystemArchive class DirArchive: public Ogre::FileSystemArchive
{ {
boost::filesystem::path currentdir; boost::filesystem::path currentdir;
std::map<std::string, std::vector<std::string>, ciLessBoost> m; std::map<std::string, std::vector<std::string>, ciLessBoost> m;
unsigned int cutoff; unsigned int cutoff;
bool findFile(const String& filename, std::string& copy) const bool findFile(const String& filename, std::string& copy) const
{ {
{ copy = filename;
String passed = filename;
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|')
passed = filename.substr(0, filename.length() - 2);
copy = passed;
}
std::replace(copy.begin(), copy.end(), '\\', '/'); std::replace(copy.begin(), copy.end(), '\\', '/');
if(copy.at(0) == '/') if(copy.at(0) == '/')
@ -223,43 +208,20 @@ public:
// OGRE's fault. You should NOT expect an open() command not to // OGRE's fault. You should NOT expect an open() command not to
// have any side effects on the archive, and hence this function // have any side effects on the archive, and hence this function
// should not have been declared const in the first place. // should not have been declared const in the first place.
BSAFile *narc = (BSAFile*)&arc; BSAFile *narc = const_cast<BSAFile*>(&arc);
String passed = filename;
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|')
passed = filename.substr(0, filename.length() - 2);
// Open the file // Open the file
return narc->getFile(passed.c_str()); return narc->getFile(filename.c_str());
} }
bool exists(const String& filename) { bool exists(const String& filename) {
return cexists(filename); return arc.exists(filename.c_str());
} }
// Check if the file exists.
bool cexists(const String& filename) const { bool cexists(const String& filename) const {
String passed = filename; return arc.exists(filename.c_str());
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':') }
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|')
passed = filename.substr(0, filename.length() - 2);
return arc.exists(passed.c_str());
}
time_t getModifiedTime(const String&) { return 0; } time_t getModifiedTime(const String&) { return 0; }
// This is never called as far as I can see. // This is never called as far as I can see.

View file

@ -96,7 +96,9 @@ public:
class ShapeData : public Record class ShapeData : public Record
{ {
public: public:
std::vector<float> vertices, normals, colors, uvlist; std::vector<Ogre::Vector3> vertices, normals;
std::vector<Ogre::Vector4> colors;
std::vector< std::vector<Ogre::Vector2> > uvlist;
Ogre::Vector3 center; Ogre::Vector3 center;
float radius; float radius;
@ -105,16 +107,16 @@ public:
int verts = nif->getUShort(); int verts = nif->getUShort();
if(nif->getInt()) if(nif->getInt())
nif->getFloats(vertices, verts*3); nif->getVector3s(vertices, verts);
if(nif->getInt()) if(nif->getInt())
nif->getFloats(normals, verts*3); nif->getVector3s(normals, verts);
center = nif->getVector3(); center = nif->getVector3();
radius = nif->getFloat(); radius = nif->getFloat();
if(nif->getInt()) if(nif->getInt())
nif->getFloats(colors, verts*4); nif->getVector4s(colors, verts);
// Only the first 6 bits are used as a count. I think the rest are // Only the first 6 bits are used as a count. I think the rest are
// flags of some sort. // flags of some sort.
@ -122,7 +124,11 @@ public:
uvs &= 0x3f; uvs &= 0x3f;
if(nif->getInt()) if(nif->getInt())
nif->getFloats(uvlist, uvs*verts*2); {
uvlist.resize(uvs);
for(int i = 0;i < uvs;i++)
nif->getVector2s(uvlist[i], verts);
}
} }
}; };
@ -202,61 +208,34 @@ public:
class NiPosData : public Record class NiPosData : public Record
{ {
public: public:
Vector3KeyList mKeyList;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
int count = nif->getInt(); mKeyList.read(nif);
int type = nif->getInt();
if(type != 1 && type != 2)
nif->fail("Cannot handle NiPosData type");
// TODO: Could make structs of these. Seems to be identical to
// translation in NiKeyframeData.
for(int i=0; i<count; i++)
{
/*float time =*/ nif->getFloat();
nif->getVector3(); // This isn't really shared between type 1
// and type 2, most likely
if(type == 2)
{
nif->getVector3();
nif->getVector3();
}
}
} }
}; };
class NiUVData : public Record class NiUVData : public Record
{ {
public: public:
FloatKeyList mKeyList[4];
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
// TODO: This is claimed to be a "float animation key", which is for(int i = 0;i < 4;i++)
// also used in FloatData and KeyframeData. We could probably mKeyList[i].read(nif);
// reuse and refactor a lot of this if we actually use it at some
// point.
for(int i=0; i<2; i++)
{
int count = nif->getInt();
if(count)
{
nif->getInt(); // always 2
nif->skip(count * (sizeof(float) + 3*sizeof(float))); // Really one time float + one vector
}
}
// Always 0
nif->getInt();
nif->getInt();
} }
}; };
class NiFloatData : public Record class NiFloatData : public Record
{ {
public: public:
FloatKeyList mKeyList;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
int count = nif->getInt(); mKeyList.read(nif);
nif->getInt(); // always 2
nif->skip(count * (sizeof(float) + 3*sizeof(float))); // Really one time float + one vector
} }
}; };
@ -302,19 +281,11 @@ public:
class NiColorData : public Record class NiColorData : public Record
{ {
public: public:
struct ColorData Vector4KeyList mKeyList;
{
float time;
Ogre::Vector4 rgba;
};
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
int count = nif->getInt(); mKeyList.read(nif);
nif->getInt(); // always 1
// Skip the data
nif->skip(count * 5*sizeof(float));
} }
}; };
@ -361,12 +332,6 @@ public:
Ogre::Vector3 trans; // Translation Ogre::Vector3 trans; // Translation
float scale; // Probably scale (always 1) float scale; // Probably scale (always 1)
}; };
struct BoneTrafoCopy
{
Ogre::Quaternion rotation;
Ogre::Vector3 trans;
float scale;
};
struct VertWeight struct VertWeight
{ {
@ -374,26 +339,12 @@ public:
float weight; float weight;
}; };
struct BoneInfo struct BoneInfo
{ {
BoneTrafo trafo; BoneTrafo trafo;
Ogre::Vector4 unknown; Ogre::Vector4 unknown;
std::vector<VertWeight> weights; std::vector<VertWeight> weights;
}; };
struct BoneInfoCopy
{
std::string bonename;
unsigned short bonehandle;
BoneTrafoCopy trafo;
Ogre::Vector4 unknown;
//std::vector<VertWeight> weights;
};
struct IndividualWeight
{
float weight;
unsigned int boneinfocopyindex;
};
BoneTrafo trafo; BoneTrafo trafo;
std::vector<BoneInfo> bones; std::vector<BoneInfo> bones;
@ -428,378 +379,45 @@ public:
} }
}; };
class NiMorphData : public Record struct NiMorphData : public Record
{ {
float startTime; struct MorphData {
float stopTime; FloatKeyList mData;
std::vector<Ogre::Vector3> initialVertices; std::vector<Ogre::Vector3> mVertices;
std::vector<std::vector<float> > relevantTimes; };
std::vector<std::vector<Ogre::Vector3> > relevantData; std::vector<MorphData> mMorphs;
std::vector<std::vector<Ogre::Vector3> > additionalVertices;
public:
float getStartTime() const
{ return startTime; }
float getStopTime() const
{ return stopTime; }
void setStartTime(float time)
{ startTime = time; }
void setStopTime(float time)
{ stopTime = time; }
const std::vector<Ogre::Vector3>& getInitialVertices() const
{ return initialVertices; }
const std::vector<std::vector<Ogre::Vector3> >& getRelevantData() const
{ return relevantData; }
const std::vector<std::vector<float> >& getRelevantTimes() const
{ return relevantTimes; }
const std::vector<std::vector<Ogre::Vector3> >& getAdditionalVertices() const
{ return additionalVertices; }
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
int morphCount = nif->getInt(); int morphCount = nif->getInt();
int vertCount = nif->getInt(); int vertCount = nif->getInt();
nif->getChar(); nif->getChar();
int magic = nif->getInt();
/*int type =*/ nif->getInt();
for(int i = 0; i < vertCount; i++) mMorphs.resize(morphCount);
for(int i = 0;i < morphCount;i++)
{ {
float x = nif->getFloat(); mMorphs[i].mData.read(nif, true);
float y = nif->getFloat();
float z = nif->getFloat();
initialVertices.push_back(Ogre::Vector3(x, y, z));
}
for(int i=1; i<morphCount; i++) mMorphs[i].mVertices.resize(vertCount);
{ for(int j = 0;j < vertCount;j++)
magic = nif->getInt(); mMorphs[i].mVertices[j] = nif->getVector3();
/*type =*/ nif->getInt();
std::vector<Ogre::Vector3> current;
std::vector<float> currentTime;
for(int i = 0; i < magic; i++)
{
// Time, data, forward, backward tangents
float time = nif->getFloat();
float x = nif->getFloat();
float y = nif->getFloat();
float z = nif->getFloat();
current.push_back(Ogre::Vector3(x,y,z));
currentTime.push_back(time);
//nif->getFloatLen(4*magic);
}
if(magic)
{
relevantData.push_back(current);
relevantTimes.push_back(currentTime);
}
std::vector<Ogre::Vector3> verts;
for(int i = 0; i < vertCount; i++)
{
float x = nif->getFloat();
float y = nif->getFloat();
float z = nif->getFloat();
verts.push_back(Ogre::Vector3(x, y, z));
}
additionalVertices.push_back(verts);
} }
} }
}; };
class NiKeyframeData : public Record struct NiKeyframeData : public Record
{ {
std::string bonename; QuaternionKeyList mRotations;
//Rotations Vector3KeyList mTranslations;
std::vector<Ogre::Quaternion> quats; FloatKeyList mScales;
std::vector<Ogre::Vector3> tbc;
std::vector<float> rottime;
float startTime;
float stopTime;
int rtype;
//Translations
std::vector<Ogre::Vector3> translist1;
std::vector<Ogre::Vector3> translist2;
std::vector<Ogre::Vector3> translist3;
std::vector<Ogre::Vector3> transtbc;
std::vector<float> transtime;
int ttype;
//Scalings
std::vector<float> scalefactor;
std::vector<float> scaletime;
std::vector<float> forwards;
std::vector<float> backwards;
std::vector<Ogre::Vector3> tbcscale;
int stype;
public:
void clone(const NiKeyframeData &c)
{
quats = c.getQuat();
tbc = c.getrTbc();
rottime = c.getrTime();
//types
ttype = c.getTtype();
rtype = c.getRtype();
stype = c.getStype();
translist1 = c.getTranslist1();
translist2 = c.getTranslist2();
translist3 = c.getTranslist3();
transtime = c.gettTime();
bonename = c.getBonename();
}
void setBonename(std::string bone)
{ bonename = bone; }
void setStartTime(float start)
{ startTime = start; }
void setStopTime(float end)
{ stopTime = end; }
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
// Rotations first mRotations.read(nif);
int count = nif->getInt(); mTranslations.read(nif);
//std::vector<Ogre::Quaternion> quat(count); mScales.read(nif);
//std::vector<float> rottime(count);
if(count)
{
//TYPE1 LINEAR_KEY
//TYPE2 QUADRATIC_KEY
//TYPE3 TBC_KEY
//TYPE4 XYZ_ROTATION_KEY
//TYPE5 UNKNOWN_KEY
rtype = nif->getInt();
//std::cout << "Count: " << count << "Type: " << type << "\n";
if(rtype == 1)
{
//We need to actually read in these values instead of skipping them
//nif->skip(count*4*5); // time + quaternion
for (int i = 0; i < count; i++)
{
float time = nif->getFloat();
float w = nif->getFloat();
float x = nif->getFloat();
float y = nif->getFloat();
float z = nif->getFloat();
Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z));
quats.push_back(quat);
rottime.push_back(time);
//if(time == 0.0 || time > 355.5)
// std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n";
}
}
else if(rtype == 3)
{
//Example - node 116 in base_anim.nif
for (int i = 0; i < count; i++)
{
float time = nif->getFloat();
float w = nif->getFloat();
float x = nif->getFloat();
float y = nif->getFloat();
float z = nif->getFloat();
float tbcx = nif->getFloat();
float tbcy = nif->getFloat();
float tbcz = nif->getFloat();
Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z));
Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz);
quats.push_back(quat);
rottime.push_back(time);
tbc.push_back(vec);
//if(time == 0.0 || time > 355.5)
// std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n";
}
}
else if(rtype == 4)
{
for(int j=0;j<count;j++)
{
nif->getFloat(); // time
for(int i=0; i<3; i++)
{
int cnt = nif->getInt();
int type = nif->getInt();
if(type == 1)
nif->skip(cnt*4*2); // time + unknown
else if(type == 2)
nif->skip(cnt*4*4); // time + unknown vector
else
nif->fail("Unknown sub-rotation type");
}
}
}
else
nif->fail("Unknown rotation type in NiKeyframeData");
}
//first = false;
// Then translation
count = nif->getInt();
if(count)
{
ttype = nif->getInt();
//std::cout << "TransCount:" << count << " Type: " << type << "\n";
if(ttype == 1)
{
for(int i = 0; i < count; i++)
{
float time = nif->getFloat();
float x = nif->getFloat();
float y = nif->getFloat();
float z = nif->getFloat();
Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
translist1.push_back(trans);
transtime.push_back(time);
}
//nif->getFloatLen(count*4); // time + translation
}
else if(ttype == 2)
{
//Example - node 116 in base_anim.nif
for(int i = 0; i < count; i++)
{
float time = nif->getFloat();
float x = nif->getFloat();
float y = nif->getFloat();
float z = nif->getFloat();
float x2 = nif->getFloat();
float y2 = nif->getFloat();
float z2 = nif->getFloat();
float x3 = nif->getFloat();
float y3 = nif->getFloat();
float z3 = nif->getFloat();
Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
Ogre::Vector3 trans2 = Ogre::Vector3(x2, y2, z2);
Ogre::Vector3 trans3 = Ogre::Vector3(x3, y3, z3);
transtime.push_back(time);
translist1.push_back(trans);
translist2.push_back(trans2);
translist3.push_back(trans3);
}
//nif->getFloatLen(count*10); // trans1 + forward + backward
}
else if(ttype == 3)
{
for(int i = 0; i < count; i++)
{
float time = nif->getFloat();
float x = nif->getFloat();
float y = nif->getFloat();
float z = nif->getFloat();
float t = nif->getFloat();
float b = nif->getFloat();
float c = nif->getFloat();
Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
Ogre::Vector3 tbc = Ogre::Vector3(t, b, c);
translist1.push_back(trans);
transtbc.push_back(tbc);
transtime.push_back(time);
}
//nif->getFloatLen(count*7); // trans1 + tension,bias,continuity
}
else nif->fail("Unknown translation type");
}
// Finally, scalings
count = nif->getInt();
if(count)
{
stype = nif->getInt();
for(int i = 0; i < count; i++)
{
//int size = 0;
if(stype >= 1 && stype < 4)
{
float time = nif->getFloat();
float scale = nif->getFloat();
scaletime.push_back(time);
scalefactor.push_back(scale);
//size = 2; // time+scale
}
else
nif->fail("Unknown scaling type");
if(stype == 2)
{
//size = 4; // 1 + forward + backward (floats)
float forward = nif->getFloat();
float backward = nif->getFloat();
forwards.push_back(forward);
backwards.push_back(backward);
}
else if(stype == 3)
{
//size = 5; // 1 + tbc
float tbcx = nif->getFloat();
float tbcy = nif->getFloat();
float tbcz = nif->getFloat();
Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz);
tbcscale.push_back(vec);
}
}
}
else
stype = 0;
} }
int getRtype() const
{ return rtype; }
int getStype() const
{ return stype; }
int getTtype() const
{ return ttype; }
float getStartTime() const
{ return startTime; }
float getStopTime() const
{ return stopTime; }
const std::vector<Ogre::Quaternion>& getQuat() const
{ return quats; }
const std::vector<Ogre::Vector3>& getrTbc() const
{ return tbc; }
const std::vector<float>& getrTime() const
{ return rottime; }
const std::vector<Ogre::Vector3>& getTranslist1() const
{ return translist1; }
const std::vector<Ogre::Vector3>& getTranslist2() const
{ return translist2; }
const std::vector<Ogre::Vector3>& getTranslist3() const
{ return translist3; }
const std::vector<float>& gettTime() const
{ return transtime; }
const std::vector<float>& getScalefactor() const
{ return scalefactor; }
const std::vector<float>& getForwards() const
{ return forwards; }
const std::vector<float>& getBackwards() const
{ return backwards; }
const std::vector<Ogre::Vector3>& getScaleTbc() const
{ return tbcscale; }
const std::vector<float>& getsTime() const
{ return scaletime; }
const std::string& getBonename() const
{ return bonename; }
}; };
} // Namespace } // Namespace

View file

@ -205,8 +205,22 @@ void NiSkinInstance::post(NIFFile *nif)
for(size_t i=0; i<bnum; i++) for(size_t i=0; i<bnum; i++)
{ {
if(!bones.has(i)) if(bones[i].empty())
nif->fail("Oops: Missing bone! Don't know how to handle this."); nif->fail("Oops: Missing bone! Don't know how to handle this.");
bones[i].makeBone(i, data->bones[i]); bones[i]->makeBone(i, data->bones[i]);
} }
} }
Ogre::Matrix4 Node::getLocalTransform()
{
Ogre::Matrix4 mat4(Ogre::Matrix4::IDENTITY);
mat4.makeTransform(trafo.pos, Ogre::Vector3(trafo.scale), Ogre::Quaternion(trafo.rotation));
return mat4;
}
Ogre::Matrix4 Node::getWorldTransform()
{
if(parent != NULL)
return parent->getWorldTransform() * getLocalTransform();
return getLocalTransform();
}

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