mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-11-04 07:56:45 +00:00 
			
		
		
		
	Merge branch 'master' into saveOnClose
This commit is contained in:
		
						commit
						9193ddc9d3
					
				
					 161 changed files with 4224 additions and 5385 deletions
				
			
		| 
						 | 
					@ -74,7 +74,6 @@ set(LIBDIR ${CMAKE_SOURCE_DIR}/libs)
 | 
				
			||||||
set(OENGINE_OGRE
 | 
					set(OENGINE_OGRE
 | 
				
			||||||
  ${LIBDIR}/openengine/ogre/renderer.cpp
 | 
					  ${LIBDIR}/openengine/ogre/renderer.cpp
 | 
				
			||||||
  ${LIBDIR}/openengine/ogre/fader.cpp
 | 
					  ${LIBDIR}/openengine/ogre/fader.cpp
 | 
				
			||||||
  ${LIBDIR}/openengine/ogre/imagerotate.cpp
 | 
					 | 
				
			||||||
  ${LIBDIR}/openengine/ogre/selectionbuffer.cpp
 | 
					  ${LIBDIR}/openengine/ogre/selectionbuffer.cpp
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
set(OENGINE_GUI
 | 
					set(OENGINE_GUI
 | 
				
			||||||
| 
						 | 
					@ -94,8 +93,6 @@ set(OENGINE_BULLET
 | 
				
			||||||
    ${LIBDIR}/openengine/bullet/physic.hpp
 | 
					    ${LIBDIR}/openengine/bullet/physic.hpp
 | 
				
			||||||
    ${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
 | 
					    ${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
 | 
				
			||||||
    ${LIBDIR}/openengine/bullet/BulletShapeLoader.h
 | 
					    ${LIBDIR}/openengine/bullet/BulletShapeLoader.h
 | 
				
			||||||
    ${LIBDIR}/openengine/bullet/pmove.cpp
 | 
					 | 
				
			||||||
    ${LIBDIR}/openengine/bullet/pmove.h
 | 
					 | 
				
			||||||
    ${LIBDIR}/openengine/bullet/trace.cpp
 | 
					    ${LIBDIR}/openengine/bullet/trace.cpp
 | 
				
			||||||
    ${LIBDIR}/openengine/bullet/trace.h
 | 
					    ${LIBDIR}/openengine/bullet/trace.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -299,7 +296,7 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
 | 
				
			||||||
    "${OpenMW_BINARY_DIR}/openmw.cfg.install")
 | 
					    "${OpenMW_BINARY_DIR}/openmw.cfg.install")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 | 
					if (NOT WIN32 AND NOT APPLE)
 | 
				
			||||||
    configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
 | 
					    configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
 | 
				
			||||||
        "${OpenMW_BINARY_DIR}/openmw.desktop")
 | 
					        "${OpenMW_BINARY_DIR}/openmw.desktop")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
| 
						 | 
					@ -380,7 +377,7 @@ if(WIN32)
 | 
				
			||||||
        "${OpenMW_SOURCE_DIR}/readme.txt"
 | 
					        "${OpenMW_SOURCE_DIR}/readme.txt"
 | 
				
			||||||
        "${OpenMW_SOURCE_DIR}/GPL3.txt"
 | 
					        "${OpenMW_SOURCE_DIR}/GPL3.txt"
 | 
				
			||||||
        "${OpenMW_SOURCE_DIR}/OFL.txt"
 | 
					        "${OpenMW_SOURCE_DIR}/OFL.txt"
 | 
				
			||||||
        "${OpenMW_SOURCE_DIR}/Bitstream Vera License.txt"
 | 
					        "${OpenMW_SOURCE_DIR}/DejaVu Font License.txt"
 | 
				
			||||||
        "${OpenMW_SOURCE_DIR}/Daedric Font License.txt"
 | 
					        "${OpenMW_SOURCE_DIR}/Daedric Font License.txt"
 | 
				
			||||||
        "${OpenMW_BINARY_DIR}/launcher.qss"
 | 
					        "${OpenMW_BINARY_DIR}/launcher.qss"
 | 
				
			||||||
        "${OpenMW_BINARY_DIR}/settings-default.cfg"
 | 
					        "${OpenMW_BINARY_DIR}/settings-default.cfg"
 | 
				
			||||||
| 
						 | 
					@ -391,7 +388,7 @@ if(WIN32)
 | 
				
			||||||
    INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
 | 
					    INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SET(CPACK_GENERATOR "NSIS")
 | 
					    SET(CPACK_GENERATOR "NSIS")
 | 
				
			||||||
    SET(CPACK_PACKAGE_NAME "OpenMW ${OPENMW_VERSION}")
 | 
					    SET(CPACK_PACKAGE_NAME "OpenMW")
 | 
				
			||||||
    SET(CPACK_PACKAGE_VENDOR "OpenMW.org")
 | 
					    SET(CPACK_PACKAGE_VENDOR "OpenMW.org")
 | 
				
			||||||
    SET(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
 | 
					    SET(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
 | 
				
			||||||
    SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
 | 
					    SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
 | 
				
			||||||
| 
						 | 
					@ -406,7 +403,7 @@ if(WIN32)
 | 
				
			||||||
    SET(CPACK_RESOURCE_FILE_README "${OpenMW_SOURCE_DIR}/readme.txt")
 | 
					    SET(CPACK_RESOURCE_FILE_README "${OpenMW_SOURCE_DIR}/readme.txt")
 | 
				
			||||||
    SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
 | 
					    SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
 | 
				
			||||||
    SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
 | 
					    SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
 | 
				
			||||||
    SET(CPACK_NSIS_DISPLAY_NAME "OpenMW")
 | 
					    SET(CPACK_NSIS_DISPLAY_NAME "OpenMW ${OPENMW_VERSION}")
 | 
				
			||||||
    SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
 | 
					    SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
 | 
				
			||||||
    SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
 | 
					    SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
 | 
				
			||||||
    SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
 | 
					    SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
 | 
				
			||||||
| 
						 | 
					@ -529,6 +526,8 @@ if (WIN32)
 | 
				
			||||||
        set(WARNINGS "${WARNINGS} /wd${d}")
 | 
					        set(WARNINGS "${WARNINGS} /wd${d}")
 | 
				
			||||||
    endforeach(d)
 | 
					    endforeach(d)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_target_properties(shiny PROPERTIES COMPILE_FLAGS ${WARNINGS})
 | 
				
			||||||
 | 
					    set_target_properties(shiny.OgrePlatform PROPERTIES COMPILE_FLAGS ${WARNINGS})
 | 
				
			||||||
    set_target_properties(components PROPERTIES COMPILE_FLAGS ${WARNINGS})
 | 
					    set_target_properties(components PROPERTIES COMPILE_FLAGS ${WARNINGS})
 | 
				
			||||||
    if (BUILD_LAUNCHER)
 | 
					    if (BUILD_LAUNCHER)
 | 
				
			||||||
		set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS ${WARNINGS})
 | 
							set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS ${WARNINGS})
 | 
				
			||||||
| 
						 | 
					@ -657,10 +656,18 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Install binaries
 | 
					    # Install binaries
 | 
				
			||||||
    INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
 | 
					    INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
 | 
				
			||||||
    INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
 | 
					    IF(BUILD_LAUNCHER)
 | 
				
			||||||
    INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
 | 
					        INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
 | 
				
			||||||
    INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" )
 | 
					    ENDIF(BUILD_LAUNCHER)
 | 
				
			||||||
    INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/opencs" DESTINATION "${BINDIR}" )
 | 
					    IF(BUILD_ESMTOOL)
 | 
				
			||||||
 | 
					        INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
 | 
				
			||||||
 | 
					    ENDIF(BUILD_ESMTOOL)
 | 
				
			||||||
 | 
					    IF(BUILD_MWINIIMPORTER)
 | 
				
			||||||
 | 
					        INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" )
 | 
				
			||||||
 | 
					    ENDIF(BUILD_MWINIIMPORTER)
 | 
				
			||||||
 | 
					    IF(BUILD_OPENCS)
 | 
				
			||||||
 | 
					        INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/opencs" DESTINATION "${BINDIR}" )
 | 
				
			||||||
 | 
					    ENDIF(BUILD_OPENCS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Install icon and .desktop
 | 
					    # Install icon and .desktop
 | 
				
			||||||
    INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "${ICONDIR}")
 | 
					    INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "${ICONDIR}")
 | 
				
			||||||
| 
						 | 
					@ -674,5 +681,7 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Install resources
 | 
					    # Install resources
 | 
				
			||||||
    INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" )
 | 
					    INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" )
 | 
				
			||||||
    INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${DATADIR}/resources" )
 | 
					    IF(BUILD_LAUNCHER)
 | 
				
			||||||
 | 
					        INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${DATADIR}/resources" )
 | 
				
			||||||
 | 
					    ENDIF(BUILD_LAUNCHER)
 | 
				
			||||||
endif(NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
 | 
					endif(NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ void CSMDoc::Document::load (const std::vector<boost::filesystem::path>::const_i
 | 
				
			||||||
        getData().loadFile (*end2, false);
 | 
					        getData().loadFile (*end2, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    addOptionalGmsts();
 | 
					    addOptionalGmsts();
 | 
				
			||||||
 | 
					    addOptionalGlobals();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CSMDoc::Document::addOptionalGmsts()
 | 
					void CSMDoc::Document::addOptionalGmsts()
 | 
				
			||||||
| 
						 | 
					@ -139,6 +140,26 @@ void CSMDoc::Document::addOptionalGmsts()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CSMDoc::Document::addOptionalGlobals()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const char *sGlobals[] =
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "dayspassed",
 | 
				
			||||||
 | 
					        "pcwerewolf",
 | 
				
			||||||
 | 
					        "pcyear",
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i=0; sGlobals[i]; ++i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ESM::Global global;
 | 
				
			||||||
 | 
					        global.mId = sGlobals[i];
 | 
				
			||||||
 | 
					        global.mType = ESM::VT_Int;
 | 
				
			||||||
 | 
					        global.mValue = 0;
 | 
				
			||||||
 | 
					        addOptionalGlobal (global);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CSMDoc::Document::addOptionalGmst (const ESM::GameSetting& gmst)
 | 
					void CSMDoc::Document::addOptionalGmst (const ESM::GameSetting& gmst)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (getData().getGmsts().searchId (gmst.mId)==-1)
 | 
					    if (getData().getGmsts().searchId (gmst.mId)==-1)
 | 
				
			||||||
| 
						 | 
					@ -150,6 +171,17 @@ void CSMDoc::Document::addOptionalGmst (const ESM::GameSetting& gmst)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CSMDoc::Document::addOptionalGlobal (const ESM::Global& global)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (getData().getGlobals().searchId (global.mId)==-1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        CSMWorld::Record<ESM::Global> record;
 | 
				
			||||||
 | 
					        record.mBase = global;
 | 
				
			||||||
 | 
					        record.mState = CSMWorld::RecordBase::State_BaseOnly;
 | 
				
			||||||
 | 
					        getData().getGlobals().appendRecord (record);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CSMDoc::Document::createBase()
 | 
					void CSMDoc::Document::createBase()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static const char *sGlobals[] =
 | 
					    static const char *sGlobals[] =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ class QAbstractItemModel;
 | 
				
			||||||
namespace ESM
 | 
					namespace ESM
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct GameSetting;
 | 
					    struct GameSetting;
 | 
				
			||||||
 | 
					    struct Global;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace CSMDoc
 | 
					namespace CSMDoc
 | 
				
			||||||
| 
						 | 
					@ -53,8 +54,12 @@ namespace CSMDoc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void addOptionalGmsts();
 | 
					            void addOptionalGmsts();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void addOptionalGlobals();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void addOptionalGmst (const ESM::GameSetting& gmst);
 | 
					            void addOptionalGmst (const ESM::GameSetting& gmst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void addOptionalGlobal (const ESM::Global& global);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public:
 | 
					        public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Document (const std::vector<boost::filesystem::path>& files, bool new_);
 | 
					            Document (const std::vector<boost::filesystem::path>& files, bool new_);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,7 +171,7 @@ namespace CSMWorld
 | 
				
			||||||
            record2.mModified = record;
 | 
					            record2.mModified = record;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            mRecords.push_back (record2);
 | 
					            mRecords.push_back (record2);
 | 
				
			||||||
            mIndex.insert (std::make_pair (id, mRecords.size()-1));
 | 
					            mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id), mRecords.size()-1));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -306,7 +306,7 @@ namespace CSMWorld
 | 
				
			||||||
    void IdCollection<ESXRecordT>::appendRecord (const RecordBase& record)
 | 
					    void IdCollection<ESXRecordT>::appendRecord (const RecordBase& record)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mRecords.push_back (dynamic_cast<const Record<ESXRecordT>&> (record));
 | 
					        mRecords.push_back (dynamic_cast<const Record<ESXRecordT>&> (record));
 | 
				
			||||||
        mIndex.insert (std::make_pair (getId (record), mRecords.size()-1));
 | 
					        mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (getId (record)), mRecords.size()-1));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template<typename ESXRecordT>
 | 
					    template<typename ESXRecordT>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ CSVDoc::Operations::Operations()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    widgetContainer->setLayout (mLayout);
 | 
					    widgetContainer->setLayout (mLayout);
 | 
				
			||||||
    setWidget (widgetContainer);
 | 
					    setWidget (widgetContainer);
 | 
				
			||||||
 | 
					    setVisible (false);
 | 
				
			||||||
    setFixedHeight (widgetContainer->height());
 | 
					    setFixedHeight (widgetContainer->height());
 | 
				
			||||||
    setTitleBarWidget (new QWidget (this));
 | 
					    setTitleBarWidget (new QWidget (this));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,8 @@ void CSVDoc::Operations::setProgress (int current, int max, int type, int thread
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( oldCount > 0)
 | 
					    if ( oldCount > 0)
 | 
				
			||||||
        setFixedHeight (height()/oldCount * newCount);
 | 
					        setFixedHeight (height()/oldCount * newCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setVisible (true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CSVDoc::Operations::quitOperation (int type)
 | 
					void CSVDoc::Operations::quitOperation (int type)
 | 
				
			||||||
| 
						 | 
					@ -59,6 +61,8 @@ void CSVDoc::Operations::quitOperation (int type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (oldCount > 1)
 | 
					            if (oldCount > 1)
 | 
				
			||||||
                setFixedHeight (height() / oldCount * newCount);
 | 
					                setFixedHeight (height() / oldCount * newCount);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                setVisible (false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,7 +242,6 @@ void CSVDoc::View::addGmstsSubView()
 | 
				
			||||||
void CSVDoc::View::abortOperation (int type)
 | 
					void CSVDoc::View::abortOperation (int type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mDocument->abortOperation (type);
 | 
					    mDocument->abortOperation (type);
 | 
				
			||||||
    mOperations->quitOperation (type);
 | 
					 | 
				
			||||||
    updateActions();
 | 
					    updateActions();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,8 +14,8 @@ set(GAME_HEADER
 | 
				
			||||||
source_group(game FILES ${GAME} ${GAME_HEADER})
 | 
					source_group(game FILES ${GAME} ${GAME_HEADER})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_openmw_dir (mwrender
 | 
					add_openmw_dir (mwrender
 | 
				
			||||||
    renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
 | 
					    renderingmanager debugging sky player animation npcanimation creatureanimation activatoranimation
 | 
				
			||||||
    renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
 | 
					    actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
 | 
				
			||||||
    compositors characterpreview externalrendering globalmap videoplayer
 | 
					    compositors characterpreview externalrendering globalmap videoplayer
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,11 +26,11 @@ add_openmw_dir (mwinput
 | 
				
			||||||
add_openmw_dir (mwgui
 | 
					add_openmw_dir (mwgui
 | 
				
			||||||
    text_input widgets race class birth review windowmanagerimp console dialogue
 | 
					    text_input widgets race class birth review windowmanagerimp console dialogue
 | 
				
			||||||
    dialogue_history window_base stats_window messagebox journalwindow charactercreation
 | 
					    dialogue_history window_base stats_window messagebox journalwindow charactercreation
 | 
				
			||||||
    map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
 | 
					    map_window window_pinnable_base tooltips scrollwindow bookwindow list
 | 
				
			||||||
    formatting inventorywindow container hud countdialog tradewindow settingswindow
 | 
					    formatting inventorywindow container hud countdialog tradewindow settingswindow
 | 
				
			||||||
    confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
 | 
					    confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
 | 
				
			||||||
    itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
 | 
					    itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
 | 
				
			||||||
    enchantingdialog trainingwindow travelwindow imagebutton exposedwindow
 | 
					    enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_openmw_dir (mwdialogue
 | 
					add_openmw_dir (mwdialogue
 | 
				
			||||||
| 
						 | 
					@ -62,8 +62,9 @@ add_openmw_dir (mwclass
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_openmw_dir (mwmechanics
 | 
					add_openmw_dir (mwmechanics
 | 
				
			||||||
    mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells
 | 
					    mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators
 | 
				
			||||||
    activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow aiescort aiactivate
 | 
					    drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
 | 
				
			||||||
 | 
					    aiescort aiactivate
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_openmw_dir (mwbase
 | 
					add_openmw_dir (mwbase
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@
 | 
				
			||||||
#include <components/bsa/bsa_archive.hpp>
 | 
					#include <components/bsa/bsa_archive.hpp>
 | 
				
			||||||
#include <components/files/configurationmanager.hpp>
 | 
					#include <components/files/configurationmanager.hpp>
 | 
				
			||||||
#include <components/translation/translation.hpp>
 | 
					#include <components/translation/translation.hpp>
 | 
				
			||||||
 | 
					#include <components/nif/nif_file.hpp>
 | 
				
			||||||
#include <components/nifoverrides/nifoverrides.hpp>
 | 
					#include <components/nifoverrides/nifoverrides.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <components/nifbullet/bullet_nif_loader.hpp>
 | 
					#include <components/nifbullet/bullet_nif_loader.hpp>
 | 
				
			||||||
| 
						 | 
					@ -17,7 +18,6 @@
 | 
				
			||||||
#include "mwinput/inputmanagerimp.hpp"
 | 
					#include "mwinput/inputmanagerimp.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "mwgui/windowmanagerimp.hpp"
 | 
					#include "mwgui/windowmanagerimp.hpp"
 | 
				
			||||||
#include "mwgui/cursorreplace.hpp"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "mwscript/scriptmanagerimp.hpp"
 | 
					#include "mwscript/scriptmanagerimp.hpp"
 | 
				
			||||||
#include "mwscript/extensions.hpp"
 | 
					#include "mwscript/extensions.hpp"
 | 
				
			||||||
| 
						 | 
					@ -66,14 +66,15 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mEnvironment.setFrameDuration (evt.timeSinceLastFrame);
 | 
					        float frametime = std::min(evt.timeSinceLastFrame, 0.2f);
 | 
				
			||||||
 | 
					        mEnvironment.setFrameDuration(frametime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // update input
 | 
					        // update input
 | 
				
			||||||
        MWBase::Environment::get().getInputManager()->update(evt.timeSinceLastFrame, false);
 | 
					        MWBase::Environment::get().getInputManager()->update(frametime, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // sound
 | 
					        // sound
 | 
				
			||||||
        if (mUseSound)
 | 
					        if (mUseSound)
 | 
				
			||||||
            MWBase::Environment::get().getSoundManager()->update (evt.timeSinceLastFrame);
 | 
					            MWBase::Environment::get().getSoundManager()->update(frametime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // global scripts
 | 
					        // global scripts
 | 
				
			||||||
        MWBase::Environment::get().getScriptManager()->getGlobalScripts().run();
 | 
					        MWBase::Environment::get().getScriptManager()->getGlobalScripts().run();
 | 
				
			||||||
| 
						 | 
					@ -87,23 +88,19 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // passing of time
 | 
					        // passing of time
 | 
				
			||||||
        if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
 | 
					        if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
 | 
				
			||||||
            MWBase::Environment::get().getWorld()->advanceTime (
 | 
					            MWBase::Environment::get().getWorld()->advanceTime(
 | 
				
			||||||
                mEnvironment.getFrameDuration()*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600);
 | 
					                frametime*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (changed) // keep change flag for another frame, if cell changed happend in local script
 | 
					        if (changed) // keep change flag for another frame, if cell changed happend in local script
 | 
				
			||||||
            MWBase::Environment::get().getWorld()->markCellAsUnchanged();
 | 
					            MWBase::Environment::get().getWorld()->markCellAsUnchanged();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // update actors
 | 
					        // update actors
 | 
				
			||||||
        std::vector<std::pair<std::string, Ogre::Vector3> > movement;
 | 
					        MWBase::Environment::get().getMechanicsManager()->update(frametime,
 | 
				
			||||||
        MWBase::Environment::get().getMechanicsManager()->update (movement, mEnvironment.getFrameDuration(),
 | 
					 | 
				
			||||||
            MWBase::Environment::get().getWindowManager()->isGuiMode());
 | 
					            MWBase::Environment::get().getWindowManager()->isGuiMode());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
 | 
					 | 
				
			||||||
            MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // update world
 | 
					        // update world
 | 
				
			||||||
        MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame, MWBase::Environment::get().getWindowManager()->isGuiMode());
 | 
					        MWBase::Environment::get().getWorld()->update(frametime, MWBase::Environment::get().getWindowManager()->isGuiMode());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // update GUI
 | 
					        // update GUI
 | 
				
			||||||
        Ogre::RenderWindow* window = mOgre->getWindow();
 | 
					        Ogre::RenderWindow* window = mOgre->getWindow();
 | 
				
			||||||
| 
						 | 
					@ -111,7 +108,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
 | 
				
			||||||
        MWBase::Environment::get().getWorld()->getTriangleBatchCount(tri, batch);
 | 
					        MWBase::Environment::get().getWorld()->getTriangleBatchCount(tri, batch);
 | 
				
			||||||
        MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(), tri, batch);
 | 
					        MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(), tri, batch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MWBase::Environment::get().getWindowManager()->onFrame(evt.timeSinceLastFrame);
 | 
					        MWBase::Environment::get().getWindowManager()->onFrame(frametime);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch (const std::exception& e)
 | 
					    catch (const std::exception& e)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -335,9 +332,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loadBSA();
 | 
					    loadBSA();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // cursor replacer (converts the cursor from the bsa so they can be used by mygui)
 | 
					 | 
				
			||||||
    MWGui::CursorReplace replacer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Create the world
 | 
					    // Create the world
 | 
				
			||||||
    mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins,
 | 
					    mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins,
 | 
				
			||||||
        mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoder, mFallbackMap,
 | 
					        mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoder, mFallbackMap,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,24 +37,24 @@ namespace MWBase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual ~MechanicsManager() {}
 | 
					            virtual ~MechanicsManager() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void addActor (const MWWorld::Ptr& ptr) = 0;
 | 
					            virtual void add (const MWWorld::Ptr& ptr) = 0;
 | 
				
			||||||
            ///< Register an actor for stats management
 | 
					            ///< Register an object for management
 | 
				
			||||||
            ///
 | 
					 | 
				
			||||||
            /// \note Dead actors are ignored.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void removeActor (const MWWorld::Ptr& ptr) = 0;
 | 
					            virtual void remove (const MWWorld::Ptr& ptr) = 0;
 | 
				
			||||||
            ///< Deregister an actor for stats management
 | 
					            ///< Deregister an object for management
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void dropActors (const MWWorld::CellStore *cellStore) = 0;
 | 
					            virtual void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) = 0;
 | 
				
			||||||
            ///< Deregister all actors in the given cell.
 | 
					            ///< Moves an object to a new cell
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual void drop (const MWWorld::CellStore *cellStore) = 0;
 | 
				
			||||||
 | 
					            ///< Deregister all objects in the given cell.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void watchActor (const MWWorld::Ptr& ptr) = 0;
 | 
					            virtual void watchActor (const MWWorld::Ptr& ptr) = 0;
 | 
				
			||||||
            ///< On each update look for changes in a previously registered actor and update the
 | 
					            ///< On each update look for changes in a previously registered actor and update the
 | 
				
			||||||
            /// GUI accordingly.
 | 
					            /// GUI accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
 | 
					            virtual void update (float duration, bool paused) = 0;
 | 
				
			||||||
                float duration, bool paused) = 0;
 | 
					            ///< Update objects
 | 
				
			||||||
            ///< Update actor stats and store desired velocity vectors in \a movement
 | 
					 | 
				
			||||||
            ///
 | 
					            ///
 | 
				
			||||||
            /// \param paused In game type does not currently advance (this usually means some GUI
 | 
					            /// \param paused In game type does not currently advance (this usually means some GUI
 | 
				
			||||||
            /// component is up).
 | 
					            /// component is up).
 | 
				
			||||||
| 
						 | 
					@ -98,6 +98,17 @@ namespace MWBase
 | 
				
			||||||
            virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type,
 | 
					            virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type,
 | 
				
			||||||
                float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) = 0;
 | 
					                float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) = 0;
 | 
				
			||||||
            ///< Perform a persuasion action on NPC
 | 
					            ///< Perform a persuasion action on NPC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number=1) = 0;
 | 
				
			||||||
 | 
					        ///< Run animation for a MW-reference. Calls to this function for references that are currently not
 | 
				
			||||||
 | 
					        /// in the scene should be ignored.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// \param mode 0 normal, 1 immediate start, 2 immediate loop
 | 
				
			||||||
 | 
					        /// \param count How many times the animation should be run
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0;
 | 
				
			||||||
 | 
					        ///< Skip the animation for the given MW-reference for one frame. Calls to this function for
 | 
				
			||||||
 | 
					        /// references that are currently not in the scene should be ignored.
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -198,7 +198,7 @@ namespace MWBase
 | 
				
			||||||
            virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0;
 | 
					            virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0;
 | 
				
			||||||
            ///< Hides dialog and schedules dialog to be deleted.
 | 
					            ///< Hides dialog and schedules dialog to be deleted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons) = 0;
 | 
					            virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>()) = 0;
 | 
				
			||||||
            virtual void enterPressed () = 0;
 | 
					            virtual void enterPressed () = 0;
 | 
				
			||||||
            virtual int readPressedButton() = 0;
 | 
					            virtual int readPressedButton() = 0;
 | 
				
			||||||
            ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
 | 
					            ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@
 | 
				
			||||||
#include <components/settings/settings.hpp>
 | 
					#include <components/settings/settings.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwworld/globals.hpp"
 | 
					#include "../mwworld/globals.hpp"
 | 
				
			||||||
 | 
					#include "../mwworld/ptr.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ogre
 | 
					namespace Ogre
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -19,6 +20,11 @@ namespace OEngine
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        class Fader;
 | 
					        class Fader;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    namespace Physic
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        class PhysicEngine;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ESM
 | 
					namespace ESM
 | 
				
			||||||
| 
						 | 
					@ -35,6 +41,7 @@ namespace ESM
 | 
				
			||||||
namespace MWRender
 | 
					namespace MWRender
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class ExternalRendering;
 | 
					    class ExternalRendering;
 | 
				
			||||||
 | 
					    class Animation;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWWorld
 | 
					namespace MWWorld
 | 
				
			||||||
| 
						 | 
					@ -42,10 +49,11 @@ namespace MWWorld
 | 
				
			||||||
    class CellStore;
 | 
					    class CellStore;
 | 
				
			||||||
    class Player;
 | 
					    class Player;
 | 
				
			||||||
    class LocalScripts;
 | 
					    class LocalScripts;
 | 
				
			||||||
    class Ptr;
 | 
					 | 
				
			||||||
    class TimeStamp;
 | 
					    class TimeStamp;
 | 
				
			||||||
    class ESMStore;
 | 
					    class ESMStore;
 | 
				
			||||||
    class RefData;
 | 
					    class RefData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typedef std::vector<std::pair<MWWorld::Ptr,Ogre::Vector3> > PtrMovementList;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWBase
 | 
					namespace MWBase
 | 
				
			||||||
| 
						 | 
					@ -227,8 +235,7 @@ namespace MWBase
 | 
				
			||||||
            virtual void positionToIndex (float x, float y, int &cellX, int &cellY) const = 0;
 | 
					            virtual void positionToIndex (float x, float y, int &cellX, int &cellY) const = 0;
 | 
				
			||||||
            ///< Convert position to cell numbers
 | 
					            ///< Convert position to cell numbers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
 | 
					            virtual void doPhysics (const MWWorld::PtrMovementList &actors, float duration) = 0;
 | 
				
			||||||
                float duration) = 0;
 | 
					 | 
				
			||||||
            ///< Run physics simulation and modify \a world accordingly.
 | 
					            ///< Run physics simulation and modify \a world accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual bool toggleCollisionMode() = 0;
 | 
					            virtual bool toggleCollisionMode() = 0;
 | 
				
			||||||
| 
						 | 
					@ -263,18 +270,6 @@ namespace MWBase
 | 
				
			||||||
            ///< Create a new recrod (of type npc) in the ESM store.
 | 
					            ///< Create a new recrod (of type npc) in the ESM store.
 | 
				
			||||||
            /// \return pointer to created record
 | 
					            /// \return pointer to created record
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName,
 | 
					 | 
				
			||||||
                int mode, int number = 1) = 0;
 | 
					 | 
				
			||||||
            ///< Run animation for a MW-reference. Calls to this function for references that are
 | 
					 | 
				
			||||||
            /// currently not in the rendered scene should be ignored.
 | 
					 | 
				
			||||||
            ///
 | 
					 | 
				
			||||||
            /// \param mode: 0 normal, 1 immediate start, 2 immediate loop
 | 
					 | 
				
			||||||
            /// \param number How offen the animation should be run
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            virtual void skipAnimation (const MWWorld::Ptr& ptr) = 0;
 | 
					 | 
				
			||||||
            ///< Skip the animation for the given MW-reference for one frame. Calls to this function for
 | 
					 | 
				
			||||||
            /// references that are currently not in the rendered scene should be ignored.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            virtual void update (float duration, bool paused) = 0;
 | 
					            virtual void update (float duration, bool paused) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual bool placeObject(const MWWorld::Ptr& object, float cursorX, float cursorY) = 0;
 | 
					            virtual bool placeObject(const MWWorld::Ptr& object, float cursorX, float cursorY) = 0;
 | 
				
			||||||
| 
						 | 
					@ -291,8 +286,10 @@ namespace MWBase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0;
 | 
					            virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual bool isSwimming(const MWWorld::Ptr &object) = 0;
 | 
					            virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
 | 
				
			||||||
            virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0;
 | 
					            virtual bool isSwimming(const MWWorld::Ptr &object) const = 0;
 | 
				
			||||||
 | 
					            virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const = 0;
 | 
				
			||||||
 | 
					            virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void togglePOV() = 0;
 | 
					            virtual void togglePOV() = 0;
 | 
				
			||||||
            virtual void togglePreviewMode(bool enable) = 0;
 | 
					            virtual void togglePreviewMode(bool enable) = 0;
 | 
				
			||||||
| 
						 | 
					@ -311,6 +308,8 @@ namespace MWBase
 | 
				
			||||||
            /// 2 - player is underwater \n
 | 
					            /// 2 - player is underwater \n
 | 
				
			||||||
            /// 3 - enemies are nearby (not implemented)
 | 
					            /// 3 - enemies are nearby (not implemented)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// \todo Probably shouldn't be here
 | 
				
			||||||
 | 
					            virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /// \todo this does not belong here
 | 
					            /// \todo this does not belong here
 | 
				
			||||||
            virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
 | 
					            virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,12 +5,13 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwbase/environment.hpp"
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
#include "../mwbase/windowmanager.hpp"
 | 
					#include "../mwbase/windowmanager.hpp"
 | 
				
			||||||
 | 
					#include "../mwbase/mechanicsmanager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwworld//cellstore.hpp"
 | 
					#include "../mwworld//cellstore.hpp"
 | 
				
			||||||
#include "../mwworld/ptr.hpp"
 | 
					#include "../mwworld/ptr.hpp"
 | 
				
			||||||
#include "../mwworld/physicssystem.hpp"
 | 
					#include "../mwworld/physicssystem.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwrender/objects.hpp"
 | 
					#include "../mwrender/actors.hpp"
 | 
				
			||||||
#include "../mwrender/renderinginterface.hpp"
 | 
					#include "../mwrender/renderinginterface.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwgui/tooltips.hpp"
 | 
					#include "../mwgui/tooltips.hpp"
 | 
				
			||||||
| 
						 | 
					@ -21,9 +22,8 @@ namespace MWClass
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        const std::string model = getModel(ptr);
 | 
					        const std::string model = getModel(ptr);
 | 
				
			||||||
        if (!model.empty()) {
 | 
					        if (!model.empty()) {
 | 
				
			||||||
            MWRender::Objects& objects = renderingInterface.getObjects();
 | 
					            MWRender::Actors& actors = renderingInterface.getActors();
 | 
				
			||||||
            objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
 | 
					            actors.insertActivator(ptr);
 | 
				
			||||||
            objects.insertMesh(ptr, model);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,7 @@ namespace MWClass
 | 
				
			||||||
        const std::string model = getModel(ptr);
 | 
					        const std::string model = getModel(ptr);
 | 
				
			||||||
        if(!model.empty())
 | 
					        if(!model.empty())
 | 
				
			||||||
            physics.addObject(ptr);
 | 
					            physics.addObject(ptr);
 | 
				
			||||||
 | 
					        MWBase::Environment::get().getMechanicsManager()->add(ptr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string Activator::getModel(const MWWorld::Ptr &ptr) const
 | 
					    std::string Activator::getModel(const MWWorld::Ptr &ptr) const
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@
 | 
				
			||||||
#include "../mwworld/physicssystem.hpp"
 | 
					#include "../mwworld/physicssystem.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwrender/renderinginterface.hpp"
 | 
					#include "../mwrender/renderinginterface.hpp"
 | 
				
			||||||
 | 
					#include "../mwrender/actors.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwgui/tooltips.hpp"
 | 
					#include "../mwgui/tooltips.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,7 +97,7 @@ namespace MWClass
 | 
				
			||||||
        const std::string model = getModel(ptr);
 | 
					        const std::string model = getModel(ptr);
 | 
				
			||||||
        if(!model.empty())
 | 
					        if(!model.empty())
 | 
				
			||||||
            physics.addActor(ptr);
 | 
					            physics.addActor(ptr);
 | 
				
			||||||
        MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
 | 
					        MWBase::Environment::get().getMechanicsManager()->add(ptr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string Creature::getModel(const MWWorld::Ptr &ptr) const
 | 
					    std::string Creature::getModel(const MWWorld::Ptr &ptr) const
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,7 @@
 | 
				
			||||||
#ifndef GAME_MWCLASS_CREATURE_H
 | 
					#ifndef GAME_MWCLASS_CREATURE_H
 | 
				
			||||||
#define GAME_MWCLASS_CREATURE_H
 | 
					#define GAME_MWCLASS_CREATURE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwrender/renderinginterface.hpp"
 | 
					#include "../mwworld/class.hpp"
 | 
				
			||||||
#include "../mwrender/actors.hpp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWClass
 | 
					namespace MWClass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,14 +36,9 @@ namespace MWClass
 | 
				
			||||||
        objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
 | 
					        objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!model.empty())
 | 
					        if (!model.empty())
 | 
				
			||||||
            objects.insertMesh(ptr, "meshes\\" + model);
 | 
					            objects.insertMesh(ptr, "meshes\\" + model, true);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
        const int color = ref->mBase->mData.mColor;
 | 
					            objects.insertLight(ptr);
 | 
				
			||||||
        const float r = ((color >> 0) & 0xFF) / 255.0f;
 | 
					 | 
				
			||||||
        const float g = ((color >> 8) & 0xFF) / 255.0f;
 | 
					 | 
				
			||||||
        const float b = ((color >> 16) & 0xFF) / 255.0f;
 | 
					 | 
				
			||||||
        const float radius = float (ref->mBase->mData.mRadius);
 | 
					 | 
				
			||||||
        objects.insertLight (ptr, r, g, b, radius);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
 | 
					    void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,9 +55,35 @@ namespace MWClass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    void Npc::ensureCustomData (const MWWorld::Ptr& ptr) const
 | 
					    void Npc::ensureCustomData (const MWWorld::Ptr& ptr) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        static bool inited = false;
 | 
				
			||||||
 | 
					        if(!inited)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            const MWBase::World *world = MWBase::Environment::get().getWorld();
 | 
				
			||||||
 | 
					            const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fMinWalkSpeed = gmst.find("fMinWalkSpeed");
 | 
				
			||||||
 | 
					            fMaxWalkSpeed = gmst.find("fMaxWalkSpeed");
 | 
				
			||||||
 | 
					            fEncumberedMoveEffect = gmst.find("fEncumberedMoveEffect");
 | 
				
			||||||
 | 
					            fSneakSpeedMultiplier = gmst.find("fSneakSpeedMultiplier");
 | 
				
			||||||
 | 
					            fAthleticsRunBonus = gmst.find("fAthleticsRunBonus");
 | 
				
			||||||
 | 
					            fBaseRunMultiplier = gmst.find("fBaseRunMultiplier");
 | 
				
			||||||
 | 
					            fMinFlySpeed = gmst.find("fMinFlySpeed");
 | 
				
			||||||
 | 
					            fMaxFlySpeed = gmst.find("fMaxFlySpeed");
 | 
				
			||||||
 | 
					            fSwimRunBase = gmst.find("fSwimRunBase");
 | 
				
			||||||
 | 
					            fSwimRunAthleticsMult = gmst.find("fSwimRunAthleticsMult");
 | 
				
			||||||
 | 
					            fJumpEncumbranceBase = gmst.find("fJumpEncumbranceBase");
 | 
				
			||||||
 | 
					            fJumpEncumbranceMultiplier = gmst.find("fJumpEncumbranceMultiplier");
 | 
				
			||||||
 | 
					            fJumpAcrobaticsBase = gmst.find("fJumpAcrobaticsBase");
 | 
				
			||||||
 | 
					            fJumpAcroMultiplier = gmst.find("fJumpAcroMultiplier");
 | 
				
			||||||
 | 
					            fJumpRunMultiplier = gmst.find("fJumpRunMultiplier");
 | 
				
			||||||
 | 
					            // Added in Tribunal/Bloodmoon, may not exist
 | 
				
			||||||
 | 
					            fWereWolfRunMult = gmst.search("fWereWolfRunMult");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            inited = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (!ptr.getRefData().getCustomData())
 | 
					        if (!ptr.getRefData().getCustomData())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            std::auto_ptr<CustomData> data (new CustomData);
 | 
					            std::auto_ptr<CustomData> data(new CustomData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
 | 
					            MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,7 +168,7 @@ 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.addActor(ptr);
 | 
					        physics.addActor(ptr);
 | 
				
			||||||
        MWBase::Environment::get().getMechanicsManager()->addActor(ptr);
 | 
					        MWBase::Environment::get().getMechanicsManager()->add(ptr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string Npc::getModel(const MWWorld::Ptr &ptr) const
 | 
					    std::string Npc::getModel(const MWWorld::Ptr &ptr) const
 | 
				
			||||||
| 
						 | 
					@ -297,9 +323,88 @@ namespace MWClass
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    float Npc::getSpeed (const MWWorld::Ptr& ptr) const
 | 
					    float Npc::getSpeed(const MWWorld::Ptr& ptr) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return getStance (ptr, Run) ? 600 : 300; // TODO calculate these values from stats
 | 
					        const MWBase::World *world = MWBase::Environment::get().getWorld();
 | 
				
			||||||
 | 
					        const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
 | 
				
			||||||
 | 
					        const MWMechanics::MagicEffects &mageffects = npcdata->mCreatureStats.getMagicEffects();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float walkSpeed = fMinWalkSpeed->getFloat() + 0.01f*npcdata->mCreatureStats.getAttribute(ESM::Attribute::Speed).getModified()*
 | 
				
			||||||
 | 
					                                                      (fMaxWalkSpeed->getFloat() - fMinWalkSpeed->getFloat());
 | 
				
			||||||
 | 
					        walkSpeed *= 1.0f - fEncumberedMoveEffect->getFloat()*normalizedEncumbrance;
 | 
				
			||||||
 | 
					        walkSpeed = std::max(0.0f, walkSpeed);
 | 
				
			||||||
 | 
					        if(Npc::getStance(ptr, Sneak, false))
 | 
				
			||||||
 | 
					            walkSpeed *= fSneakSpeedMultiplier->getFloat();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float runSpeed = walkSpeed*(0.01f * npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified() *
 | 
				
			||||||
 | 
					                                    fAthleticsRunBonus->getFloat() + fBaseRunMultiplier->getFloat());
 | 
				
			||||||
 | 
					        if(npcdata->mNpcStats.isWerewolf())
 | 
				
			||||||
 | 
					            runSpeed *= fWereWolfRunMult->getFloat();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float moveSpeed;
 | 
				
			||||||
 | 
					        if(normalizedEncumbrance >= 1.0f)
 | 
				
			||||||
 | 
					            moveSpeed = 0.0f;
 | 
				
			||||||
 | 
					        else if(mageffects.get(MWMechanics::EffectKey(10/*levitate*/)).mMagnitude > 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            float flySpeed = 0.01f*(npcdata->mCreatureStats.getAttribute(ESM::Attribute::Speed).getModified() +
 | 
				
			||||||
 | 
					                                    mageffects.get(MWMechanics::EffectKey(10/*levitate*/)).mMagnitude);
 | 
				
			||||||
 | 
					            flySpeed = fMinFlySpeed->getFloat() + flySpeed*(fMaxFlySpeed->getFloat() - fMinFlySpeed->getFloat());
 | 
				
			||||||
 | 
					            flySpeed *= 1.0f - fEncumberedMoveEffect->getFloat() * normalizedEncumbrance;
 | 
				
			||||||
 | 
					            flySpeed = std::max(0.0f, flySpeed);
 | 
				
			||||||
 | 
					            moveSpeed = flySpeed;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(world->isSwimming(ptr))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            float swimSpeed = walkSpeed;
 | 
				
			||||||
 | 
					            if(Npc::getStance(ptr, Run, false))
 | 
				
			||||||
 | 
					                swimSpeed = runSpeed;
 | 
				
			||||||
 | 
					            swimSpeed *= 1.0f + 0.01f * mageffects.get(MWMechanics::EffectKey(1/*swift swim*/)).mMagnitude;
 | 
				
			||||||
 | 
					            swimSpeed *= fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()*
 | 
				
			||||||
 | 
					                                                    fSwimRunAthleticsMult->getFloat();
 | 
				
			||||||
 | 
					            moveSpeed = swimSpeed;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(Npc::getStance(ptr, Run, false))
 | 
				
			||||||
 | 
					            moveSpeed = runSpeed;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            moveSpeed = walkSpeed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(getMovementSettings(ptr).mLeftRight != 0 && getMovementSettings(ptr).mForwardBackward == 0)
 | 
				
			||||||
 | 
					            moveSpeed *= 0.75f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return moveSpeed;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    float Npc::getJump(const MWWorld::Ptr &ptr) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
 | 
				
			||||||
 | 
					        const MWMechanics::MagicEffects &mageffects = npcdata->mCreatureStats.getMagicEffects();
 | 
				
			||||||
 | 
					        const float encumbranceTerm = fJumpEncumbranceBase->getFloat() +
 | 
				
			||||||
 | 
					                                          fJumpEncumbranceMultiplier->getFloat() *
 | 
				
			||||||
 | 
					                                          (1.0f - Npc::getEncumbrance(ptr)/Npc::getCapacity(ptr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float a = npcdata->mNpcStats.getSkill(ESM::Skill::Acrobatics).getModified();
 | 
				
			||||||
 | 
					        float b = 0.0f;
 | 
				
			||||||
 | 
					        if(a > 50.0f)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            b = a - 50.0f;
 | 
				
			||||||
 | 
					            a = 50.0f;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float x = fJumpAcrobaticsBase->getFloat() +
 | 
				
			||||||
 | 
					                  std::pow(a / 15.0f, fJumpAcroMultiplier->getFloat());
 | 
				
			||||||
 | 
					        x += 3 * b * fJumpAcroMultiplier->getFloat();
 | 
				
			||||||
 | 
					        x += mageffects.get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude * 64;
 | 
				
			||||||
 | 
					        x *= encumbranceTerm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(Npc::getStance(ptr, Run, false))
 | 
				
			||||||
 | 
					            x *= fJumpRunMultiplier->getFloat();
 | 
				
			||||||
 | 
					        x *= 1.25f;//fatigueTerm;
 | 
				
			||||||
 | 
					        x -= -627.2/*gravity constant*/;
 | 
				
			||||||
 | 
					        x /= 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return x;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
 | 
					    MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
 | 
				
			||||||
| 
						 | 
					@ -311,14 +416,10 @@ namespace MWClass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
 | 
					    Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ogre::Vector3 vector (0, 0, 0);
 | 
					        Ogre::Vector3 vector;
 | 
				
			||||||
 | 
					        vector.x = getMovementSettings(ptr).mLeftRight;
 | 
				
			||||||
        vector.x = getMovementSettings (ptr).mLeftRight * 127;
 | 
					        vector.y = getMovementSettings(ptr).mForwardBackward;
 | 
				
			||||||
        vector.y = getMovementSettings (ptr).mForwardBackward * 127;
 | 
					        vector.z = getMovementSettings(ptr).mUpDown;
 | 
				
			||||||
        vector.z = getMovementSettings(ptr).mUpDown * 127;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //if (getStance (ptr, Run, false))
 | 
					 | 
				
			||||||
        //    vector *= 2;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return vector;
 | 
					        return vector;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -420,4 +521,21 @@ namespace MWClass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
 | 
					        return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fMinWalkSpeed;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fMaxWalkSpeed;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fEncumberedMoveEffect;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fSneakSpeedMultiplier;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fAthleticsRunBonus;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fBaseRunMultiplier;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fMinFlySpeed;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fMaxFlySpeed;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fSwimRunBase;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fSwimRunAthleticsMult;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fJumpEncumbranceBase;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fJumpEncumbranceMultiplier;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fJumpAcrobaticsBase;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fJumpAcroMultiplier;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fJumpRunMultiplier;
 | 
				
			||||||
 | 
					    const ESM::GameSetting *Npc::fWereWolfRunMult;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwworld/class.hpp"
 | 
					#include "../mwworld/class.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace ESM
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class GameSetting;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWClass
 | 
					namespace MWClass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class Npc : public MWWorld::Class
 | 
					    class Npc : public MWWorld::Class
 | 
				
			||||||
| 
						 | 
					@ -12,6 +17,23 @@ namespace MWClass
 | 
				
			||||||
            virtual MWWorld::Ptr
 | 
					            virtual MWWorld::Ptr
 | 
				
			||||||
            copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
 | 
					            copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fMinWalkSpeed;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fMaxWalkSpeed;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fEncumberedMoveEffect;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fSneakSpeedMultiplier;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fAthleticsRunBonus;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fBaseRunMultiplier;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fMinFlySpeed;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fMaxFlySpeed;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fSwimRunBase;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fSwimRunAthleticsMult;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fJumpEncumbranceBase;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fJumpEncumbranceMultiplier;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fJumpAcrobaticsBase;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fJumpAcroMultiplier;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fJumpRunMultiplier;
 | 
				
			||||||
 | 
					            static const ESM::GameSetting *fWereWolfRunMult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public:
 | 
					        public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual std::string getId (const MWWorld::Ptr& ptr) const;
 | 
					            virtual std::string getId (const MWWorld::Ptr& ptr) const;
 | 
				
			||||||
| 
						 | 
					@ -64,6 +86,9 @@ namespace MWClass
 | 
				
			||||||
            virtual float getSpeed (const MWWorld::Ptr& ptr) const;
 | 
					            virtual float getSpeed (const MWWorld::Ptr& ptr) const;
 | 
				
			||||||
            ///< Return movement speed.
 | 
					            ///< Return movement speed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual float getJump(const MWWorld::Ptr &ptr) const;
 | 
				
			||||||
 | 
					            ///< Return jump velocity (not accounting for movement)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
 | 
					            virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
 | 
				
			||||||
            ///< Return desired movement.
 | 
					            ///< Return desired movement.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
#include "dialoguemanagerimp.hpp"
 | 
					#include "dialoguemanagerimp.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cctype>
 | 
					#include <cctype>
 | 
				
			||||||
 | 
					#include <cstdlib>
 | 
				
			||||||
#include <algorithm>
 | 
					#include <algorithm>
 | 
				
			||||||
#include <iterator>
 | 
					#include <iterator>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -251,8 +252,12 @@ namespace MWDialogue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
 | 
					        MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (const ESM::DialInfo *info = filter.search (dialogue, true))
 | 
					        std::vector<const ESM::DialInfo *> infos = filter.list (dialogue, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!infos.empty())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            const ESM::DialInfo* info = infos[std::rand() % infos.size()];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            parseText (info->mResponse);
 | 
					            parseText (info->mResponse);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (dialogue.mType==ESM::Dialogue::Persuasion)
 | 
					            if (dialogue.mType==ESM::Dialogue::Persuasion)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -289,7 +289,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case SelectWrapper::Function_PcGender:
 | 
					        case SelectWrapper::Function_PcGender:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female ? 0 : 1;
 | 
					            return player.get<ESM::NPC>()->mBase->isMale() ? 0 : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case SelectWrapper::Function_PcClothingModifier:
 | 
					        case SelectWrapper::Function_PcClothingModifier:
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -559,8 +559,21 @@ MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedTo
 | 
				
			||||||
: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
 | 
					: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
 | 
				
			||||||
{}
 | 
					{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const
 | 
					const ESM::DialInfo* MWDialogue::Filter::search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    std::vector<const ESM::DialInfo *> suitableInfos = list (dialogue, fallbackToInfoRefusal, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (suitableInfos.empty())
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return suitableInfos[0];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue& dialogue,
 | 
				
			||||||
 | 
					    bool fallbackToInfoRefusal, bool searchAll) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    std::vector<const ESM::DialInfo *> infos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool infoRefusal = false;
 | 
					    bool infoRefusal = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Iterate over topic responses to find a matching one
 | 
					    // Iterate over topic responses to find a matching one
 | 
				
			||||||
| 
						 | 
					@ -569,14 +582,17 @@ const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
 | 
					        if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (testDisposition (*iter))
 | 
					            if (testDisposition (*iter)) {
 | 
				
			||||||
                return &*iter;
 | 
					                infos.push_back(&*iter);
 | 
				
			||||||
 | 
					                if (!searchAll)
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                infoRefusal = true;
 | 
					                infoRefusal = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (infoRefusal && fallbackToInfoRefusal)
 | 
					    if (infos.empty() && infoRefusal && fallbackToInfoRefusal)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // No response is valid because of low NPC disposition,
 | 
					        // No response is valid because of low NPC disposition,
 | 
				
			||||||
        // search a response in the topic "Info Refusal"
 | 
					        // search a response in the topic "Info Refusal"
 | 
				
			||||||
| 
						 | 
					@ -588,11 +604,14 @@ const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (std::vector<ESM::DialInfo>::const_iterator iter = infoRefusalDialogue.mInfo.begin();
 | 
					        for (std::vector<ESM::DialInfo>::const_iterator iter = infoRefusalDialogue.mInfo.begin();
 | 
				
			||||||
            iter!=infoRefusalDialogue.mInfo.end(); ++iter)
 | 
					            iter!=infoRefusalDialogue.mInfo.end(); ++iter)
 | 
				
			||||||
            if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter))
 | 
					            if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter)) {
 | 
				
			||||||
                return &*iter;
 | 
					                infos.push_back(&*iter);
 | 
				
			||||||
 | 
					                if (!searchAll)
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return infos;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const
 | 
					bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
#ifndef GAME_MWDIALOGUE_FILTER_H
 | 
					#ifndef GAME_MWDIALOGUE_FILTER_H
 | 
				
			||||||
#define GAME_MWDIALOGUE_FILTER_H
 | 
					#define GAME_MWDIALOGUE_FILTER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwworld/ptr.hpp"
 | 
					#include "../mwworld/ptr.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ESM
 | 
					namespace ESM
 | 
				
			||||||
| 
						 | 
					@ -51,7 +53,10 @@ namespace MWDialogue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
 | 
					            Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const ESM::DialInfo *search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
 | 
					            std::vector<const ESM::DialInfo *> list (const ESM::Dialogue& dialogue,
 | 
				
			||||||
 | 
					                bool fallbackToInfoRefusal, bool searchAll) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
 | 
				
			||||||
            ///< Get a matching response for the requested dialogue.
 | 
					            ///< Get a matching response for the requested dialogue.
 | 
				
			||||||
            ///  Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition.
 | 
					            ///  Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@ bool sortBirthSigns(const std::pair<std::string, const ESM::BirthSign*>& left, c
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager)
 | 
					BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
  : WindowBase("openmw_chargen_birth.layout", parWindowManager)
 | 
					  : WindowModal("openmw_chargen_birth.layout", parWindowManager)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Centre dialog
 | 
					    // Centre dialog
 | 
				
			||||||
    center();
 | 
					    center();
 | 
				
			||||||
| 
						 | 
					@ -66,7 +66,7 @@ void BirthDialog::setNextButtonShow(bool shown)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void BirthDialog::open()
 | 
					void BirthDialog::open()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    WindowBase::open();
 | 
					    WindowModal::open();
 | 
				
			||||||
    updateBirths();
 | 
					    updateBirths();
 | 
				
			||||||
    updateSpells();
 | 
					    updateSpells();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWGui
 | 
					namespace MWGui
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class BirthDialog : public WindowBase
 | 
					    class BirthDialog : public WindowModal
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        BirthDialog(MWBase::WindowManager& parWindowManager);
 | 
					        BirthDialog(MWBase::WindowManager& parWindowManager);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ using namespace MWGui;
 | 
				
			||||||
/* GenerateClassResultDialog */
 | 
					/* GenerateClassResultDialog */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GenerateClassResultDialog::GenerateClassResultDialog(MWBase::WindowManager& parWindowManager)
 | 
					GenerateClassResultDialog::GenerateClassResultDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
  : WindowBase("openmw_chargen_generate_class_result.layout", parWindowManager)
 | 
					  : WindowModal("openmw_chargen_generate_class_result.layout", parWindowManager)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Centre dialog
 | 
					    // Centre dialog
 | 
				
			||||||
    center();
 | 
					    center();
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,7 @@ void GenerateClassResultDialog::onBackClicked(MyGUI::Widget* _sender)
 | 
				
			||||||
/* PickClassDialog */
 | 
					/* PickClassDialog */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PickClassDialog::PickClassDialog(MWBase::WindowManager& parWindowManager)
 | 
					PickClassDialog::PickClassDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
  : WindowBase("openmw_chargen_class.layout", parWindowManager)
 | 
					  : WindowModal("openmw_chargen_class.layout", parWindowManager)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Centre dialog
 | 
					    // Centre dialog
 | 
				
			||||||
    center();
 | 
					    center();
 | 
				
			||||||
| 
						 | 
					@ -122,6 +122,7 @@ void PickClassDialog::setNextButtonShow(bool shown)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void PickClassDialog::open()
 | 
					void PickClassDialog::open()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    WindowModal::open ();
 | 
				
			||||||
    updateClasses();
 | 
					    updateClasses();
 | 
				
			||||||
    updateStats();
 | 
					    updateStats();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -276,7 +277,7 @@ void InfoBoxDialog::layoutVertically(MyGUI::WidgetPtr widget, int margin)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
InfoBoxDialog::InfoBoxDialog(MWBase::WindowManager& parWindowManager)
 | 
					InfoBoxDialog::InfoBoxDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
    : WindowBase("openmw_infobox.layout", parWindowManager)
 | 
					    : WindowModal("openmw_infobox.layout", parWindowManager)
 | 
				
			||||||
    , mCurrentButton(-1)
 | 
					    , mCurrentButton(-1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    getWidget(mTextBox, "TextBox");
 | 
					    getWidget(mTextBox, "TextBox");
 | 
				
			||||||
| 
						 | 
					@ -327,6 +328,7 @@ void InfoBoxDialog::setButtons(ButtonList &buttons)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void InfoBoxDialog::open()
 | 
					void InfoBoxDialog::open()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    WindowModal::open();
 | 
				
			||||||
    // Fix layout
 | 
					    // Fix layout
 | 
				
			||||||
    layoutVertically(mTextBox, 4);
 | 
					    layoutVertically(mTextBox, 4);
 | 
				
			||||||
    layoutVertically(mButtonBar, 6);
 | 
					    layoutVertically(mButtonBar, 6);
 | 
				
			||||||
| 
						 | 
					@ -373,7 +375,7 @@ ClassChoiceDialog::ClassChoiceDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
/* CreateClassDialog */
 | 
					/* CreateClassDialog */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CreateClassDialog::CreateClassDialog(MWBase::WindowManager& parWindowManager)
 | 
					CreateClassDialog::CreateClassDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
  : WindowBase("openmw_chargen_create_class.layout", parWindowManager)
 | 
					  : WindowModal("openmw_chargen_create_class.layout", parWindowManager)
 | 
				
			||||||
  , mSpecDialog(nullptr)
 | 
					  , mSpecDialog(nullptr)
 | 
				
			||||||
  , mAttribDialog(nullptr)
 | 
					  , mAttribDialog(nullptr)
 | 
				
			||||||
  , mSkillDialog(nullptr)
 | 
					  , mSkillDialog(nullptr)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWGui
 | 
					namespace MWGui
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class InfoBoxDialog : public WindowBase
 | 
					    class InfoBoxDialog : public WindowModal
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        InfoBoxDialog(MWBase::WindowManager& parWindowManager);
 | 
					        InfoBoxDialog(MWBase::WindowManager& parWindowManager);
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ namespace MWGui
 | 
				
			||||||
        ClassChoiceDialog(MWBase::WindowManager& parWindowManager);
 | 
					        ClassChoiceDialog(MWBase::WindowManager& parWindowManager);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class GenerateClassResultDialog : public WindowBase
 | 
					    class GenerateClassResultDialog : public WindowModal
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        GenerateClassResultDialog(MWBase::WindowManager& parWindowManager);
 | 
					        GenerateClassResultDialog(MWBase::WindowManager& parWindowManager);
 | 
				
			||||||
| 
						 | 
					@ -90,7 +90,7 @@ namespace MWGui
 | 
				
			||||||
        std::string mCurrentClassId;
 | 
					        std::string mCurrentClassId;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class PickClassDialog : public WindowBase
 | 
					    class PickClassDialog : public WindowModal
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        PickClassDialog(MWBase::WindowManager& parWindowManager);
 | 
					        PickClassDialog(MWBase::WindowManager& parWindowManager);
 | 
				
			||||||
| 
						 | 
					@ -238,7 +238,7 @@ namespace MWGui
 | 
				
			||||||
        MyGUI::EditPtr mTextEdit;
 | 
					        MyGUI::EditPtr mTextEdit;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class CreateClassDialog : public WindowBase
 | 
					    class CreateClassDialog : public WindowModal
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        CreateClassDialog(MWBase::WindowManager& parWindowManager);
 | 
					        CreateClassDialog(MWBase::WindowManager& parWindowManager);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										130
									
								
								apps/openmw/mwgui/cursor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								apps/openmw/mwgui/cursor.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,130 @@
 | 
				
			||||||
 | 
					#include "cursor.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <MyGUI_PointerManager.h>
 | 
				
			||||||
 | 
					#include <MyGUI_InputManager.h>
 | 
				
			||||||
 | 
					#include <MyGUI_RenderManager.h>
 | 
				
			||||||
 | 
					#include <MyGUI_RotatingSkin.h>
 | 
				
			||||||
 | 
					#include <MyGUI_Gui.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <OgreMath.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWGui
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ResourceImageSetPointerFix::ResourceImageSetPointerFix() :
 | 
				
			||||||
 | 
					        mImageSet(nullptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ResourceImageSetPointerFix::~ResourceImageSetPointerFix()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void ResourceImageSetPointerFix::deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Base::deserialization(_node, _version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MyGUI::xml::ElementEnumerator info = _node->getElementEnumerator();
 | 
				
			||||||
 | 
					        while (info.next("Property"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            const std::string& key = info->findAttribute("key");
 | 
				
			||||||
 | 
					            const std::string& value = info->findAttribute("value");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (key == "Point")
 | 
				
			||||||
 | 
					                mPoint = MyGUI::IntPoint::parse(value);
 | 
				
			||||||
 | 
					            else if (key == "Size")
 | 
				
			||||||
 | 
					                mSize = MyGUI::IntSize::parse(value);
 | 
				
			||||||
 | 
					            else if (key == "Rotation")
 | 
				
			||||||
 | 
					                mRotation = MyGUI::utility::parseInt(value);
 | 
				
			||||||
 | 
					            else if (key == "Resource")
 | 
				
			||||||
 | 
					                mImageSet = MyGUI::ResourceManager::getInstance().getByName(value)->castType<MyGUI::ResourceImageSet>();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int ResourceImageSetPointerFix::getRotation()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return mRotation;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void ResourceImageSetPointerFix::setImage(MyGUI::ImageBox* _image)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (mImageSet != nullptr)
 | 
				
			||||||
 | 
					            _image->setItemResourceInfo(mImageSet->getIndexInfo(0, 0));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void ResourceImageSetPointerFix::setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _image->setCoord(_point.left - mPoint.left, _point.top - mPoint.top, mSize.width, mSize.height);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MyGUI::ResourceImageSetPtr ResourceImageSetPointerFix:: getImageSet()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return mImageSet;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MyGUI::IntPoint ResourceImageSetPointerFix::getHotSpot()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return mPoint;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MyGUI::IntSize ResourceImageSetPointerFix::getSize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return mSize;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ----------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Cursor::Cursor()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // hide mygui's pointer since we're rendering it ourselves (because mygui's pointer doesn't support rotation)
 | 
				
			||||||
 | 
					        MyGUI::PointerManager::getInstance().setVisible(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &Cursor::onCursorChange);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mWidget = MyGUI::Gui::getInstance().createWidget<MyGUI::ImageBox>("RotatingSkin",0,0,0,0,MyGUI::Align::Default,"Pointer","");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Cursor::~Cursor()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void Cursor::onCursorChange(const std::string &name)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ResourceImageSetPointerFix* imgSetPtr = dynamic_cast<ResourceImageSetPointerFix*>(
 | 
				
			||||||
 | 
					                    MyGUI::PointerManager::getInstance().getByName(name));
 | 
				
			||||||
 | 
					        assert(imgSetPtr != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MyGUI::ResourceImageSet* imgSet = imgSetPtr->getImageSet();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::string texture = imgSet->getIndexInfo(0,0).texture;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mSize = imgSetPtr->getSize();
 | 
				
			||||||
 | 
					        mHotSpot = imgSetPtr->getHotSpot();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int rotation = imgSetPtr->getRotation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mWidget->setImageTexture(texture);
 | 
				
			||||||
 | 
					        MyGUI::ISubWidget* main = mWidget->getSubWidgetMain();
 | 
				
			||||||
 | 
					        MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
 | 
				
			||||||
 | 
					        rotatingSubskin->setCenter(MyGUI::IntPoint(mSize.width/2,mSize.height/2));
 | 
				
			||||||
 | 
					        rotatingSubskin->setAngle(Ogre::Degree(rotation).valueRadians());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void Cursor::update()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MyGUI::IntPoint position = MyGUI::InputManager::getInstance().getMousePosition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mWidget->setPosition(position - mHotSpot);
 | 
				
			||||||
 | 
					        mWidget->setSize(mSize);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void Cursor::setVisible(bool visible)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        mWidget->setVisible(visible);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								apps/openmw/mwgui/cursor.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								apps/openmw/mwgui/cursor.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,62 @@
 | 
				
			||||||
 | 
					#ifndef MWGUI_CURSOR_H
 | 
				
			||||||
 | 
					#define MWGUI_CURSOR_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <MyGUI_IPointer.h>
 | 
				
			||||||
 | 
					#include <MyGUI_ResourceImageSet.h>
 | 
				
			||||||
 | 
					#include <MyGUI_RTTI.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWGui
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// \brief Allows us to get the members of
 | 
				
			||||||
 | 
					    ///        ResourceImageSetPointer that we need.
 | 
				
			||||||
 | 
					    /// \example MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
 | 
				
			||||||
 | 
					    ///          MyGUI::ResourceManager::getInstance().load("core.xml");
 | 
				
			||||||
 | 
					    class ResourceImageSetPointerFix :
 | 
				
			||||||
 | 
					        public MyGUI::IPointer
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MYGUI_RTTI_DERIVED( ResourceImageSetPointerFix )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        ResourceImageSetPointerFix();
 | 
				
			||||||
 | 
					        virtual ~ResourceImageSetPointerFix();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual void setImage(MyGUI::ImageBox* _image);
 | 
				
			||||||
 | 
					        virtual void setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //and now for the whole point of this class, allow us to get
 | 
				
			||||||
 | 
					        //the hot spot, the image and the size of the cursor.
 | 
				
			||||||
 | 
					        virtual MyGUI::ResourceImageSetPtr getImageSet();
 | 
				
			||||||
 | 
					        virtual MyGUI::IntPoint getHotSpot();
 | 
				
			||||||
 | 
					        virtual MyGUI::IntSize getSize();
 | 
				
			||||||
 | 
					        virtual int getRotation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        MyGUI::IntPoint mPoint;
 | 
				
			||||||
 | 
					        MyGUI::IntSize mSize;
 | 
				
			||||||
 | 
					        MyGUI::ResourceImageSetPtr mImageSet;
 | 
				
			||||||
 | 
					        int mRotation; // rotation in degrees
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Cursor
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        Cursor();
 | 
				
			||||||
 | 
					        ~Cursor();
 | 
				
			||||||
 | 
					        void update ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void setVisible (bool visible);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void onCursorChange (const std::string& name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        MyGUI::ImageBox* mWidget;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MyGUI::IntSize mSize;
 | 
				
			||||||
 | 
					        MyGUI::IntPoint mHotSpot;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -1,16 +0,0 @@
 | 
				
			||||||
#include "cursorreplace.hpp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <boost/filesystem.hpp>
 | 
					 | 
				
			||||||
#include <openengine/ogre/imagerotate.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <OgreResourceGroupManager.h>
 | 
					 | 
				
			||||||
#include <OgreRoot.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace MWGui;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CursorReplace::CursorReplace()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90);
 | 
					 | 
				
			||||||
    OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize1.png", -45);
 | 
					 | 
				
			||||||
    OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize2.png", 45);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,16 +0,0 @@
 | 
				
			||||||
#ifndef GAME_CURSORREPLACE_H
 | 
					 | 
				
			||||||
#define GAME_CURSORREPLACE_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace MWGui
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// \brief MyGUI does not support rotating cursors, so we have to do it manually
 | 
					 | 
				
			||||||
    class CursorReplace
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        CursorReplace();
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
| 
						 | 
					@ -106,7 +106,7 @@ namespace MWGui
 | 
				
			||||||
        float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading);
 | 
					        float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading);
 | 
				
			||||||
        assert(progress <= 1 && progress >= 0);
 | 
					        assert(progress <= 1 && progress >= 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mLoadingText->setCaption(stage + "... ");
 | 
					        mLoadingText->setCaption(stage);
 | 
				
			||||||
        mProgressBar->setProgressPosition (static_cast<size_t>(progress * 1000));
 | 
					        mProgressBar->setProgressPosition (static_cast<size_t>(progress * 1000));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static float loadingScreenFps = 30.f;
 | 
					        static float loadingScreenFps = 30.f;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
#include "../mwbase/environment.hpp"
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
#include "../mwbase/world.hpp"
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
#include "../mwbase/windowmanager.hpp"
 | 
					#include "../mwbase/windowmanager.hpp"
 | 
				
			||||||
 | 
					#include "../mwbase/soundmanager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWGui
 | 
					namespace MWGui
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -65,6 +66,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void MainMenu::onButtonClicked(MyGUI::Widget *sender)
 | 
					    void MainMenu::onButtonClicked(MyGUI::Widget *sender)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
 | 
				
			||||||
        if (sender == mButtons["return"])
 | 
					        if (sender == mButtons["return"])
 | 
				
			||||||
            MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu);
 | 
					            MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu);
 | 
				
			||||||
        else if (sender == mButtons["options"])
 | 
					        else if (sender == mButtons["options"])
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,8 @@
 | 
				
			||||||
#include <OgreTextureManager.h>
 | 
					#include <OgreTextureManager.h>
 | 
				
			||||||
#include <OgreSceneNode.h>
 | 
					#include <OgreSceneNode.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <MyGUI_Gui.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwbase/windowmanager.hpp"
 | 
					#include "../mwbase/windowmanager.hpp"
 | 
				
			||||||
#include "../mwbase/world.hpp"
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
#include "../mwbase/environment.hpp"
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
| 
						 | 
					@ -13,6 +15,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwrender/globalmap.hpp"
 | 
					#include "../mwrender/globalmap.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "widgets.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace MWGui;
 | 
					using namespace MWGui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LocalMapBase::LocalMapBase()
 | 
					LocalMapBase::LocalMapBase()
 | 
				
			||||||
| 
						 | 
					@ -88,7 +92,7 @@ void LocalMapBase::applyFogOfWar()
 | 
				
			||||||
                    + boost::lexical_cast<std::string>(my);
 | 
					                    + boost::lexical_cast<std::string>(my);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
 | 
					            std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
 | 
				
			||||||
                    + boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1)));
 | 
					                    + boost::lexical_cast<std::string>(mCurY + (-1*(my-1)));
 | 
				
			||||||
            MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx];
 | 
					            MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx];
 | 
				
			||||||
            fog->setImageTexture(mFogOfWar ?
 | 
					            fog->setImageTexture(mFogOfWar ?
 | 
				
			||||||
                ((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
 | 
					                ((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
 | 
				
			||||||
| 
						 | 
					@ -96,6 +100,7 @@ void LocalMapBase::applyFogOfWar()
 | 
				
			||||||
               : "");
 | 
					               : "");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    notifyMapChanged ();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
 | 
					void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
 | 
				
			||||||
| 
						 | 
					@ -127,7 +132,7 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // map
 | 
					            // map
 | 
				
			||||||
            std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
 | 
					            std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
 | 
				
			||||||
                    + boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1)));
 | 
					                    + boost::lexical_cast<std::string>(y + (-1*(my-1)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
 | 
					            std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
 | 
				
			||||||
                    + boost::lexical_cast<std::string>(my);
 | 
					                    + boost::lexical_cast<std::string>(my);
 | 
				
			||||||
| 
						 | 
					@ -173,7 +178,7 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Ogre::Vector2 position (marker.x, -marker.y);
 | 
					                    Ogre::Vector2 position (marker.x, marker.y);
 | 
				
			||||||
                    MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy);
 | 
					                    MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + (1+cellDx-x) * 512, nY * 512 - 4 + (1+cellDy-y) * 512, 8, 8);
 | 
					                    widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + (1+cellDx-x) * 512, nY * 512 - 4 + (1+cellDy-y) * 512, 8, 8);
 | 
				
			||||||
| 
						 | 
					@ -394,10 +399,10 @@ void MapWindow::globalMapUpdatePlayer ()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
 | 
					    Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
 | 
				
			||||||
    Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
 | 
					    Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
 | 
				
			||||||
    Ogre::Vector2 dir (orient.yAxis ().x, -orient.yAxis().z);
 | 
					    Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    float worldX, worldY;
 | 
					    float worldX, worldY;
 | 
				
			||||||
    mGlobalMapRender->worldPosToImageSpace (pos.x, pos.z, worldX, worldY);
 | 
					    mGlobalMapRender->worldPosToImageSpace (pos.x, pos.y, worldX, worldY);
 | 
				
			||||||
    worldX *= mGlobalMapRender->getWidth();
 | 
					    worldX *= mGlobalMapRender->getWidth();
 | 
				
			||||||
    worldY *= mGlobalMapRender->getHeight();
 | 
					    worldY *= mGlobalMapRender->getHeight();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -425,3 +430,17 @@ void MapWindow::notifyPlayerUpdate ()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    globalMapUpdatePlayer ();
 | 
					    globalMapUpdatePlayer ();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MapWindow::notifyMapChanged ()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // workaround to prevent the map from drawing on top of the button
 | 
				
			||||||
 | 
					    MyGUI::IntCoord oldCoord = mButton->getCoord ();
 | 
				
			||||||
 | 
					    MyGUI::Gui::getInstance().destroyWidget (mButton);
 | 
				
			||||||
 | 
					    mButton = mMainWidget->createWidget<MWGui::Widgets::AutoSizedButton>("MW_Button",
 | 
				
			||||||
 | 
					         oldCoord, MyGUI::Align::Bottom | MyGUI::Align::Right);
 | 
				
			||||||
 | 
					    mButton->setProperty ("ExpandDirection", "Left");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
 | 
				
			||||||
 | 
					    mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" :
 | 
				
			||||||
 | 
					            "#{sWorld}");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,7 @@ namespace MWGui
 | 
				
			||||||
        void onMarkerUnfocused(MyGUI::Widget* w1, MyGUI::Widget* w2);
 | 
					        void onMarkerUnfocused(MyGUI::Widget* w1, MyGUI::Widget* w2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual void notifyPlayerUpdate() {}
 | 
					        virtual void notifyPlayerUpdate() {}
 | 
				
			||||||
 | 
					        virtual void notifyMapChanged() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        OEngine::GUI::Layout* mLayout;
 | 
					        OEngine::GUI::Layout* mLayout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +100,8 @@ namespace MWGui
 | 
				
			||||||
        virtual void onPinToggled();
 | 
					        virtual void onPinToggled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual void notifyPlayerUpdate();
 | 
					        virtual void notifyPlayerUpdate();
 | 
				
			||||||
 | 
					        virtual void notifyMapChanged();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
#include <components/misc/stringops.hpp>
 | 
					#include <components/misc/stringops.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "messagebox.hpp"
 | 
					#include "messagebox.hpp"
 | 
				
			||||||
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
 | 
					#include "../mwbase/soundmanager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace MWGui;
 | 
					using namespace MWGui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -375,6 +377,7 @@ void InteractiveMessageBox::enterPressed()
 | 
				
			||||||
        if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
 | 
					        if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            buttonActivated(*button);
 | 
					            buttonActivated(*button);
 | 
				
			||||||
 | 
					            MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@ using namespace MWGui;
 | 
				
			||||||
using namespace Widgets;
 | 
					using namespace Widgets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
 | 
					RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
  : WindowBase("openmw_chargen_race.layout", parWindowManager)
 | 
					  : WindowModal("openmw_chargen_race.layout", parWindowManager)
 | 
				
			||||||
  , mGenderIndex(0)
 | 
					  , mGenderIndex(0)
 | 
				
			||||||
  , mFaceIndex(0)
 | 
					  , mFaceIndex(0)
 | 
				
			||||||
  , mHairIndex(0)
 | 
					  , mHairIndex(0)
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
    prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair);
 | 
					    prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair);
 | 
				
			||||||
    nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair);
 | 
					    nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu4", "Race"));
 | 
					    setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu5", "Race"));
 | 
				
			||||||
    getWidget(mRaceList, "RaceList");
 | 
					    getWidget(mRaceList, "RaceList");
 | 
				
			||||||
    mRaceList->setScrollVisible(true);
 | 
					    mRaceList->setScrollVisible(true);
 | 
				
			||||||
    mRaceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
 | 
					    mRaceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
 | 
				
			||||||
| 
						 | 
					@ -100,6 +100,8 @@ void RaceDialog::setNextButtonShow(bool shown)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RaceDialog::open()
 | 
					void RaceDialog::open()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    WindowModal::open();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    updateRaces();
 | 
					    updateRaces();
 | 
				
			||||||
    updateSkills();
 | 
					    updateSkills();
 | 
				
			||||||
    updateSpellPowers();
 | 
					    updateSpellPowers();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWGui
 | 
					namespace MWGui
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class RaceDialog : public WindowBase
 | 
					    class RaceDialog : public WindowModal
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RaceDialog(MWBase::WindowManager& parWindowManager);
 | 
					        RaceDialog(MWBase::WindowManager& parWindowManager);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ using namespace Widgets;
 | 
				
			||||||
const int ReviewDialog::sLineHeight = 18;
 | 
					const int ReviewDialog::sLineHeight = 18;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ReviewDialog::ReviewDialog(MWBase::WindowManager& parWindowManager)
 | 
					ReviewDialog::ReviewDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
    : WindowBase("openmw_chargen_review.layout", parWindowManager)
 | 
					    : WindowModal("openmw_chargen_review.layout", parWindowManager)
 | 
				
			||||||
    , mLastPos(0)
 | 
					    , mLastPos(0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Centre dialog
 | 
					    // Centre dialog
 | 
				
			||||||
| 
						 | 
					@ -97,6 +97,7 @@ ReviewDialog::ReviewDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ReviewDialog::open()
 | 
					void ReviewDialog::open()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    WindowModal::open();
 | 
				
			||||||
    updateSkillArea();
 | 
					    updateSkillArea();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ Layout is defined by resources/mygui/openmw_chargen_review.layout.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWGui
 | 
					namespace MWGui
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class ReviewDialog : public WindowBase
 | 
					    class ReviewDialog : public WindowModal
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        enum Dialogs {
 | 
					        enum Dialogs {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
using namespace MWGui;
 | 
					using namespace MWGui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TextInputDialog::TextInputDialog(MWBase::WindowManager& parWindowManager)
 | 
					TextInputDialog::TextInputDialog(MWBase::WindowManager& parWindowManager)
 | 
				
			||||||
  : WindowBase("openmw_text_input.layout", parWindowManager)
 | 
					  : WindowModal("openmw_text_input.layout", parWindowManager)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Centre dialog
 | 
					    // Centre dialog
 | 
				
			||||||
    center();
 | 
					    center();
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,7 @@ void TextInputDialog::setTextLabel(const std::string &label)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TextInputDialog::open()
 | 
					void TextInputDialog::open()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    WindowModal::open();
 | 
				
			||||||
    // Make sure the edit box has focus
 | 
					    // Make sure the edit box has focus
 | 
				
			||||||
    MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
 | 
					    MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWGui
 | 
					namespace MWGui
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class TextInputDialog : public WindowBase
 | 
					    class TextInputDialog : public WindowModal
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        TextInputDialog(MWBase::WindowManager& parWindowManager);
 | 
					        TextInputDialog(MWBase::WindowManager& parWindowManager);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,11 +19,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "inventorywindow.hpp"
 | 
					#include "inventorywindow.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const float BALANCE_CHANGE_INITIAL_PAUSE = 0.5; // in seconds
 | 
					 | 
				
			||||||
static const float BALANCE_CHANGE_INTERVAL = 0.1; // in seconds
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace MWGui
 | 
					namespace MWGui
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    const float TradeWindow::sBalanceChangeInitialPause = 0.5;
 | 
				
			||||||
 | 
					    const float TradeWindow::sBalanceChangeInterval = 0.1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TradeWindow::TradeWindow(MWBase::WindowManager& parWindowManager) :
 | 
					    TradeWindow::TradeWindow(MWBase::WindowManager& parWindowManager) :
 | 
				
			||||||
        WindowBase("openmw_trade_window.layout", parWindowManager)
 | 
					        WindowBase("openmw_trade_window.layout", parWindowManager)
 | 
				
			||||||
        , ContainerBase(NULL) // no drag&drop
 | 
					        , ContainerBase(NULL) // no drag&drop
 | 
				
			||||||
| 
						 | 
					@ -157,7 +157,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mBalanceChangePause -= frameDuration;
 | 
					        mBalanceChangePause -= frameDuration;
 | 
				
			||||||
        if (mBalanceChangePause < 0.0) {
 | 
					        if (mBalanceChangePause < 0.0) {
 | 
				
			||||||
            mBalanceChangePause += BALANCE_CHANGE_INTERVAL;
 | 
					            mBalanceChangePause += sBalanceChangeInterval;
 | 
				
			||||||
            if (mBalanceButtonsState == BBS_Increase)
 | 
					            if (mBalanceButtonsState == BBS_Increase)
 | 
				
			||||||
                onIncreaseButtonTriggered();
 | 
					                onIncreaseButtonTriggered();
 | 
				
			||||||
            else if (mBalanceButtonsState == BBS_Decrease)
 | 
					            else if (mBalanceButtonsState == BBS_Decrease)
 | 
				
			||||||
| 
						 | 
					@ -296,14 +296,14 @@ namespace MWGui
 | 
				
			||||||
    void TradeWindow::onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
 | 
					    void TradeWindow::onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mBalanceButtonsState = BBS_Increase;
 | 
					        mBalanceButtonsState = BBS_Increase;
 | 
				
			||||||
        mBalanceChangePause = BALANCE_CHANGE_INITIAL_PAUSE;
 | 
					        mBalanceChangePause = sBalanceChangeInitialPause;
 | 
				
			||||||
        onIncreaseButtonTriggered();
 | 
					        onIncreaseButtonTriggered();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void TradeWindow::onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
 | 
					    void TradeWindow::onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mBalanceButtonsState = BBS_Decrease;
 | 
					        mBalanceButtonsState = BBS_Decrease;
 | 
				
			||||||
        mBalanceChangePause = BALANCE_CHANGE_INITIAL_PAUSE;
 | 
					        mBalanceChangePause = sBalanceChangeInitialPause;
 | 
				
			||||||
        onDecreaseButtonTriggered();
 | 
					        onDecreaseButtonTriggered();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,9 @@ namespace MWGui
 | 
				
			||||||
            void onFrame(float frameDuration);
 | 
					            void onFrame(float frameDuration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected:
 | 
					        protected:
 | 
				
			||||||
 | 
					            static const float sBalanceChangeInitialPause; // in seconds
 | 
				
			||||||
 | 
					            static const float sBalanceChangeInterval; // in seconds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            MyGUI::Button* mFilterAll;
 | 
					            MyGUI::Button* mFilterAll;
 | 
				
			||||||
            MyGUI::Button* mFilterWeapon;
 | 
					            MyGUI::Button* mFilterWeapon;
 | 
				
			||||||
            MyGUI::Button* mFilterApparel;
 | 
					            MyGUI::Button* mFilterApparel;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,31 +95,46 @@ namespace MWGui
 | 
				
			||||||
        // http://www.uesp.net/wiki/Lore:Calendar
 | 
					        // http://www.uesp.net/wiki/Lore:Calendar
 | 
				
			||||||
        std::string month;
 | 
					        std::string month;
 | 
				
			||||||
        int m = MWBase::Environment::get().getWorld ()->getMonth ();
 | 
					        int m = MWBase::Environment::get().getWorld ()->getMonth ();
 | 
				
			||||||
        if (m == 0)
 | 
					        switch (m) {
 | 
				
			||||||
            month = "#{sMonthMorningstar}";
 | 
					            case 0:
 | 
				
			||||||
        else if (m == 1)
 | 
					                month = "#{sMonthMorningstar}";
 | 
				
			||||||
            month = "#{sMonthSunsdawn}";
 | 
					                break;
 | 
				
			||||||
        else if (m == 2)
 | 
					            case 1:
 | 
				
			||||||
            month = "#{sMonthFirstseed}";
 | 
					                month = "#{sMonthSunsdawn}";
 | 
				
			||||||
        else if (m == 3)
 | 
					                break;
 | 
				
			||||||
            month = "#{sMonthRainshand}";
 | 
					            case 2:
 | 
				
			||||||
        else if (m == 4)
 | 
					                month = "#{sMonthFirstseed}";
 | 
				
			||||||
            month = "#{sMonthSecondseed}";
 | 
					                break;
 | 
				
			||||||
        else if (m == 5)
 | 
					            case 3:
 | 
				
			||||||
            month = "#{sMonthMidyear}";
 | 
					                month = "#{sMonthRainshand}";
 | 
				
			||||||
        else if (m == 6)
 | 
					                break;
 | 
				
			||||||
            month = "#{sMonthSunsheight}";
 | 
					            case 4:
 | 
				
			||||||
        else if (m == 7)
 | 
					                month = "#{sMonthSecondseed}";
 | 
				
			||||||
            month = "#{sMonthLastseed}";
 | 
					                break;
 | 
				
			||||||
        else if (m == 8)
 | 
					            case 5:
 | 
				
			||||||
            month = "#{sMonthHeartfire}";
 | 
					                month = "#{sMonthMidyear}";
 | 
				
			||||||
        else if (m == 9)
 | 
					                break;
 | 
				
			||||||
            month = "#{sMonthFrostfall}";
 | 
					            case 6:
 | 
				
			||||||
        else if (m == 10)
 | 
					                month = "#{sMonthSunsheight}";
 | 
				
			||||||
            month = "#{sMonthSunsdusk}";
 | 
					                break;
 | 
				
			||||||
        else if (m == 11)
 | 
					            case 7:
 | 
				
			||||||
            month = "#{sMonthEveningstar}";
 | 
					                month = "#{sMonthLastseed}";
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 8:
 | 
				
			||||||
 | 
					                month = "#{sMonthHeartfire}";
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 9:
 | 
				
			||||||
 | 
					                month = "#{sMonthFrostfall}";
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 10:
 | 
				
			||||||
 | 
					                month = "#{sMonthSunsdusk}";
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 11:
 | 
				
			||||||
 | 
					                month = "#{sMonthEveningstar}";
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:   
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        int hour = MWBase::Environment::get().getWorld ()->getTimeStamp ().getHour ();
 | 
					        int hour = MWBase::Environment::get().getWorld ()->getTimeStamp ().getHour ();
 | 
				
			||||||
        bool pm = hour >= 12;
 | 
					        bool pm = hour >= 12;
 | 
				
			||||||
        if (hour >= 13) hour -= 12;
 | 
					        if (hour >= 13) hour -= 12;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +53,7 @@
 | 
				
			||||||
#include "trainingwindow.hpp"
 | 
					#include "trainingwindow.hpp"
 | 
				
			||||||
#include "imagebutton.hpp"
 | 
					#include "imagebutton.hpp"
 | 
				
			||||||
#include "exposedwindow.hpp"
 | 
					#include "exposedwindow.hpp"
 | 
				
			||||||
 | 
					#include "cursor.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace MWGui;
 | 
					using namespace MWGui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -130,6 +131,9 @@ WindowManager::WindowManager(
 | 
				
			||||||
    MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ImageButton>("Widget");
 | 
					    MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ImageButton>("Widget");
 | 
				
			||||||
    MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget");
 | 
					    MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
 | 
				
			||||||
 | 
					    MyGUI::ResourceManager::getInstance().load("core.xml");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag);
 | 
					    MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Get size info from the Gui object
 | 
					    // Get size info from the Gui object
 | 
				
			||||||
| 
						 | 
					@ -178,6 +182,8 @@ WindowManager::WindowManager(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows","");
 | 
					    mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows","");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mCursor = new Cursor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The HUD is always on
 | 
					    // The HUD is always on
 | 
				
			||||||
    mHud->setVisible(true);
 | 
					    mHud->setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -236,6 +242,7 @@ WindowManager::~WindowManager()
 | 
				
			||||||
    delete mTrainingWindow;
 | 
					    delete mTrainingWindow;
 | 
				
			||||||
    delete mCountDialog;
 | 
					    delete mCountDialog;
 | 
				
			||||||
    delete mQuickKeysMenu;
 | 
					    delete mQuickKeysMenu;
 | 
				
			||||||
 | 
					    delete mCursor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cleanupGarbage();
 | 
					    cleanupGarbage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -262,6 +269,8 @@ void WindowManager::update()
 | 
				
			||||||
    mHud->setFPS(mFPS);
 | 
					    mHud->setFPS(mFPS);
 | 
				
			||||||
    mHud->setTriangleCount(mTriangleCount);
 | 
					    mHud->setTriangleCount(mTriangleCount);
 | 
				
			||||||
    mHud->setBatchCount(mBatchCount);
 | 
					    mHud->setBatchCount(mBatchCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mCursor->update();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WindowManager::updateVisible()
 | 
					void WindowManager::updateVisible()
 | 
				
			||||||
| 
						 | 
					@ -293,7 +302,7 @@ void WindowManager::updateVisible()
 | 
				
			||||||
    mHud->setVisible(true);
 | 
					    mHud->setVisible(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Mouse is visible whenever we're not in game mode
 | 
					    // Mouse is visible whenever we're not in game mode
 | 
				
			||||||
    MyGUI::PointerManager::getInstance().setVisible(isGuiMode());
 | 
					    mCursor->setVisible(isGuiMode());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool gameMode = !isGuiMode();
 | 
					    bool gameMode = !isGuiMode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -421,13 +430,19 @@ void WindowManager::updateVisible()
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case GM_LoadingWallpaper:
 | 
					        case GM_LoadingWallpaper:
 | 
				
			||||||
            mHud->setVisible(false);
 | 
					            mHud->setVisible(false);
 | 
				
			||||||
            MyGUI::PointerManager::getInstance().setVisible(false);
 | 
					            mCursor->setVisible(false);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case GM_Loading:
 | 
					        case GM_Loading:
 | 
				
			||||||
            MyGUI::PointerManager::getInstance().setVisible(false);
 | 
					            // Show the pinned windows
 | 
				
			||||||
 | 
					            mMap->setVisible(mMap->pinned());
 | 
				
			||||||
 | 
					            mStatsWindow->setVisible(mStatsWindow->pinned());
 | 
				
			||||||
 | 
					            mInventoryWindow->setVisible(mInventoryWindow->pinned());
 | 
				
			||||||
 | 
					            mSpellWindow->setVisible(mSpellWindow->pinned());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            mCursor->setVisible(false);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case GM_Video:
 | 
					        case GM_Video:
 | 
				
			||||||
            MyGUI::PointerManager::getInstance().setVisible(false);
 | 
					            mCursor->setVisible(false);
 | 
				
			||||||
            mHud->setVisible(false);
 | 
					            mHud->setVisible(false);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
| 
						 | 
					@ -749,7 +764,7 @@ void WindowManager::setSpellVisibility(bool visible)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WindowManager::setMouseVisible(bool visible)
 | 
					void WindowManager::setMouseVisible(bool visible)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MyGUI::PointerManager::getInstance().setVisible(visible);
 | 
					    mCursor->setVisible(visible);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WindowManager::setDragDrop(bool dragDrop)
 | 
					void WindowManager::setDragDrop(bool dragDrop)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,6 +72,7 @@ namespace MWGui
 | 
				
			||||||
  class SpellCreationDialog;
 | 
					  class SpellCreationDialog;
 | 
				
			||||||
  class EnchantingDialog;
 | 
					  class EnchantingDialog;
 | 
				
			||||||
  class TrainingWindow;
 | 
					  class TrainingWindow;
 | 
				
			||||||
 | 
					  class Cursor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  class WindowManager : public MWBase::WindowManager
 | 
					  class WindowManager : public MWBase::WindowManager
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
| 
						 | 
					@ -188,7 +189,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
 | 
					    virtual void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons);
 | 
					    virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>());
 | 
				
			||||||
    virtual void enterPressed ();
 | 
					    virtual void enterPressed ();
 | 
				
			||||||
    virtual int readPressedButton (); ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
 | 
					    virtual int readPressedButton (); ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -260,6 +261,7 @@ namespace MWGui
 | 
				
			||||||
    EnchantingDialog* mEnchantingDialog;
 | 
					    EnchantingDialog* mEnchantingDialog;
 | 
				
			||||||
    TrainingWindow* mTrainingWindow;
 | 
					    TrainingWindow* mTrainingWindow;
 | 
				
			||||||
    Translation::Storage& mTranslationDataStorage;
 | 
					    Translation::Storage& mTranslationDataStorage;
 | 
				
			||||||
 | 
					    Cursor* mCursor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CharacterCreation* mCharGen;
 | 
					    CharacterCreation* mCharGen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@
 | 
				
			||||||
#include "../engine.hpp"
 | 
					#include "../engine.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwworld/player.hpp"
 | 
					#include "../mwworld/player.hpp"
 | 
				
			||||||
 | 
					#include "../mwworld/class.hpp"
 | 
				
			||||||
#include "../mwbase/world.hpp"
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
#include "../mwbase/windowmanager.hpp"
 | 
					#include "../mwbase/windowmanager.hpp"
 | 
				
			||||||
#include "../mwbase/soundmanager.hpp"
 | 
					#include "../mwbase/soundmanager.hpp"
 | 
				
			||||||
| 
						 | 
					@ -51,6 +52,7 @@ namespace MWInput
 | 
				
			||||||
        , mUIYMultiplier (Settings::Manager::getFloat("ui y multiplier", "Input"))
 | 
					        , mUIYMultiplier (Settings::Manager::getFloat("ui y multiplier", "Input"))
 | 
				
			||||||
        , mPreviewPOVDelay(0.f)
 | 
					        , mPreviewPOVDelay(0.f)
 | 
				
			||||||
        , mTimeIdle(0.f)
 | 
					        , mTimeIdle(0.f)
 | 
				
			||||||
 | 
					        , mOverencumberedMessageDelay(0.f)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ogre::RenderWindow* window = ogre.getWindow ();
 | 
					        Ogre::RenderWindow* window = ogre.getWindow ();
 | 
				
			||||||
        size_t windowHnd;
 | 
					        size_t windowHnd;
 | 
				
			||||||
| 
						 | 
					@ -85,10 +87,12 @@ namespace MWInput
 | 
				
			||||||
                std::string("false")));
 | 
					                std::string("false")));
 | 
				
			||||||
            pl.insert(std::make_pair(std::string("x11_keyboard_grab"),
 | 
					            pl.insert(std::make_pair(std::string("x11_keyboard_grab"),
 | 
				
			||||||
                std::string("false")));
 | 
					                std::string("false")));
 | 
				
			||||||
            pl.insert(std::make_pair(std::string("XAutoRepeatOn"),
 | 
					 | 
				
			||||||
                std::string("true")));
 | 
					 | 
				
			||||||
            #endif
 | 
					            #endif
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					#if defined OIS_LINUX_PLATFORM
 | 
				
			||||||
 | 
					        pl.insert(std::make_pair(std::string("XAutoRepeatOn"),
 | 
				
			||||||
 | 
					            std::string("true")));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__APPLE__) && !defined(__LP64__)
 | 
					#if defined(__APPLE__) && !defined(__LP64__)
 | 
				
			||||||
        // Give the application window focus to receive input events
 | 
					        // Give the application window focus to receive input events
 | 
				
			||||||
| 
						 | 
					@ -175,6 +179,11 @@ namespace MWInput
 | 
				
			||||||
            case A_Activate:
 | 
					            case A_Activate:
 | 
				
			||||||
                resetIdleTime();
 | 
					                resetIdleTime();
 | 
				
			||||||
                activate();
 | 
					                activate();
 | 
				
			||||||
 | 
					                if( MWBase::Environment::get().getWindowManager()->isGuiMode()
 | 
				
			||||||
 | 
					                    && MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_InterMessageBox ) {
 | 
				
			||||||
 | 
					                        // Pressing the activation key when a messagebox is prompting for "ok" will activate the ok button
 | 
				
			||||||
 | 
					                        MWBase::Environment::get().getWindowManager()->enterPressed();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case A_Journal:
 | 
					            case A_Journal:
 | 
				
			||||||
                toggleJournal ();
 | 
					                toggleJournal ();
 | 
				
			||||||
| 
						 | 
					@ -268,26 +277,29 @@ namespace MWInput
 | 
				
			||||||
        // be done in the physics system.
 | 
					        // be done in the physics system.
 | 
				
			||||||
        if (mControlSwitch["playercontrols"])
 | 
					        if (mControlSwitch["playercontrols"])
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            bool triedToMove = false;
 | 
				
			||||||
            if (actionIsActive(A_MoveLeft))
 | 
					            if (actionIsActive(A_MoveLeft))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                mPlayer.setAutoMove (false);
 | 
					                triedToMove = true;
 | 
				
			||||||
                mPlayer.setLeftRight (1);
 | 
					                mPlayer.setLeftRight (-1);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (actionIsActive(A_MoveRight))
 | 
					            else if (actionIsActive(A_MoveRight))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                mPlayer.setAutoMove (false);
 | 
					                triedToMove = true;
 | 
				
			||||||
                mPlayer.setLeftRight (-1);
 | 
					                mPlayer.setLeftRight (1);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                mPlayer.setLeftRight (0);
 | 
					                mPlayer.setLeftRight (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (actionIsActive(A_MoveForward))
 | 
					            if (actionIsActive(A_MoveForward))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
					                triedToMove = true;
 | 
				
			||||||
                mPlayer.setAutoMove (false);
 | 
					                mPlayer.setAutoMove (false);
 | 
				
			||||||
                mPlayer.setForwardBackward (1);
 | 
					                mPlayer.setForwardBackward (1);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (actionIsActive(A_MoveBackward))
 | 
					            else if (actionIsActive(A_MoveBackward))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
					                triedToMove = true;
 | 
				
			||||||
                mPlayer.setAutoMove (false);
 | 
					                mPlayer.setAutoMove (false);
 | 
				
			||||||
                mPlayer.setForwardBackward (-1);
 | 
					                mPlayer.setForwardBackward (-1);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -295,12 +307,35 @@ namespace MWInput
 | 
				
			||||||
                mPlayer.setForwardBackward (0);
 | 
					                mPlayer.setForwardBackward (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (actionIsActive(A_Jump) && mControlSwitch["playerjumping"])
 | 
					            if (actionIsActive(A_Jump) && mControlSwitch["playerjumping"])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                mPlayer.setUpDown (1);
 | 
					                mPlayer.setUpDown (1);
 | 
				
			||||||
 | 
					                triedToMove = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            else if (actionIsActive(A_Crouch))
 | 
					            else if (actionIsActive(A_Crouch))
 | 
				
			||||||
                mPlayer.setUpDown (-1);
 | 
					                mPlayer.setUpDown (-1);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                mPlayer.setUpDown (0);
 | 
					                mPlayer.setUpDown (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(actionIsActive(A_Run))
 | 
				
			||||||
 | 
					                mPlayer.setRunState(true);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                mPlayer.setRunState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // if player tried to start moving, but can't (due to being overencumbered), display a notification.
 | 
				
			||||||
 | 
					            if (triedToMove)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
 | 
				
			||||||
 | 
					                mOverencumberedMessageDelay -= dt;
 | 
				
			||||||
 | 
					                if (MWWorld::Class::get(player).getEncumbrance(player) >= MWWorld::Class::get(player).getCapacity(player))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (mOverencumberedMessageDelay <= 0)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage59}");
 | 
				
			||||||
 | 
					                        mOverencumberedMessageDelay = 1.0;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (mControlSwitch["playerviewswitch"]) {
 | 
					            if (mControlSwitch["playerviewswitch"]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // work around preview mode toggle when pressing Alt+Tab
 | 
					                // work around preview mode toggle when pressing Alt+Tab
 | 
				
			||||||
| 
						 | 
					@ -521,6 +556,9 @@ namespace MWInput
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void InputManager::toggleMainMenu()
 | 
					    void InputManager::toggleMainMenu()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        if (MyGUI::InputManager::getInstance ().isModalAny())
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (mWindows.isGuiMode () && (mWindows.getMode () == MWGui::GM_MainMenu || mWindows.getMode () == MWGui::GM_Settings))
 | 
					        if (mWindows.isGuiMode () && (mWindows.getMode () == MWGui::GM_MainMenu || mWindows.getMode () == MWGui::GM_Settings))
 | 
				
			||||||
            mWindows.popGuiMode();
 | 
					            mWindows.popGuiMode();
 | 
				
			||||||
        else if (mWindows.isGuiMode () && mWindows.getMode () == MWGui::GM_Video)
 | 
					        else if (mWindows.isGuiMode () && mWindows.getMode () == MWGui::GM_Video)
 | 
				
			||||||
| 
						 | 
					@ -599,6 +637,9 @@ namespace MWInput
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void InputManager::toggleConsole()
 | 
					    void InputManager::toggleConsole()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        if (MyGUI::InputManager::getInstance ().isModalAny())
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool gameMode = !mWindows.isGuiMode();
 | 
					        bool gameMode = !mWindows.isGuiMode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Switch to console mode no matter what mode we are currently
 | 
					        // Switch to console mode no matter what mode we are currently
 | 
				
			||||||
| 
						 | 
					@ -705,6 +746,7 @@ namespace MWInput
 | 
				
			||||||
        defaultKeyBindings[A_ToggleSpell] = OIS::KC_R;
 | 
					        defaultKeyBindings[A_ToggleSpell] = OIS::KC_R;
 | 
				
			||||||
        defaultKeyBindings[A_QuickKeysMenu] = OIS::KC_F1;
 | 
					        defaultKeyBindings[A_QuickKeysMenu] = OIS::KC_F1;
 | 
				
			||||||
        defaultKeyBindings[A_Console] = OIS::KC_F2;
 | 
					        defaultKeyBindings[A_Console] = OIS::KC_F2;
 | 
				
			||||||
 | 
					        defaultKeyBindings[A_Run] = OIS::KC_LSHIFT;
 | 
				
			||||||
        defaultKeyBindings[A_Crouch] = OIS::KC_LCONTROL;
 | 
					        defaultKeyBindings[A_Crouch] = OIS::KC_LCONTROL;
 | 
				
			||||||
        defaultKeyBindings[A_AutoMove] = OIS::KC_Q;
 | 
					        defaultKeyBindings[A_AutoMove] = OIS::KC_Q;
 | 
				
			||||||
        defaultKeyBindings[A_Jump] = OIS::KC_E;
 | 
					        defaultKeyBindings[A_Jump] = OIS::KC_E;
 | 
				
			||||||
| 
						 | 
					@ -771,6 +813,7 @@ namespace MWInput
 | 
				
			||||||
        descriptions[A_ToggleWeapon] = "sReady_Weapon";
 | 
					        descriptions[A_ToggleWeapon] = "sReady_Weapon";
 | 
				
			||||||
        descriptions[A_ToggleSpell] = "sReady_Magic";
 | 
					        descriptions[A_ToggleSpell] = "sReady_Magic";
 | 
				
			||||||
        descriptions[A_Console] = "sConsoleTitle";
 | 
					        descriptions[A_Console] = "sConsoleTitle";
 | 
				
			||||||
 | 
					        descriptions[A_Run] = "sRun";
 | 
				
			||||||
        descriptions[A_Crouch] = "sCrouch_Sneak";
 | 
					        descriptions[A_Crouch] = "sCrouch_Sneak";
 | 
				
			||||||
        descriptions[A_AutoMove] = "sAuto_Run";
 | 
					        descriptions[A_AutoMove] = "sAuto_Run";
 | 
				
			||||||
        descriptions[A_Jump] = "sJump";
 | 
					        descriptions[A_Jump] = "sJump";
 | 
				
			||||||
| 
						 | 
					@ -819,6 +862,7 @@ namespace MWInput
 | 
				
			||||||
        ret.push_back(A_MoveLeft);
 | 
					        ret.push_back(A_MoveLeft);
 | 
				
			||||||
        ret.push_back(A_MoveRight);
 | 
					        ret.push_back(A_MoveRight);
 | 
				
			||||||
        ret.push_back(A_TogglePOV);
 | 
					        ret.push_back(A_TogglePOV);
 | 
				
			||||||
 | 
					        ret.push_back(A_Run);
 | 
				
			||||||
        ret.push_back(A_Crouch);
 | 
					        ret.push_back(A_Crouch);
 | 
				
			||||||
        ret.push_back(A_Activate);
 | 
					        ret.push_back(A_Activate);
 | 
				
			||||||
        ret.push_back(A_ToggleWeapon);
 | 
					        ret.push_back(A_ToggleWeapon);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,6 +145,8 @@ namespace MWInput
 | 
				
			||||||
        bool mMouseLookEnabled;
 | 
					        bool mMouseLookEnabled;
 | 
				
			||||||
        bool mGuiCursorEnabled;
 | 
					        bool mGuiCursorEnabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float mOverencumberedMessageDelay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        float mMouseX;
 | 
					        float mMouseX;
 | 
				
			||||||
        float mMouseY;
 | 
					        float mMouseY;
 | 
				
			||||||
        int mMouseWheel;
 | 
					        int mMouseWheel;
 | 
				
			||||||
| 
						 | 
					@ -207,7 +209,7 @@ namespace MWInput
 | 
				
			||||||
            A_Journal,    //Journal
 | 
					            A_Journal,    //Journal
 | 
				
			||||||
            A_Weapon,     //Draw/Sheath weapon
 | 
					            A_Weapon,     //Draw/Sheath weapon
 | 
				
			||||||
            A_Spell,      //Ready/Unready Casting
 | 
					            A_Spell,      //Ready/Unready Casting
 | 
				
			||||||
            A_AlwaysRun,  //Toggle Always Run
 | 
					            A_Run,        //Run when held
 | 
				
			||||||
            A_CycleSpellLeft, //cycling through spells
 | 
					            A_CycleSpellLeft, //cycling through spells
 | 
				
			||||||
            A_CycleSpellRight,
 | 
					            A_CycleSpellRight,
 | 
				
			||||||
            A_CycleWeaponLeft,//Cycling through weapons
 | 
					            A_CycleWeaponLeft,//Cycling through weapons
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										76
									
								
								apps/openmw/mwmechanics/activators.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								apps/openmw/mwmechanics/activators.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,76 @@
 | 
				
			||||||
 | 
					#include "activators.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <OgreVector3.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWMechanics
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Activators::Activators()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Activators::addActivator(const MWWorld::Ptr& ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
 | 
				
			||||||
 | 
					    if(anim != NULL)
 | 
				
			||||||
 | 
					        mActivators.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle, true)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Activators::removeActivator (const MWWorld::Ptr& ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PtrControllerMap::iterator iter = mActivators.find(ptr);
 | 
				
			||||||
 | 
					    if(iter != mActivators.end())
 | 
				
			||||||
 | 
					        mActivators.erase(iter);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Activators::updateActivator(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PtrControllerMap::iterator iter = mActivators.find(old);
 | 
				
			||||||
 | 
					    if(iter != mActivators.end())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        CharacterController ctrl = iter->second;
 | 
				
			||||||
 | 
					        mActivators.erase(iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ctrl.updatePtr(ptr);
 | 
				
			||||||
 | 
					        mActivators.insert(std::make_pair(ptr, ctrl));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Activators::dropActivators (const MWWorld::Ptr::CellStore *cellStore)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PtrControllerMap::iterator iter = mActivators.begin();
 | 
				
			||||||
 | 
					    while(iter != mActivators.end())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(iter->first.getCell()==cellStore)
 | 
				
			||||||
 | 
					            mActivators.erase(iter++);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            ++iter;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Activators::update(float duration, bool paused)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(!paused)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for(PtrControllerMap::iterator iter(mActivators.begin());iter != mActivators.end();++iter)
 | 
				
			||||||
 | 
					            iter->second.update(duration);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Activators::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PtrControllerMap::iterator iter = mActivators.find(ptr);
 | 
				
			||||||
 | 
					    if(iter != mActivators.end())
 | 
				
			||||||
 | 
					        iter->second.playGroup(groupName, mode, number);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void Activators::skipAnimation(const MWWorld::Ptr& ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PtrControllerMap::iterator iter = mActivators.find(ptr);
 | 
				
			||||||
 | 
					    if(iter != mActivators.end())
 | 
				
			||||||
 | 
					        iter->second.skipAnim();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										45
									
								
								apps/openmw/mwmechanics/activators.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								apps/openmw/mwmechanics/activators.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,45 @@
 | 
				
			||||||
 | 
					#ifndef GAME_MWMECHANICS_ACTIVATORS_H
 | 
				
			||||||
 | 
					#define GAME_MWMECHANICS_ACTOVATRS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "character.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWWorld
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class Ptr;
 | 
				
			||||||
 | 
					    class CellStore;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWMechanics
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class Activators
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        typedef std::map<MWWorld::Ptr,CharacterController> PtrControllerMap;
 | 
				
			||||||
 | 
					        PtrControllerMap mActivators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        Activators();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void addActivator (const MWWorld::Ptr& ptr);
 | 
				
			||||||
 | 
					        ///< Register an animated activator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void removeActivator (const MWWorld::Ptr& ptr);
 | 
				
			||||||
 | 
					        ///< Deregister an activator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void updateActivator(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr);
 | 
				
			||||||
 | 
					        ///< Updates an activator with a new Ptr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void dropActivators (const MWWorld::CellStore *cellStore);
 | 
				
			||||||
 | 
					        ///< Deregister all activators in the given cell.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void update (float duration, bool paused);
 | 
				
			||||||
 | 
					        ///< Update activator animations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
 | 
				
			||||||
 | 
					        void skipAnimation(const MWWorld::Ptr& ptr);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -165,35 +165,46 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Actors::addActor (const MWWorld::Ptr& ptr)
 | 
					    void Actors::addActor (const MWWorld::Ptr& ptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (!MWWorld::Class::get (ptr).getCreatureStats (ptr).isDead())
 | 
					        MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
 | 
				
			||||||
            mActors.insert (ptr);
 | 
					        if(!MWWorld::Class::get(ptr).getCreatureStats(ptr).isDead())
 | 
				
			||||||
 | 
					            mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle, true)));
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            MWBase::Environment::get().getWorld()->playAnimationGroup (ptr, "death1", 2);
 | 
					            mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Death1, false)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Actors::removeActor (const MWWorld::Ptr& ptr)
 | 
					    void Actors::removeActor (const MWWorld::Ptr& ptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::set<MWWorld::Ptr>::iterator iter = mActors.find (ptr);
 | 
					        PtrControllerMap::iterator iter = mActors.find(ptr);
 | 
				
			||||||
 | 
					        if(iter != mActors.end())
 | 
				
			||||||
 | 
					            mActors.erase(iter);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (iter!=mActors.end())
 | 
					    void Actors::updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
 | 
				
			||||||
            mActors.erase (iter);
 | 
					    {
 | 
				
			||||||
 | 
					        PtrControllerMap::iterator iter = mActors.find(old);
 | 
				
			||||||
 | 
					        if(iter != mActors.end())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            CharacterController ctrl = iter->second;
 | 
				
			||||||
 | 
					            mActors.erase(iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ctrl.updatePtr(ptr);
 | 
				
			||||||
 | 
					            mActors.insert(std::make_pair(ptr, ctrl));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore)
 | 
					    void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
 | 
					        PtrControllerMap::iterator iter = mActors.begin();
 | 
				
			||||||
 | 
					        while(iter != mActors.end())
 | 
				
			||||||
        while (iter!=mActors.end())
 | 
					        {
 | 
				
			||||||
            if (iter->getCell()==cellStore)
 | 
					            if(iter->first.getCell()==cellStore)
 | 
				
			||||||
            {
 | 
					                mActors.erase(iter++);
 | 
				
			||||||
                mActors.erase (iter++);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                ++iter;
 | 
					                ++iter;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Actors::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement, float duration,
 | 
					    void Actors::update (float duration, bool paused)
 | 
				
			||||||
        bool paused)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mDuration += duration;
 | 
					        mDuration += duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,78 +213,90 @@ namespace MWMechanics
 | 
				
			||||||
            float totalDuration = mDuration;
 | 
					            float totalDuration = mDuration;
 | 
				
			||||||
            mDuration = 0;
 | 
					            mDuration = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::set<MWWorld::Ptr>::iterator iter (mActors.begin());
 | 
					            for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();iter++)
 | 
				
			||||||
 | 
					 | 
				
			||||||
            while (iter!=mActors.end())
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (!MWWorld::Class::get (*iter).getCreatureStats (*iter).isDead())
 | 
					                if(!MWWorld::Class::get(iter->first).getCreatureStats(iter->first).isDead())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    updateActor (*iter, totalDuration);
 | 
					                    if(iter->second.getState() >= CharState_Death1)
 | 
				
			||||||
 | 
					                        iter->second.setState(CharState_Idle, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (iter->getTypeName()==typeid (ESM::NPC).name())
 | 
					                    updateActor(iter->first, totalDuration);
 | 
				
			||||||
                        updateNpc (*iter, totalDuration, paused);
 | 
					                    if(iter->first.getTypeName() == typeid(ESM::NPC).name())
 | 
				
			||||||
 | 
					                        updateNpc(iter->first, totalDuration, paused);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if(!MWWorld::Class::get(iter->first).getCreatureStats(iter->first).isDead())
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (MWWorld::Class::get (*iter).getCreatureStats (*iter).isDead())
 | 
					                // workaround: always keep player alive for now
 | 
				
			||||||
 | 
					                // \todo remove workaround, once player death can be handled
 | 
				
			||||||
 | 
					                if(iter->first.getRefData().getHandle()=="player")
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    // workaround: always keep player alive for now
 | 
					                    MWMechanics::DynamicStat<float> stat (
 | 
				
			||||||
                    // \todo remove workaround, once player death can be handled
 | 
					                        MWWorld::Class::get(iter->first).getCreatureStats(iter->first).getHealth());
 | 
				
			||||||
                    if (iter->getRefData().getHandle()=="player")
 | 
					
 | 
				
			||||||
 | 
					                    if (stat.getModified()<1)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        MWMechanics::DynamicStat<float> stat (
 | 
					                        stat.setModified (1, 0);
 | 
				
			||||||
                            MWWorld::Class::get (*iter).getCreatureStats (*iter).getHealth());
 | 
					                        MWWorld::Class::get(iter->first).getCreatureStats(iter->first).setHealth(stat);
 | 
				
			||||||
                            
 | 
					 | 
				
			||||||
                        if (stat.getModified()<1)
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            stat.setModified (1, 0);
 | 
					 | 
				
			||||||
                            MWWorld::Class::get (*iter).getCreatureStats (*iter).setHealth (stat);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        MWWorld::Class::get (*iter).getCreatureStats (*iter).resurrect();
 | 
					 | 
				
			||||||
                        ++iter;
 | 
					 | 
				
			||||||
                        continue;
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    ++mDeathCount[MWWorld::Class::get (*iter).getId (*iter)];
 | 
					                    MWWorld::Class::get(iter->first).getCreatureStats(iter->first).resurrect();
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
                    MWBase::Environment::get().getWorld()->playAnimationGroup (*iter, "death1", 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (MWWorld::Class::get (*iter).isEssential (*iter))
 | 
					 | 
				
			||||||
                        MWBase::Environment::get().getWindowManager()->messageBox (
 | 
					 | 
				
			||||||
                            "#{sKilledEssential}", std::vector<std::string>());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    mActors.erase (iter++);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					
 | 
				
			||||||
                    ++iter;
 | 
					                if(iter->second.getState() >= CharState_Death1)
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                iter->second.setState(CharState_Death1, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ++mDeathCount[MWWorld::Class::get(iter->first).getId(iter->first)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(MWWorld::Class::get(iter->first).isEssential(iter->first))
 | 
				
			||||||
 | 
					                    MWBase::Environment::get().getWindowManager()->messageBox(
 | 
				
			||||||
 | 
					                        "#{sKilledEssential}", std::vector<std::string>());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
 | 
					        if(!paused)
 | 
				
			||||||
            ++iter)
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
 | 
					            mMovement.reserve(mActors.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (vector!=Ogre::Vector3::ZERO)
 | 
					            for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
 | 
				
			||||||
                movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
 | 
					            {
 | 
				
			||||||
 | 
					                Ogre::Vector3 movement = iter->second.update(duration);
 | 
				
			||||||
 | 
					                mMovement.push_back(std::make_pair(iter->first, movement));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            MWBase::Environment::get().getWorld()->doPhysics(mMovement, duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            mMovement.clear();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Actors::restoreDynamicStats()
 | 
					    void Actors::restoreDynamicStats()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter)
 | 
					        for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
 | 
				
			||||||
        {
 | 
					            calculateRestoration(iter->first, 3600);
 | 
				
			||||||
            calculateRestoration (*iter, 3600);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    int Actors::countDeaths (const std::string& id) const
 | 
					    int Actors::countDeaths (const std::string& id) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::map<std::string, int>::const_iterator iter = mDeathCount.find (id);
 | 
					        std::map<std::string, int>::const_iterator iter = mDeathCount.find(id);
 | 
				
			||||||
 | 
					        if(iter != mDeathCount.end())
 | 
				
			||||||
        if (iter!=mDeathCount.end())
 | 
					 | 
				
			||||||
            return iter->second;
 | 
					            return iter->second;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void Actors::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        PtrControllerMap::iterator iter = mActors.find(ptr);
 | 
				
			||||||
 | 
					        if(iter != mActors.end())
 | 
				
			||||||
 | 
					            iter->second.playGroup(groupName, mode, number);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    void Actors::skipAnimation(const MWWorld::Ptr& ptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        PtrControllerMap::iterator iter = mActors.find(ptr);
 | 
				
			||||||
 | 
					        if(iter != mActors.end())
 | 
				
			||||||
 | 
					            iter->second.skipAnim();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,9 @@
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <map>
 | 
					#include <map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "character.hpp"
 | 
				
			||||||
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ogre
 | 
					namespace Ogre
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class Vector3;
 | 
					    class Vector3;
 | 
				
			||||||
| 
						 | 
					@ -21,9 +24,14 @@ namespace MWMechanics
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class Actors
 | 
					    class Actors
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
            std::set<MWWorld::Ptr> mActors;
 | 
					        typedef std::map<MWWorld::Ptr,CharacterController> PtrControllerMap;
 | 
				
			||||||
            float mDuration;
 | 
					        PtrControllerMap mActors;
 | 
				
			||||||
            std::map<std::string, int> mDeathCount;
 | 
					
 | 
				
			||||||
 | 
					        MWWorld::PtrMovementList mMovement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::map<std::string, int> mDeathCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float mDuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused);
 | 
					            void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,11 +58,13 @@ namespace MWMechanics
 | 
				
			||||||
            ///
 | 
					            ///
 | 
				
			||||||
            /// \note Ignored, if \a ptr is not a registered actor.
 | 
					            /// \note Ignored, if \a ptr is not a registered actor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr);
 | 
				
			||||||
 | 
					            ///< Updates an actor with a new Ptr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void dropActors (const MWWorld::CellStore *cellStore);
 | 
					            void dropActors (const MWWorld::CellStore *cellStore);
 | 
				
			||||||
            ///< Deregister all actors in the given cell.
 | 
					            ///< Deregister all actors in the given cell.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
 | 
					            void update (float duration, bool paused);
 | 
				
			||||||
                float duration, bool paused);
 | 
					 | 
				
			||||||
            ///< Update actor stats and store desired velocity vectors in \a movement
 | 
					            ///< Update actor stats and store desired velocity vectors in \a movement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void updateActor (const MWWorld::Ptr& ptr, float duration);
 | 
					            void updateActor (const MWWorld::Ptr& ptr, float duration);
 | 
				
			||||||
| 
						 | 
					@ -66,6 +76,9 @@ namespace MWMechanics
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            int countDeaths (const std::string& id) const;
 | 
					            int countDeaths (const std::string& id) const;
 | 
				
			||||||
            ///< Return the number of deaths for actors with the given ID.
 | 
					            ///< Return the number of deaths for actors with the given ID.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
 | 
				
			||||||
 | 
					        void skipAnimation(const MWWorld::Ptr& ptr);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										296
									
								
								apps/openmw/mwmechanics/character.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								apps/openmw/mwmechanics/character.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,296 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * OpenMW - The completely unofficial reimplementation of Morrowind
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file (character.cpp) is part of the OpenMW package.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * OpenMW is distributed as free software: you can redistribute it
 | 
				
			||||||
 | 
					 * and/or modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 * version 3, as published by the Free Software Foundation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * version 3 along with this program. If not, see
 | 
				
			||||||
 | 
					 * http://www.gnu.org/licenses/ .
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "character.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <OgreStringConverter.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwrender/animation.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwworld/class.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWMechanics
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct {
 | 
				
			||||||
 | 
					    CharacterState state;
 | 
				
			||||||
 | 
					    const char groupname[32];
 | 
				
			||||||
 | 
					} sStateList[] = {
 | 
				
			||||||
 | 
					    { CharState_Idle, "idle" },
 | 
				
			||||||
 | 
					    { CharState_Idle2, "idle2" },
 | 
				
			||||||
 | 
					    { CharState_Idle3, "idle3" },
 | 
				
			||||||
 | 
					    { CharState_Idle4, "idle4" },
 | 
				
			||||||
 | 
					    { CharState_Idle5, "idle5" },
 | 
				
			||||||
 | 
					    { CharState_Idle6, "idle6" },
 | 
				
			||||||
 | 
					    { CharState_Idle7, "idle7" },
 | 
				
			||||||
 | 
					    { CharState_Idle8, "idle8" },
 | 
				
			||||||
 | 
					    { CharState_Idle9, "idle9" },
 | 
				
			||||||
 | 
					    { CharState_IdleSwim, "idleswim" },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    { CharState_WalkForward, "walkforward" },
 | 
				
			||||||
 | 
					    { CharState_WalkBack, "walkback" },
 | 
				
			||||||
 | 
					    { CharState_WalkLeft, "walkleft" },
 | 
				
			||||||
 | 
					    { CharState_WalkRight, "walkright" },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    { CharState_SwimWalkForward, "swimwalkforward" },
 | 
				
			||||||
 | 
					    { CharState_SwimWalkBack, "swimwalkback" },
 | 
				
			||||||
 | 
					    { CharState_SwimWalkLeft, "swimwalkleft" },
 | 
				
			||||||
 | 
					    { CharState_SwimWalkRight, "swimwalkright" },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    { CharState_RunForward, "runforward" },
 | 
				
			||||||
 | 
					    { CharState_RunBack, "runback" },
 | 
				
			||||||
 | 
					    { CharState_RunLeft, "runleft" },
 | 
				
			||||||
 | 
					    { CharState_RunRight, "runright" },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    { CharState_SwimRunForward, "swimrunforward" },
 | 
				
			||||||
 | 
					    { CharState_SwimRunBack, "swimrunback" },
 | 
				
			||||||
 | 
					    { CharState_SwimRunLeft, "swimrunleft" },
 | 
				
			||||||
 | 
					    { CharState_SwimRunRight, "swimrunright" },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    { CharState_Jump, "jump" },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    { CharState_Death1, "death1" },
 | 
				
			||||||
 | 
					    { CharState_Death2, "death2" },
 | 
				
			||||||
 | 
					    { CharState_Death3, "death3" },
 | 
				
			||||||
 | 
					    { CharState_Death4, "death4" },
 | 
				
			||||||
 | 
					    { CharState_Death5, "death5" },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static const size_t sStateListSize = sizeof(sStateList)/sizeof(sStateList[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void getStateInfo(CharacterState state, std::string *group)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for(size_t i = 0;i < sStateListSize;i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(sStateList[i].state == state)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            *group = sStateList[i].groupname;
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(state));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop)
 | 
				
			||||||
 | 
					  : mPtr(ptr), mAnimation(anim), mState(state), mSkipAnim(false)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(!mAnimation)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mAnimation->setController(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getStateInfo(mState, &mCurrentGroup);
 | 
				
			||||||
 | 
					    if(ptr.getTypeName() == typeid(ESM::Activator).name())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Don't accumulate with activators (they don't get moved). */
 | 
				
			||||||
 | 
					        mAnimation->setAccumulation(Ogre::Vector3::ZERO);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Accumulate along X/Y only for now, until we can figure out how we should
 | 
				
			||||||
 | 
					         * handle knockout and death which moves the character down. */
 | 
				
			||||||
 | 
					        mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(mAnimation->hasAnimation(mCurrentGroup))
 | 
				
			||||||
 | 
					        mAnimation->play(mCurrentGroup, "stop", "stop", loop);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CharacterController::CharacterController(const CharacterController &rhs)
 | 
				
			||||||
 | 
					  : mPtr(rhs.mPtr), mAnimation(rhs.mAnimation), mAnimQueue(rhs.mAnimQueue)
 | 
				
			||||||
 | 
					  , mCurrentGroup(rhs.mCurrentGroup), mState(rhs.mState)
 | 
				
			||||||
 | 
					  , mSkipAnim(rhs.mSkipAnim)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(!mAnimation)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    /* We've been copied. Update the animation with the new controller. */
 | 
				
			||||||
 | 
					    mAnimation->setController(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CharacterController::~CharacterController()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CharacterController::updatePtr(const MWWorld::Ptr &ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mPtr = ptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CharacterController::markerEvent(float time, const std::string &evt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(evt == "stop")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1])
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            mAnimQueue.pop_front();
 | 
				
			||||||
 | 
					            mAnimation->play(mCurrentGroup, "loop start", "stop", false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(mAnimQueue.size() > 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            mAnimQueue.pop_front();
 | 
				
			||||||
 | 
					            if(mAnimQueue.size() > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                mCurrentGroup = mAnimQueue.front();
 | 
				
			||||||
 | 
					                mAnimation->play(mCurrentGroup, "start", "stop", false);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cerr<< "Unhandled animation event: "<<evt <<std::endl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ogre::Vector3 CharacterController::update(float duration)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Ogre::Vector3 movement(0.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    float speed = 0.0f;
 | 
				
			||||||
 | 
					    if(!(getState() >= CharState_Death1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const MWBase::World *world = MWBase::Environment::get().getWorld();
 | 
				
			||||||
 | 
					        const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
 | 
				
			||||||
 | 
					        const Ogre::Vector3 &vec = cls.getMovementVector(mPtr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bool onground = world->isOnGround(mPtr);
 | 
				
			||||||
 | 
					        bool inwater = world->isSwimming(mPtr);
 | 
				
			||||||
 | 
					        bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
 | 
				
			||||||
 | 
					        speed = cls.getSpeed(mPtr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except
 | 
				
			||||||
 | 
					         * for the initial thrust (which would be carried by "physics" until landing). */
 | 
				
			||||||
 | 
					        if(onground && vec.z > 0.0f)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            float x = cls.getJump(mPtr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(vec.x == 0 && vec.y == 0)
 | 
				
			||||||
 | 
					                movement.z += x*duration;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                /* FIXME: this would be more correct if we were going into a jumping state,
 | 
				
			||||||
 | 
					                 * rather than normal walking/idle states. */
 | 
				
			||||||
 | 
					                //Ogre::Vector3 lat = Ogre::Vector3(vec.x, vec.y, 0.0f).normalisedCopy();
 | 
				
			||||||
 | 
					                //movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration;
 | 
				
			||||||
 | 
					                movement.z += x * 0.707f * duration;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(std::abs(vec.x/2.0f) > std::abs(vec.y) && speed > 0.0f)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if(vec.x > 0.0f)
 | 
				
			||||||
 | 
					                setState(isrunning ?
 | 
				
			||||||
 | 
					                         (inwater ? CharState_SwimRunRight : CharState_RunRight) :
 | 
				
			||||||
 | 
					                         (inwater ? CharState_SwimWalkRight : CharState_WalkRight), true);
 | 
				
			||||||
 | 
					            else if(vec.x < 0.0f)
 | 
				
			||||||
 | 
					                setState(isrunning ?
 | 
				
			||||||
 | 
					                         (inwater ? CharState_SwimRunLeft: CharState_RunLeft) :
 | 
				
			||||||
 | 
					                         (inwater ? CharState_SwimWalkLeft : CharState_WalkLeft), true);
 | 
				
			||||||
 | 
					            // Apply any forward/backward movement manually
 | 
				
			||||||
 | 
					            movement.y += vec.y * (speed*duration);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(vec.y != 0.0f && speed > 0.0f)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if(vec.y > 0.0f)
 | 
				
			||||||
 | 
					                setState(isrunning ?
 | 
				
			||||||
 | 
					                         (inwater ? CharState_SwimRunForward : CharState_RunForward) :
 | 
				
			||||||
 | 
					                         (inwater ? CharState_SwimWalkForward : CharState_WalkForward), true);
 | 
				
			||||||
 | 
					            else if(vec.y < 0.0f)
 | 
				
			||||||
 | 
					                setState(isrunning ?
 | 
				
			||||||
 | 
					                         (inwater ? CharState_SwimRunBack : CharState_RunBack) :
 | 
				
			||||||
 | 
					                         (inwater ? CharState_SwimWalkBack : CharState_WalkBack), true);
 | 
				
			||||||
 | 
					            // Apply any sideways movement manually
 | 
				
			||||||
 | 
					            movement.x += vec.x * (speed*duration);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(mAnimQueue.size() == 0)
 | 
				
			||||||
 | 
					            setState((inwater ? CharState_IdleSwim : CharState_Idle), true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(mAnimation && !mSkipAnim)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        mAnimation->setSpeed(speed);
 | 
				
			||||||
 | 
					        movement += mAnimation->runAnimation(duration);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    mSkipAnim = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return movement;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CharacterController::playGroup(const std::string &groupname, int mode, int count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(!mAnimation || !mAnimation->hasAnimation(groupname))
 | 
				
			||||||
 | 
					        std::cerr<< "Animation "<<groupname<<" not found" <<std::endl;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        count = std::max(count, 1);
 | 
				
			||||||
 | 
					        if(mode != 0 || mAnimQueue.size() == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            mAnimQueue.clear();
 | 
				
			||||||
 | 
					            while(count-- > 0)
 | 
				
			||||||
 | 
					                mAnimQueue.push_back(groupname);
 | 
				
			||||||
 | 
					            mCurrentGroup = groupname;
 | 
				
			||||||
 | 
					            mState = CharState_SpecialIdle;
 | 
				
			||||||
 | 
					            mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start"), "stop", false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(mode == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            mAnimQueue.resize(1);
 | 
				
			||||||
 | 
					            while(count-- > 0)
 | 
				
			||||||
 | 
					                mAnimQueue.push_back(groupname);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CharacterController::skipAnim()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mSkipAnim = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CharacterController::setState(CharacterState state, bool loop)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(mState == state)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(mAnimation)
 | 
				
			||||||
 | 
					            mAnimation->setLooping(loop);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    mState = state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!mAnimation)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    mAnimQueue.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string anim;
 | 
				
			||||||
 | 
					    getStateInfo(mState, &anim);
 | 
				
			||||||
 | 
					    if(mAnimation->hasAnimation(anim))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        mCurrentGroup = anim;
 | 
				
			||||||
 | 
					        mAnimation->play(mCurrentGroup, "start", "stop", loop);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										96
									
								
								apps/openmw/mwmechanics/character.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								apps/openmw/mwmechanics/character.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,96 @@
 | 
				
			||||||
 | 
					#ifndef GAME_MWMECHANICS_CHARACTER_HPP
 | 
				
			||||||
 | 
					#define GAME_MWMECHANICS_CHARACTER_HPP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <OgreVector3.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwworld/ptr.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWRender
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class Animation;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWMechanics
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum CharacterState {
 | 
				
			||||||
 | 
					    CharState_SpecialIdle,
 | 
				
			||||||
 | 
					    CharState_Idle,
 | 
				
			||||||
 | 
					    CharState_Idle2,
 | 
				
			||||||
 | 
					    CharState_Idle3,
 | 
				
			||||||
 | 
					    CharState_Idle4,
 | 
				
			||||||
 | 
					    CharState_Idle5,
 | 
				
			||||||
 | 
					    CharState_Idle6,
 | 
				
			||||||
 | 
					    CharState_Idle7,
 | 
				
			||||||
 | 
					    CharState_Idle8,
 | 
				
			||||||
 | 
					    CharState_Idle9,
 | 
				
			||||||
 | 
					    CharState_IdleSwim,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CharState_WalkForward,
 | 
				
			||||||
 | 
					    CharState_WalkBack,
 | 
				
			||||||
 | 
					    CharState_WalkLeft,
 | 
				
			||||||
 | 
					    CharState_WalkRight,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CharState_SwimWalkForward,
 | 
				
			||||||
 | 
					    CharState_SwimWalkBack,
 | 
				
			||||||
 | 
					    CharState_SwimWalkLeft,
 | 
				
			||||||
 | 
					    CharState_SwimWalkRight,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CharState_RunForward,
 | 
				
			||||||
 | 
					    CharState_RunBack,
 | 
				
			||||||
 | 
					    CharState_RunLeft,
 | 
				
			||||||
 | 
					    CharState_RunRight,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CharState_SwimRunForward,
 | 
				
			||||||
 | 
					    CharState_SwimRunBack,
 | 
				
			||||||
 | 
					    CharState_SwimRunLeft,
 | 
				
			||||||
 | 
					    CharState_SwimRunRight,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CharState_Jump,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Death states must be last! */
 | 
				
			||||||
 | 
					    CharState_Death1,
 | 
				
			||||||
 | 
					    CharState_Death2,
 | 
				
			||||||
 | 
					    CharState_Death3,
 | 
				
			||||||
 | 
					    CharState_Death4,
 | 
				
			||||||
 | 
					    CharState_Death5
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CharacterController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MWWorld::Ptr mPtr;
 | 
				
			||||||
 | 
					    MWRender::Animation *mAnimation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typedef std::deque<std::string> AnimationQueue;
 | 
				
			||||||
 | 
					    AnimationQueue mAnimQueue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string mCurrentGroup;
 | 
				
			||||||
 | 
					    CharacterState mState;
 | 
				
			||||||
 | 
					    bool mSkipAnim;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					    /* Called by the animation whenever a new text key is reached. */
 | 
				
			||||||
 | 
					    void markerEvent(float time, const std::string &evt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    friend class MWRender::Animation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop);
 | 
				
			||||||
 | 
					    CharacterController(const CharacterController &rhs);
 | 
				
			||||||
 | 
					    virtual ~CharacterController();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void updatePtr(const MWWorld::Ptr &ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ogre::Vector3 update(float duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void playGroup(const std::string &groupname, int mode, int count);
 | 
				
			||||||
 | 
					    void skipAnim();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setState(CharacterState state, bool loop);
 | 
				
			||||||
 | 
					    CharacterState getState() const
 | 
				
			||||||
 | 
					    { return mState; }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* GAME_MWMECHANICS_CHARACTER_HPP */
 | 
				
			||||||
| 
						 | 
					@ -175,34 +175,47 @@ namespace MWMechanics
 | 
				
			||||||
        buildPlayer();
 | 
					        buildPlayer();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void MechanicsManager::addActor (const MWWorld::Ptr& ptr)
 | 
					    void MechanicsManager::add(const MWWorld::Ptr& ptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mActors.addActor (ptr);
 | 
					        if(ptr.getTypeName() == typeid(ESM::Activator).name())
 | 
				
			||||||
 | 
					            mActivators.addActivator(ptr);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            mActors.addActor(ptr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
 | 
					    void MechanicsManager::remove(const MWWorld::Ptr& ptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (ptr==mWatched)
 | 
					        if(ptr == mWatched)
 | 
				
			||||||
 | 
					            mWatched = MWWorld::Ptr();
 | 
				
			||||||
 | 
					        mActors.removeActor(ptr);
 | 
				
			||||||
 | 
					        mActivators.removeActivator(ptr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void MechanicsManager::updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(ptr.getTypeName() == typeid(ESM::Activator).name())
 | 
				
			||||||
 | 
					            mActivators.updateActivator(old, ptr);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            mActors.updateActor(old, ptr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void MechanicsManager::drop(const MWWorld::CellStore *cellStore)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(!mWatched.isEmpty() && mWatched.getCell() == cellStore)
 | 
				
			||||||
            mWatched = MWWorld::Ptr();
 | 
					            mWatched = MWWorld::Ptr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mActors.removeActor (ptr);
 | 
					        mActors.dropActors(cellStore);
 | 
				
			||||||
 | 
					        mActivators.dropActivators(cellStore);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
 | 
					 | 
				
			||||||
            mWatched = MWWorld::Ptr();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mActors.dropActors (cellStore);
 | 
					    void MechanicsManager::watchActor(const MWWorld::Ptr& ptr)
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void MechanicsManager::watchActor (const MWWorld::Ptr& ptr)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mWatched = ptr;
 | 
					        mWatched = ptr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
 | 
					    void MechanicsManager::update(float duration, bool paused)
 | 
				
			||||||
        float duration, bool paused)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (!mWatched.isEmpty())
 | 
					        if (!mWatched.isEmpty())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -296,9 +309,16 @@ namespace MWMechanics
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            winMgr->configureSkills (majorSkills, minorSkills);
 | 
					            winMgr->configureSkills (majorSkills, minorSkills);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // HACK? The player has been changed, so a new Animation object may
 | 
				
			||||||
 | 
					            // have been made for them. Make sure they're properly updated.
 | 
				
			||||||
 | 
					            MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
 | 
				
			||||||
 | 
					            mActors.removeActor(ptr);
 | 
				
			||||||
 | 
					            mActors.addActor(ptr);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mActors.update (movement, duration, paused);
 | 
					        mActors.update(duration, paused);
 | 
				
			||||||
 | 
					        mActivators.update(duration, paused);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void MechanicsManager::restoreDynamicStats()
 | 
					    void MechanicsManager::restoreDynamicStats()
 | 
				
			||||||
| 
						 | 
					@ -471,8 +491,10 @@ namespace MWMechanics
 | 
				
			||||||
        if(buying) x = buyTerm;
 | 
					        if(buying) x = buyTerm;
 | 
				
			||||||
        else x = std::min(buyTerm, sellTerm);
 | 
					        else x = std::min(buyTerm, sellTerm);
 | 
				
			||||||
        int offerPrice;
 | 
					        int offerPrice;
 | 
				
			||||||
        if (x < 1) offerPrice = int(x * basePrice);
 | 
					        if (x < 1)
 | 
				
			||||||
        if (x >= 1) offerPrice = basePrice + int((x - 1) * basePrice);
 | 
					            offerPrice = int(x * basePrice);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            offerPrice = basePrice + int((x - 1) * basePrice);
 | 
				
			||||||
        offerPrice = std::max(1, offerPrice);
 | 
					        offerPrice = std::max(1, offerPrice);
 | 
				
			||||||
        return offerPrice;
 | 
					        return offerPrice;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -535,7 +557,8 @@ namespace MWMechanics
 | 
				
			||||||
        float fPerDieRollMult = gmst.find("fPerDieRollMult")->getFloat();
 | 
					        float fPerDieRollMult = gmst.find("fPerDieRollMult")->getFloat();
 | 
				
			||||||
        float fPerTempMult = gmst.find("fPerTempMult")->getFloat();
 | 
					        float fPerTempMult = gmst.find("fPerTempMult")->getFloat();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        float x,y;
 | 
					        float x = 0;
 | 
				
			||||||
 | 
					        float y = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        float roll = static_cast<float> (std::rand()) / RAND_MAX * 100;
 | 
					        float roll = static_cast<float> (std::rand()) / RAND_MAX * 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -629,4 +652,20 @@ namespace MWMechanics
 | 
				
			||||||
            permChange = success ? -int(cappedDispositionChange/ fPerTempMult) : y;
 | 
					            permChange = success ? -int(cappedDispositionChange/ fPerTempMult) : y;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(ptr.getTypeName() == typeid(ESM::Activator).name())
 | 
				
			||||||
 | 
					            mActivators.playAnimationGroup(ptr, groupName, mode, number);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            mActors.playAnimationGroup(ptr, groupName, mode, number);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    void MechanicsManager::skipAnimation(const MWWorld::Ptr& ptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(ptr.getTypeName() == typeid(ESM::Activator).name())
 | 
				
			||||||
 | 
					            mActivators.skipAnimation(ptr);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            mActors.skipAnimation(ptr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "creaturestats.hpp"
 | 
					#include "creaturestats.hpp"
 | 
				
			||||||
#include "npcstats.hpp"
 | 
					#include "npcstats.hpp"
 | 
				
			||||||
 | 
					#include "activators.hpp"
 | 
				
			||||||
#include "actors.hpp"
 | 
					#include "actors.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ogre
 | 
					namespace Ogre
 | 
				
			||||||
| 
						 | 
					@ -29,6 +30,8 @@ namespace MWMechanics
 | 
				
			||||||
            bool mUpdatePlayer;
 | 
					            bool mUpdatePlayer;
 | 
				
			||||||
            bool mClassSelected;
 | 
					            bool mClassSelected;
 | 
				
			||||||
            bool mRaceSelected;
 | 
					            bool mRaceSelected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Activators mActivators;
 | 
				
			||||||
            Actors mActors;
 | 
					            Actors mActors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void buildPlayer();
 | 
					            void buildPlayer();
 | 
				
			||||||
| 
						 | 
					@ -39,24 +42,24 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            MechanicsManager();
 | 
					            MechanicsManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void addActor (const MWWorld::Ptr& ptr);
 | 
					            virtual void add (const MWWorld::Ptr& ptr);
 | 
				
			||||||
            ///< Register an actor for stats management
 | 
					            ///< Register an object for management
 | 
				
			||||||
            ///
 | 
					 | 
				
			||||||
            /// \note Dead actors are ignored.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void removeActor (const MWWorld::Ptr& ptr);
 | 
					            virtual void remove (const MWWorld::Ptr& ptr);
 | 
				
			||||||
            ///< Deregister an actor for stats management
 | 
					            ///< Deregister an object for management
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void dropActors (const MWWorld::CellStore *cellStore);
 | 
					            virtual void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr);
 | 
				
			||||||
            ///< Deregister all actors in the given cell.
 | 
					            ///< Moves an object to a new cell
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void watchActor (const MWWorld::Ptr& ptr);
 | 
					            virtual void drop(const MWWorld::CellStore *cellStore);
 | 
				
			||||||
 | 
					            ///< Deregister all objects in the given cell.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual void watchActor(const MWWorld::Ptr& ptr);
 | 
				
			||||||
            ///< On each update look for changes in a previously registered actor and update the
 | 
					            ///< On each update look for changes in a previously registered actor and update the
 | 
				
			||||||
            /// GUI accordingly.
 | 
					            /// GUI accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
 | 
					            virtual void update (float duration, bool paused);
 | 
				
			||||||
                float duration, bool paused);
 | 
					            ///< Update objects
 | 
				
			||||||
            ///< Update actor stats and store desired velocity vectors in \a movement
 | 
					 | 
				
			||||||
            ///
 | 
					            ///
 | 
				
			||||||
            /// \param paused In game type does not currently advance (this usually means some GUI
 | 
					            /// \param paused In game type does not currently advance (this usually means some GUI
 | 
				
			||||||
            /// component is up).
 | 
					            /// component is up).
 | 
				
			||||||
| 
						 | 
					@ -92,6 +95,9 @@ namespace MWMechanics
 | 
				
			||||||
                float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange);
 | 
					                float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange);
 | 
				
			||||||
            void toLower(std::string npcFaction);
 | 
					            void toLower(std::string npcFaction);
 | 
				
			||||||
            ///< Perform a persuasion action on NPC
 | 
					            ///< Perform a persuasion action on NPC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
 | 
				
			||||||
 | 
					        virtual void skipAnimation(const MWWorld::Ptr& ptr);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										56
									
								
								apps/openmw/mwrender/activatoranimation.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								apps/openmw/mwrender/activatoranimation.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,56 @@
 | 
				
			||||||
 | 
					#include "activatoranimation.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <OgreEntity.h>
 | 
				
			||||||
 | 
					#include <OgreSceneManager.h>
 | 
				
			||||||
 | 
					#include <OgreSubEntity.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "renderconst.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWRender
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ActivatorAnimation::~ActivatorAnimation()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
 | 
				
			||||||
 | 
					  : Animation(ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MWWorld::LiveCellRef<ESM::Activator> *ref = mPtr.get<ESM::Activator>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert (ref->mBase != NULL);
 | 
				
			||||||
 | 
					    if(!ref->mBase->mModel.empty())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::string mesh = "meshes\\" + ref->mBase->mModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        createEntityList(mPtr.getRefData().getBaseNode(), mesh);
 | 
				
			||||||
 | 
					        for(size_t i = 0;i < mEntityList.mEntities.size();i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Ogre::Entity *ent = mEntityList.mEntities[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bool transparent = false;
 | 
				
			||||||
 | 
					            for(unsigned int j=0;!transparent && j < ent->getNumSubEntities(); ++j)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
 | 
				
			||||||
 | 
					                Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
 | 
				
			||||||
 | 
					                while(!transparent && techIt.hasMoreElements())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Ogre::Technique* tech = techIt.getNext();
 | 
				
			||||||
 | 
					                    Ogre::Technique::PassIterator passIt = tech->getPassIterator();
 | 
				
			||||||
 | 
					                    while(!transparent && passIt.hasMoreElements())
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Ogre::Pass* pass = passIt.getNext();
 | 
				
			||||||
 | 
					                        transparent = pass->isTransparent();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ent->setVisibilityFlags(RV_Misc);
 | 
				
			||||||
 | 
					            ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        setAnimationSource(mesh);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								apps/openmw/mwrender/activatoranimation.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								apps/openmw/mwrender/activatoranimation.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					#ifndef _GAME_RENDER_ACTIVATORANIMATION_H
 | 
				
			||||||
 | 
					#define _GAME_RENDER_ACTIVATORANIMATION_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "animation.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWWorld
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class Ptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWRender
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class ActivatorAnimation : public Animation
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        ActivatorAnimation(const MWWorld::Ptr& ptr);
 | 
				
			||||||
 | 
					        virtual ~ActivatorAnimation();
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -3,14 +3,23 @@
 | 
				
			||||||
#include <OgreSceneNode.h>
 | 
					#include <OgreSceneNode.h>
 | 
				
			||||||
#include <OgreSceneManager.h>
 | 
					#include <OgreSceneManager.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwworld/ptr.hpp"
 | 
				
			||||||
 | 
					#include "../mwworld/class.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "animation.hpp"
 | 
				
			||||||
 | 
					#include "activatoranimation.hpp"
 | 
				
			||||||
 | 
					#include "creatureanimation.hpp"
 | 
				
			||||||
 | 
					#include "npcanimation.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "renderconst.hpp"
 | 
					#include "renderconst.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWRender
 | 
					namespace MWRender
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					using namespace Ogre;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Actors::~Actors(){
 | 
					Actors::~Actors()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    PtrAnimationMap::iterator it = mAllActors.begin();
 | 
					    PtrAnimationMap::iterator it = mAllActors.begin();
 | 
				
			||||||
    for(;it != mAllActors.end();++it)
 | 
					    for(;it != mAllActors.end();++it)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -19,18 +28,10 @@ Actors::~Actors(){
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Actors::setMwRoot(Ogre::SceneNode* root)
 | 
					void Actors::setRootNode(Ogre::SceneNode* root)
 | 
				
			||||||
{ mMwRoot = root; }
 | 
					{ mRootNode = root; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Actors::insertNPC(const MWWorld::Ptr &ptr, MWWorld::InventoryStore &inv)
 | 
					void Actors::insertBegin(const MWWorld::Ptr &ptr)
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    insertBegin(ptr, true, true);
 | 
					 | 
				
			||||||
    NpcAnimation* anim = new MWRender::NpcAnimation(ptr, ptr.getRefData ().getBaseNode (), inv, RV_Actors);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    mAllActors[ptr] = anim;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Ogre::SceneNode* cellnode;
 | 
					    Ogre::SceneNode* cellnode;
 | 
				
			||||||
    CellSceneNodeMap::const_iterator celliter = mCellSceneNodes.find(ptr.getCell());
 | 
					    CellSceneNodeMap::const_iterator celliter = mCellSceneNodes.find(ptr.getCell());
 | 
				
			||||||
| 
						 | 
					@ -39,7 +40,7 @@ void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        //Create the scenenode and put it in the map
 | 
					        //Create the scenenode and put it in the map
 | 
				
			||||||
        cellnode = mMwRoot->createChildSceneNode();
 | 
					        cellnode = mRootNode->createChildSceneNode();
 | 
				
			||||||
        mCellSceneNodes[ptr.getCell()] = cellnode;
 | 
					        mCellSceneNodes[ptr.getCell()] = cellnode;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,17 +63,27 @@ void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   // Rotates first around z, then y, then x
 | 
					   // Rotates first around z, then y, then x
 | 
				
			||||||
    insert->setOrientation(xr*yr*zr);
 | 
					    insert->setOrientation(xr*yr*zr);
 | 
				
			||||||
    if (!enabled)
 | 
					 | 
				
			||||||
         insert->setVisible (false);
 | 
					 | 
				
			||||||
    ptr.getRefData().setBaseNode(insert);
 | 
					    ptr.getRefData().setBaseNode(insert);
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Actors::insertCreature (const MWWorld::Ptr& ptr){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    insertBegin(ptr, true, true);
 | 
					 | 
				
			||||||
    CreatureAnimation* anim = new MWRender::CreatureAnimation(ptr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    insertBegin(ptr);
 | 
				
			||||||
 | 
					    NpcAnimation* anim = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), inv, RV_Actors);
 | 
				
			||||||
 | 
					    delete mAllActors[ptr];
 | 
				
			||||||
 | 
					    mAllActors[ptr] = anim;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void Actors::insertCreature (const MWWorld::Ptr& ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    insertBegin(ptr);
 | 
				
			||||||
 | 
					    CreatureAnimation* anim = new CreatureAnimation(ptr);
 | 
				
			||||||
 | 
					    delete mAllActors[ptr];
 | 
				
			||||||
 | 
					    mAllActors[ptr] = anim;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void Actors::insertActivator (const MWWorld::Ptr& ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    insertBegin(ptr);
 | 
				
			||||||
 | 
					    ActivatorAnimation* anim = new ActivatorAnimation(ptr);
 | 
				
			||||||
    delete mAllActors[ptr];
 | 
					    delete mAllActors[ptr];
 | 
				
			||||||
    mAllActors[ptr] = anim;
 | 
					    mAllActors[ptr] = anim;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -125,47 +136,41 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Actors::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    PtrAnimationMap::const_iterator iter = mAllActors.find(ptr);
 | 
					 | 
				
			||||||
    if(iter != mAllActors.end())
 | 
					 | 
				
			||||||
        iter->second->playGroup(groupName, mode, number);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
void Actors::skipAnimation (const MWWorld::Ptr& ptr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    PtrAnimationMap::const_iterator iter = mAllActors.find(ptr);
 | 
					 | 
				
			||||||
    if(iter != mAllActors.end())
 | 
					 | 
				
			||||||
        iter->second->skipAnim();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
void Actors::update (float duration)
 | 
					void Actors::update (float duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    for(PtrAnimationMap::const_iterator iter = mAllActors.begin();iter != mAllActors.end();iter++)
 | 
					    // Nothing to do
 | 
				
			||||||
        iter->second->runAnimation(duration);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Actors::updateObjectCell(const MWWorld::Ptr &ptr)
 | 
					Animation* Actors::getAnimation(const MWWorld::Ptr &ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PtrAnimationMap::const_iterator iter = mAllActors.find(ptr);
 | 
				
			||||||
 | 
					    if(iter != mAllActors.end())
 | 
				
			||||||
 | 
					        return iter->second;
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Actors::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Ogre::SceneNode *node;
 | 
					    Ogre::SceneNode *node;
 | 
				
			||||||
    MWWorld::CellStore *newCell = ptr.getCell();
 | 
					    MWWorld::CellStore *newCell = cur.getCell();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CellSceneNodeMap::const_iterator celliter = mCellSceneNodes.find(newCell);
 | 
					    CellSceneNodeMap::const_iterator celliter = mCellSceneNodes.find(newCell);
 | 
				
			||||||
    if(celliter != mCellSceneNodes.end())
 | 
					    if(celliter != mCellSceneNodes.end())
 | 
				
			||||||
        node = celliter->second;
 | 
					        node = celliter->second;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        node = mMwRoot->createChildSceneNode();
 | 
					        node = mRootNode->createChildSceneNode();
 | 
				
			||||||
        mCellSceneNodes[newCell] = node;
 | 
					        mCellSceneNodes[newCell] = node;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    node->addChild(ptr.getRefData().getBaseNode());
 | 
					    node->addChild(cur.getRefData().getBaseNode());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PtrAnimationMap::iterator iter = mAllActors.find(ptr);
 | 
					    PtrAnimationMap::iterator iter = mAllActors.find(old);
 | 
				
			||||||
    if(iter != mAllActors.end())
 | 
					    if(iter != mAllActors.end())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /// \note Update key (Ptr's are compared only with refdata so mCell
 | 
					 | 
				
			||||||
        /// on key is outdated), maybe redundant
 | 
					 | 
				
			||||||
        Animation *anim = iter->second;
 | 
					        Animation *anim = iter->second;
 | 
				
			||||||
        mAllActors.erase(iter);
 | 
					        mAllActors.erase(iter);
 | 
				
			||||||
        mAllActors[ptr] = anim;
 | 
					        anim->updatePtr(cur);
 | 
				
			||||||
 | 
					        mAllActors[cur] = anim;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,24 +1,27 @@
 | 
				
			||||||
#ifndef _GAME_RENDER_ACTORS_H
 | 
					#ifndef _GAME_RENDER_ACTORS_H
 | 
				
			||||||
#define _GAME_RENDER_ACTORS_H
 | 
					#define _GAME_RENDER_ACTORS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "npcanimation.hpp"
 | 
					#include <openengine/ogre/renderer.hpp>
 | 
				
			||||||
#include "creatureanimation.hpp"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWWorld
 | 
					namespace MWWorld
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class Ptr;
 | 
					    class Ptr;
 | 
				
			||||||
    class CellStore;
 | 
					    class CellStore;
 | 
				
			||||||
 | 
					    class InventoryStore;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWRender
 | 
					namespace MWRender
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    class Animation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Actors
 | 
					    class Actors
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        typedef std::map<MWWorld::CellStore*,Ogre::SceneNode*> CellSceneNodeMap;
 | 
					        typedef std::map<MWWorld::CellStore*,Ogre::SceneNode*> CellSceneNodeMap;
 | 
				
			||||||
        typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap;
 | 
					        typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        OEngine::Render::OgreRenderer &mRend;
 | 
					        OEngine::Render::OgreRenderer &mRend;
 | 
				
			||||||
        Ogre::SceneNode* mMwRoot;
 | 
					        Ogre::SceneNode* mRootNode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CellSceneNodeMap mCellSceneNodes;
 | 
					        CellSceneNodeMap mCellSceneNodes;
 | 
				
			||||||
        PtrAnimationMap mAllActors;
 | 
					        PtrAnimationMap mAllActors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,31 +29,22 @@ namespace MWRender
 | 
				
			||||||
        Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {}
 | 
					        Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {}
 | 
				
			||||||
        ~Actors();
 | 
					        ~Actors();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void setMwRoot(Ogre::SceneNode* root);
 | 
					        void setRootNode(Ogre::SceneNode* root);
 | 
				
			||||||
        void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
 | 
					        void insertBegin (const MWWorld::Ptr& ptr);
 | 
				
			||||||
        void insertCreature (const MWWorld::Ptr& ptr);
 | 
					 | 
				
			||||||
        void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv);
 | 
					        void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv);
 | 
				
			||||||
 | 
					        void insertCreature (const MWWorld::Ptr& ptr);
 | 
				
			||||||
 | 
					        void insertActivator (const MWWorld::Ptr& ptr);
 | 
				
			||||||
         bool deleteObject (const MWWorld::Ptr& ptr);
 | 
					         bool deleteObject (const MWWorld::Ptr& ptr);
 | 
				
			||||||
        ///< \return found?
 | 
					        ///< \return found?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void removeCell(MWWorld::CellStore* store);
 | 
					        void removeCell(MWWorld::CellStore* store);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode,
 | 
					 | 
				
			||||||
        int number = 1);
 | 
					 | 
				
			||||||
        ///< Run animation for a MW-reference. Calls to this function for references that are currently not
 | 
					 | 
				
			||||||
        /// in the rendered scene should be ignored.
 | 
					 | 
				
			||||||
        ///
 | 
					 | 
				
			||||||
        /// \param mode: 0 normal, 1 immediate start, 2 immediate loop
 | 
					 | 
				
			||||||
        /// \param number How offen the animation should be run
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void skipAnimation (const MWWorld::Ptr& ptr);
 | 
					 | 
				
			||||||
        ///< Skip the animation for the given MW-reference for one frame. Calls to this function for
 | 
					 | 
				
			||||||
        /// references that are currently not in the rendered scene should be ignored.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void update (float duration);
 | 
					        void update (float duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// Updates containing cell for object rendering data
 | 
					        /// Updates containing cell for object rendering data
 | 
				
			||||||
        void updateObjectCell(const MWWorld::Ptr &ptr);
 | 
					        void updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Animation* getAnimation(const MWWorld::Ptr &ptr);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,148 +1,453 @@
 | 
				
			||||||
#include "animation.hpp"
 | 
					#include "animation.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <OgreHardwarePixelBuffer.h>
 | 
					#include <OgreSkeletonManager.h>
 | 
				
			||||||
#include <OgreSkeletonInstance.h>
 | 
					#include <OgreSkeletonInstance.h>
 | 
				
			||||||
#include <OgreEntity.h>
 | 
					#include <OgreEntity.h>
 | 
				
			||||||
#include <OgreBone.h>
 | 
					#include <OgreBone.h>
 | 
				
			||||||
#include <OgreSubMesh.h>
 | 
					#include <OgreSubMesh.h>
 | 
				
			||||||
#include <OgreSceneManager.h>
 | 
					#include <OgreSceneManager.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
 | 
					#include "../mwbase/soundmanager.hpp"
 | 
				
			||||||
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwmechanics/character.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWRender
 | 
					namespace MWRender
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Animation::Animation()
 | 
					Animation::Animation(const MWWorld::Ptr &ptr)
 | 
				
			||||||
    : mInsert(NULL)
 | 
					    : mPtr(ptr)
 | 
				
			||||||
    , mTime(0.0f)
 | 
					    , mController(NULL)
 | 
				
			||||||
    , mSkipFrame(false)
 | 
					    , mInsert(NULL)
 | 
				
			||||||
 | 
					    , mAccumRoot(NULL)
 | 
				
			||||||
 | 
					    , mNonAccumRoot(NULL)
 | 
				
			||||||
 | 
					    , mAccumulate(Ogre::Vector3::ZERO)
 | 
				
			||||||
 | 
					    , mLastPosition(0.0f)
 | 
				
			||||||
 | 
					    , mCurrentKeys(NULL)
 | 
				
			||||||
 | 
					    , mCurrentAnim(NULL)
 | 
				
			||||||
 | 
					    , mCurrentTime(0.0f)
 | 
				
			||||||
 | 
					    , mStopTime(0.0f)
 | 
				
			||||||
 | 
					    , mPlaying(false)
 | 
				
			||||||
 | 
					    , mLooping(false)
 | 
				
			||||||
 | 
					    , mAnimVelocity(0.0f)
 | 
				
			||||||
 | 
					    , mAnimSpeedMult(1.0f)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Animation::~Animation()
 | 
					Animation::~Animation()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Ogre::SceneManager *sceneMgr = mInsert->getCreator();
 | 
					    if(mInsert)
 | 
				
			||||||
    for(size_t i = 0;i < mEntityList.mEntities.size();i++)
 | 
					    {
 | 
				
			||||||
        sceneMgr->destroyEntity(mEntityList.mEntities[i]);
 | 
					        Ogre::SceneManager *sceneMgr = mInsert->getCreator();
 | 
				
			||||||
 | 
					        for(size_t i = 0;i < mEntityList.mEntities.size();i++)
 | 
				
			||||||
 | 
					            sceneMgr->destroyEntity(mEntityList.mEntities[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    mEntityList.mEntities.clear();
 | 
					    mEntityList.mEntities.clear();
 | 
				
			||||||
 | 
					    mEntityList.mSkelBase = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct checklow {
 | 
					void Animation::setAnimationSources(const std::vector<std::string> &names)
 | 
				
			||||||
    bool operator()(const char &a, const char &b) const
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return ::tolower(a) == ::tolower(b);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool Animation::findGroupTimes(const std::string &groupname, Animation::GroupTimes *times)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const std::string &start = groupname+": start";
 | 
					    if(!mEntityList.mSkelBase)
 | 
				
			||||||
    const std::string &startloop = groupname+": loop start";
 | 
					        return;
 | 
				
			||||||
    const std::string &stop = groupname+": stop";
 | 
					 | 
				
			||||||
    const std::string &stoploop = groupname+": loop stop";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    NifOgre::TextKeyMap::const_iterator iter;
 | 
					    mCurrentAnim = NULL;
 | 
				
			||||||
    for(iter = mTextKeys.begin();iter != mTextKeys.end();iter++)
 | 
					    mCurrentKeys = NULL;
 | 
				
			||||||
 | 
					    mAnimVelocity = 0.0f;
 | 
				
			||||||
 | 
					    mAccumRoot = NULL;
 | 
				
			||||||
 | 
					    mNonAccumRoot = NULL;
 | 
				
			||||||
 | 
					    mSkeletonSources.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<std::string>::const_iterator nameiter;
 | 
				
			||||||
 | 
					    for(nameiter = names.begin();nameiter != names.end();nameiter++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if(times->mStart >= 0.0f && times->mLoopStart >= 0.0f && times->mLoopStop >= 0.0f && times->mStop >= 0.0f)
 | 
					        Ogre::SkeletonPtr skel = NifOgre::Loader::getSkeleton(*nameiter);
 | 
				
			||||||
            return true;
 | 
					        if(skel.isNull())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            std::cerr<< "Failed to get skeleton source "<<*nameiter <<std::endl;
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        skel->touch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string::const_iterator strpos = iter->second.begin();
 | 
					        Ogre::Skeleton::BoneIterator boneiter = skel->getBoneIterator();
 | 
				
			||||||
        std::string::const_iterator strend = iter->second.end();
 | 
					        while(boneiter.hasMoreElements())
 | 
				
			||||||
        size_t strlen = strend-strpos;
 | 
					        {
 | 
				
			||||||
 | 
					            Ogre::Bone *bone = boneiter.getNext();
 | 
				
			||||||
 | 
					            Ogre::UserObjectBindings &bindings = bone->getUserObjectBindings();
 | 
				
			||||||
 | 
					            const Ogre::Any &data = bindings.getUserAny(NifOgre::sTextKeyExtraDataID);
 | 
				
			||||||
 | 
					            if(data.isEmpty() || !Ogre::any_cast<bool>(data))
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(!mNonAccumRoot)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                mAccumRoot = mInsert;
 | 
				
			||||||
 | 
					                mNonAccumRoot = mEntityList.mSkelBase->getSkeleton()->getBone(bone->getName());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            mSkeletonSources.push_back(skel);
 | 
				
			||||||
 | 
					            for(int i = 0;i < skel->getNumAnimations();i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Ogre::Animation *anim = skel->getAnimation(i);
 | 
				
			||||||
 | 
					                const Ogre::Any &groupdata = bindings.getUserAny(std::string(NifOgre::sTextKeyExtraDataID)+
 | 
				
			||||||
 | 
					                                                                "@"+anim->getName());
 | 
				
			||||||
 | 
					                if(!groupdata.isEmpty())
 | 
				
			||||||
 | 
					                    mTextKeys[anim->getName()] = Ogre::any_cast<NifOgre::TextKeyMap>(groupdata);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(start.size() <= strlen && std::mismatch(strpos, strend, start.begin(), checklow()).first == strend)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            times->mStart = iter->first;
 | 
					 | 
				
			||||||
            times->mLoopStart = iter->first;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if(startloop.size() <= strlen && std::mismatch(strpos, strend, startloop.begin(), checklow()).first == strend)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            times->mLoopStart = iter->first;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if(stoploop.size() <= strlen && std::mismatch(strpos, strend, stoploop.begin(), checklow()).first == strend)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            times->mLoopStop = iter->first;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if(stop.size() <= strlen && std::mismatch(strpos, strend, stop.begin(), checklow()).first == strend)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            times->mStop = iter->first;
 | 
					 | 
				
			||||||
            if(times->mLoopStop < 0.0f)
 | 
					 | 
				
			||||||
                times->mLoopStop = iter->first;
 | 
					 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (times->mStart >= 0.0f && times->mLoopStart >= 0.0f && times->mLoopStop >= 0.0f && times->mStop >= 0.0f);
 | 
					void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mInsert = node->createChildSceneNode();
 | 
				
			||||||
 | 
					    assert(mInsert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mEntityList = NifOgre::Loader::createEntities(mInsert, model);
 | 
				
			||||||
 | 
					    if(mEntityList.mSkelBase)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
 | 
				
			||||||
 | 
					        Ogre::AnimationStateIterator asiter = aset->getAnimationStateIterator();
 | 
				
			||||||
 | 
					        while(asiter.hasMoreElements())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Ogre::AnimationState *state = asiter.getNext();
 | 
				
			||||||
 | 
					            state->setEnabled(false);
 | 
				
			||||||
 | 
					            state->setLoop(false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Set the bones as manually controlled since we're applying the
 | 
				
			||||||
 | 
					        // transformations manually (needed if we want to apply an animation
 | 
				
			||||||
 | 
					        // from one skeleton onto another).
 | 
				
			||||||
 | 
					        Ogre::SkeletonInstance *skelinst = mEntityList.mSkelBase->getSkeleton();
 | 
				
			||||||
 | 
					        Ogre::Skeleton::BoneIterator boneiter = skelinst->getBoneIterator();
 | 
				
			||||||
 | 
					        while(boneiter.hasMoreElements())
 | 
				
			||||||
 | 
					            boneiter.getNext()->setManuallyControlled(true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Animation::playGroup(std::string groupname, int mode, int loops)
 | 
					bool Animation::hasAnimation(const std::string &anim)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GroupTimes times;
 | 
					    for(std::vector<Ogre::SkeletonPtr>::const_iterator iter(mSkeletonSources.begin());iter != mSkeletonSources.end();iter++)
 | 
				
			||||||
    times.mLoops = loops;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(groupname == "all")
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        times.mStart = times.mLoopStart = 0.0f;
 | 
					        if((*iter)->hasAnimation(anim))
 | 
				
			||||||
        times.mLoopStop = times.mStop = 0.0f;
 | 
					            return true;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        NifOgre::TextKeyMap::const_reverse_iterator iter = mTextKeys.rbegin();
 | 
					 | 
				
			||||||
        if(iter != mTextKeys.rend())
 | 
					 | 
				
			||||||
            times.mLoopStop = times.mStop = iter->first;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if(!findGroupTimes(groupname, ×))
 | 
					    return false;
 | 
				
			||||||
        throw std::runtime_error("Failed to find animation group "+groupname);
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(mode == 0 && mCurGroup.mLoops > 0)
 | 
					
 | 
				
			||||||
        mNextGroup = times;
 | 
					void Animation::setController(MWMechanics::CharacterController *controller)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mController = controller;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Animation::setAccumulation(const Ogre::Vector3 &accum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mAccumulate = accum;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Animation::setSpeed(float speed)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mAnimSpeedMult = 1.0f;
 | 
				
			||||||
 | 
					    if(mAnimVelocity > 1.0f && speed > 0.0f)
 | 
				
			||||||
 | 
					        mAnimSpeedMult = speed / mAnimVelocity;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Animation::setLooping(bool loop)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mLooping = loop;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Animation::updatePtr(const MWWorld::Ptr &ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mPtr = ptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Animation::calcAnimVelocity()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const Ogre::NodeAnimationTrack *track = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ogre::Animation::NodeTrackIterator trackiter = mCurrentAnim->getNodeTrackIterator();
 | 
				
			||||||
 | 
					    while(!track && trackiter.hasMoreElements())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const Ogre::NodeAnimationTrack *cur = trackiter.getNext();
 | 
				
			||||||
 | 
					        if(cur->getAssociatedNode()->getName() == mNonAccumRoot->getName())
 | 
				
			||||||
 | 
					            track = cur;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(track && track->getNumKeyFrames() > 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        float loopstarttime = 0.0f;
 | 
				
			||||||
 | 
					        float loopstoptime = mCurrentAnim->getLength();
 | 
				
			||||||
 | 
					        NifOgre::TextKeyMap::const_iterator keyiter = mCurrentKeys->begin();
 | 
				
			||||||
 | 
					        while(keyiter != mCurrentKeys->end())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if(keyiter->second == "loop start")
 | 
				
			||||||
 | 
					                loopstarttime = keyiter->first;
 | 
				
			||||||
 | 
					            else if(keyiter->second == "loop stop")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                loopstoptime = keyiter->first;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            keyiter++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(loopstoptime > loopstarttime)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Ogre::TransformKeyFrame startkf(0, loopstarttime);
 | 
				
			||||||
 | 
					            Ogre::TransformKeyFrame endkf(0, loopstoptime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(loopstarttime), &startkf);
 | 
				
			||||||
 | 
					            track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(loopstoptime), &endkf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            mAnimVelocity = startkf.getTranslate().distance(endkf.getTranslate()) /
 | 
				
			||||||
 | 
					                            (loopstoptime-loopstarttime);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Animation::applyAnimation(const Ogre::Animation *anim, float time, Ogre::SkeletonInstance *skel)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Ogre::TimeIndex timeindex = anim->_getTimeIndex(time);
 | 
				
			||||||
 | 
					    Ogre::Animation::NodeTrackIterator tracks = anim->getNodeTrackIterator();
 | 
				
			||||||
 | 
					    while(tracks.hasMoreElements())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Ogre::NodeAnimationTrack *track = tracks.getNext();
 | 
				
			||||||
 | 
					        const Ogre::String &targetname = track->getAssociatedNode()->getName();
 | 
				
			||||||
 | 
					        if(!skel->hasBone(targetname))
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        Ogre::Bone *bone = skel->getBone(targetname);
 | 
				
			||||||
 | 
					        bone->setOrientation(Ogre::Quaternion::IDENTITY);
 | 
				
			||||||
 | 
					        bone->setPosition(Ogre::Vector3::ZERO);
 | 
				
			||||||
 | 
					        bone->setScale(Ogre::Vector3::UNIT_SCALE);
 | 
				
			||||||
 | 
					        track->applyToNode(bone, timeindex);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // HACK: Dirty the animation state set so that Ogre will apply the
 | 
				
			||||||
 | 
					    // transformations to entities this skeleton instance is shared with.
 | 
				
			||||||
 | 
					    mEntityList.mSkelBase->getAllAnimationStates()->_notifyDirty();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void updateBoneTree(const Ogre::SkeletonInstance *skelsrc, Ogre::Bone *bone)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(skelsrc->hasBone(bone->getName()))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Ogre::Bone *srcbone = skelsrc->getBone(bone->getName());
 | 
				
			||||||
 | 
					        if(!srcbone->getParent() || !bone->getParent())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            bone->setOrientation(srcbone->getOrientation());
 | 
				
			||||||
 | 
					            bone->setPosition(srcbone->getPosition());
 | 
				
			||||||
 | 
					            bone->setScale(srcbone->getScale());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            bone->_setDerivedOrientation(srcbone->_getDerivedOrientation());
 | 
				
			||||||
 | 
					            bone->_setDerivedPosition(srcbone->_getDerivedPosition());
 | 
				
			||||||
 | 
					            bone->setScale(Ogre::Vector3::UNIT_SCALE);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mCurGroup = times;
 | 
					        // No matching bone in the source. Make sure it stays properly offset
 | 
				
			||||||
        mNextGroup = GroupTimes();
 | 
					        // from its parent.
 | 
				
			||||||
        mTime = ((mode==2) ? mCurGroup.mLoopStart : mCurGroup.mStart);
 | 
					        bone->resetToInitialState();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ogre::Node::ChildNodeIterator boneiter = bone->getChildIterator();
 | 
				
			||||||
 | 
					    while(boneiter.hasMoreElements())
 | 
				
			||||||
 | 
					        updateBoneTree(skelsrc, static_cast<Ogre::Bone*>(boneiter.getNext()));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Animation::skipAnim()
 | 
					void Animation::updateSkeletonInstance(const Ogre::SkeletonInstance *skelsrc, Ogre::SkeletonInstance *skel)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mSkipFrame = true;
 | 
					    Ogre::Skeleton::BoneIterator boneiter = skel->getRootBoneIterator();
 | 
				
			||||||
 | 
					    while(boneiter.hasMoreElements())
 | 
				
			||||||
 | 
					        updateBoneTree(skelsrc, boneiter.getNext());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Animation::runAnimation(float timepassed)
 | 
					
 | 
				
			||||||
 | 
					Ogre::Vector3 Animation::updatePosition(float time)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if(mCurGroup.mLoops > 0 && !mSkipFrame)
 | 
					    if(mLooping)
 | 
				
			||||||
 | 
					        mCurrentTime = std::fmod(std::max(time, 0.0f), mCurrentAnim->getLength());
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        mCurrentTime = std::min(mCurrentAnim->getLength(), std::max(time, 0.0f));
 | 
				
			||||||
 | 
					    applyAnimation(mCurrentAnim, mCurrentTime, mEntityList.mSkelBase->getSkeleton());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ogre::Vector3 posdiff = Ogre::Vector3::ZERO;
 | 
				
			||||||
 | 
					    if(mNonAccumRoot)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mTime += timepassed;
 | 
					        /* Get the non-accumulation root's difference from the last update. */
 | 
				
			||||||
        if(mTime >= mCurGroup.mLoopStop)
 | 
					        posdiff = (mNonAccumRoot->getPosition() - mLastPosition) * mAccumulate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Translate the accumulation root back to compensate for the move. */
 | 
				
			||||||
 | 
					        mLastPosition += posdiff;
 | 
				
			||||||
 | 
					        mAccumRoot->setPosition(-mLastPosition);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return posdiff;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Animation::reset(const std::string &start, const std::string &stop)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mNextKey = mCurrentKeys->begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(mNextKey != mCurrentKeys->end() && mNextKey->second != start)
 | 
				
			||||||
 | 
					        mNextKey++;
 | 
				
			||||||
 | 
					    if(mNextKey != mCurrentKeys->end())
 | 
				
			||||||
 | 
					        mCurrentTime = mNextKey->first;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        mNextKey = mCurrentKeys->begin();
 | 
				
			||||||
 | 
					        mCurrentTime = 0.0f;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(stop.length() > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        NifOgre::TextKeyMap::const_iterator stopKey = mNextKey;
 | 
				
			||||||
 | 
					        while(stopKey != mCurrentKeys->end() && stopKey->second != stop)
 | 
				
			||||||
 | 
					            stopKey++;
 | 
				
			||||||
 | 
					        if(stopKey != mCurrentKeys->end())
 | 
				
			||||||
 | 
					            mStopTime = stopKey->first;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            mStopTime = mCurrentAnim->getLength();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(mNonAccumRoot)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const Ogre::NodeAnimationTrack *track = 0;
 | 
				
			||||||
 | 
					        Ogre::Animation::NodeTrackIterator trackiter = mCurrentAnim->getNodeTrackIterator();
 | 
				
			||||||
 | 
					        while(!track && trackiter.hasMoreElements())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if(mCurGroup.mLoops > 1)
 | 
					            const Ogre::NodeAnimationTrack *cur = trackiter.getNext();
 | 
				
			||||||
            {
 | 
					            if(cur->getAssociatedNode()->getName() == mNonAccumRoot->getName())
 | 
				
			||||||
                mCurGroup.mLoops--;
 | 
					                track = cur;
 | 
				
			||||||
                mTime = mTime - mCurGroup.mLoopStop + mCurGroup.mLoopStart;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else if(mTime >= mCurGroup.mStop)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if(mNextGroup.mLoops > 0)
 | 
					 | 
				
			||||||
                    mTime = mTime - mCurGroup.mStop + mNextGroup.mStart;
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    mTime = mCurGroup.mStop;
 | 
					 | 
				
			||||||
                mCurGroup = mNextGroup;
 | 
					 | 
				
			||||||
                mNextGroup = GroupTimes();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(mEntityList.mSkelBase)
 | 
					        if(track)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
 | 
					            Ogre::TransformKeyFrame kf(0, mCurrentTime);
 | 
				
			||||||
            Ogre::AnimationStateIterator as = aset->getAnimationStateIterator();
 | 
					            track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(mCurrentTime), &kf);
 | 
				
			||||||
            while(as.hasMoreElements())
 | 
					            mLastPosition = kf.getTranslate() * mAccumulate;
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Ogre::AnimationState *state = as.getNext();
 | 
					 | 
				
			||||||
                state->setTimePosition(mTime);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mSkipFrame = false;
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Animation::handleEvent(float time, const std::string &evt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(evt == "start" || evt == "loop start")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Do nothing */
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(evt.compare(0, 7, "sound: ") == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
 | 
				
			||||||
 | 
					        sndMgr->playSound3D(mPtr, evt.substr(7), 1.0f, 1.0f);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(evt.compare(0, 10, "soundgen: ") == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // FIXME: Lookup the SoundGen (SNDG) for the specified sound that corresponds
 | 
				
			||||||
 | 
					        // to this actor type
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(evt == "loop stop")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(mLooping)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            reset("loop start", "");
 | 
				
			||||||
 | 
					            if(mCurrentTime >= time)
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(evt == "stop")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(mLooping)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            reset("loop start", "");
 | 
				
			||||||
 | 
					            if(mCurrentTime >= time)
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // fall-through
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(mController)
 | 
				
			||||||
 | 
					        mController->markerEvent(time, evt);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Animation::play(const std::string &groupname, const std::string &start, const std::string &stop, bool loop)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        bool found = false;
 | 
				
			||||||
 | 
					        /* Look in reverse; last-inserted source has priority. */
 | 
				
			||||||
 | 
					        for(std::vector<Ogre::SkeletonPtr>::const_reverse_iterator iter(mSkeletonSources.rbegin());iter != mSkeletonSources.rend();iter++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if((*iter)->hasAnimation(groupname))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                mCurrentAnim = (*iter)->getAnimation(groupname);
 | 
				
			||||||
 | 
					                mCurrentKeys = &mTextKeys[groupname];
 | 
				
			||||||
 | 
					                mAnimVelocity = 0.0f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(mNonAccumRoot)
 | 
				
			||||||
 | 
					                    calcAnimVelocity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                found = true;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(!found)
 | 
				
			||||||
 | 
					            throw std::runtime_error("Failed to find animation "+groupname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        reset(start, stop);
 | 
				
			||||||
 | 
					        setLooping(loop);
 | 
				
			||||||
 | 
					        mPlaying = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    catch(std::exception &e) {
 | 
				
			||||||
 | 
					        std::cerr<< e.what() <<std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ogre::Vector3 Animation::runAnimation(float timepassed)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Ogre::Vector3 movement = Ogre::Vector3::ZERO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    timepassed *= mAnimSpeedMult;
 | 
				
			||||||
 | 
					    while(mCurrentAnim && mPlaying)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        float targetTime = std::min(mStopTime, mCurrentTime+timepassed);
 | 
				
			||||||
 | 
					        if(mNextKey == mCurrentKeys->end() || mNextKey->first > targetTime)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            movement += updatePosition(targetTime);
 | 
				
			||||||
 | 
					            mPlaying = (mLooping || mStopTime > targetTime);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float time = mNextKey->first;
 | 
				
			||||||
 | 
					        const std::string &evt = mNextKey->second;
 | 
				
			||||||
 | 
					        mNextKey++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        movement += updatePosition(time);
 | 
				
			||||||
 | 
					        mPlaying = (mLooping || mStopTime > time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        timepassed = targetTime - time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!handleEvent(time, evt))
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return movement;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,55 +1,99 @@
 | 
				
			||||||
#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 <components/nifogre/ogre_nif_loader.hpp>
 | 
				
			||||||
#include <openengine/ogre/renderer.hpp>
 | 
					 | 
				
			||||||
#include "../mwworld/actiontalk.hpp"
 | 
					 | 
				
			||||||
#include <components/nif/node.hpp>
 | 
					 | 
				
			||||||
#include <openengine/bullet/physic.hpp>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwworld/ptr.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWMechanics
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class CharacterController;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWRender
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWRender {
 | 
					class Animation
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
class Animation {
 | 
					 | 
				
			||||||
    struct GroupTimes {
 | 
					 | 
				
			||||||
        float mStart;
 | 
					 | 
				
			||||||
        float mStop;
 | 
					 | 
				
			||||||
        float mLoopStart;
 | 
					 | 
				
			||||||
        float mLoopStop;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        size_t mLoops;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        GroupTimes()
 | 
					 | 
				
			||||||
          : mStart(-1.0f), mStop(-1.0f), mLoopStart(-1.0f), mLoopStop(-1.0f),
 | 
					 | 
				
			||||||
            mLoops(0)
 | 
					 | 
				
			||||||
        { }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
 | 
					    MWWorld::Ptr mPtr;
 | 
				
			||||||
 | 
					    MWMechanics::CharacterController *mController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ogre::SceneNode* mInsert;
 | 
					    Ogre::SceneNode* mInsert;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    float mTime;
 | 
					 | 
				
			||||||
    GroupTimes mCurGroup;
 | 
					 | 
				
			||||||
    GroupTimes mNextGroup;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool mSkipFrame;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    NifOgre::EntityList mEntityList;
 | 
					    NifOgre::EntityList mEntityList;
 | 
				
			||||||
    NifOgre::TextKeyMap mTextKeys;
 | 
					    std::map<std::string,NifOgre::TextKeyMap> mTextKeys;
 | 
				
			||||||
 | 
					    Ogre::Node *mAccumRoot;
 | 
				
			||||||
 | 
					    Ogre::Bone *mNonAccumRoot;
 | 
				
			||||||
 | 
					    Ogre::Vector3 mAccumulate;
 | 
				
			||||||
 | 
					    Ogre::Vector3 mLastPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool findGroupTimes(const std::string &groupname, GroupTimes *times);
 | 
					    std::vector<Ogre::SkeletonPtr> mSkeletonSources;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NifOgre::TextKeyMap *mCurrentKeys;
 | 
				
			||||||
 | 
					    NifOgre::TextKeyMap::const_iterator mNextKey;
 | 
				
			||||||
 | 
					    Ogre::Animation *mCurrentAnim;
 | 
				
			||||||
 | 
					    float mCurrentTime;
 | 
				
			||||||
 | 
					    float mStopTime;
 | 
				
			||||||
 | 
					    bool mPlaying;
 | 
				
			||||||
 | 
					    bool mLooping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    float mAnimVelocity;
 | 
				
			||||||
 | 
					    float mAnimSpeedMult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void calcAnimVelocity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Applies the given animation to the given skeleton instance, using the specified time. */
 | 
				
			||||||
 | 
					    void applyAnimation(const Ogre::Animation *anim, float time, Ogre::SkeletonInstance *skel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Updates a skeleton instance so that all bones matching the source skeleton (based on
 | 
				
			||||||
 | 
					     * bone names) are positioned identically. */
 | 
				
			||||||
 | 
					    void updateSkeletonInstance(const Ogre::SkeletonInstance *skelsrc, Ogre::SkeletonInstance *skel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Updates the animation to the specified time, and returns the movement
 | 
				
			||||||
 | 
					     * vector since the last update or reset. */
 | 
				
			||||||
 | 
					    Ogre::Vector3 updatePosition(float time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Resets the animation to the time of the specified start marker, without
 | 
				
			||||||
 | 
					     * moving anything, and set the end time to the specified stop marker. If
 | 
				
			||||||
 | 
					     * the marker is not found, it resets to the beginning or end respectively.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void reset(const std::string &start, const std::string &stop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool handleEvent(float time, const std::string &evt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Specifies a list of skeleton names to use as animation sources. */
 | 
				
			||||||
 | 
					    void setAnimationSources(const std::vector<std::string> &names);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Specifies a single skeleton name to use as an animation source. */
 | 
				
			||||||
 | 
					    void setAnimationSource(const std::string &name)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::vector<std::string> names(1, name);
 | 
				
			||||||
 | 
					        setAnimationSources(names);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void createEntityList(Ogre::SceneNode *node, const std::string &model);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    Animation();
 | 
					    Animation(const MWWorld::Ptr &ptr);
 | 
				
			||||||
    virtual ~Animation();
 | 
					    virtual ~Animation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void playGroup(std::string groupname, int mode, int loops);
 | 
					    void setController(MWMechanics::CharacterController *controller);
 | 
				
			||||||
    void skipAnim();
 | 
					
 | 
				
			||||||
    virtual void runAnimation(float timepassed);
 | 
					    void updatePtr(const MWWorld::Ptr &ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool hasAnimation(const std::string &anim);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Specifies the axis' to accumulate on. Non-accumulated axis will just
 | 
				
			||||||
 | 
					    // move visually, but not affect the actual movement. Each x/y/z value
 | 
				
			||||||
 | 
					    // should be on the scale of 0 to 1.
 | 
				
			||||||
 | 
					    void setAccumulation(const Ogre::Vector3 &accum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setSpeed(float speed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setLooping(bool loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void play(const std::string &groupname, const std::string &start, const std::string &stop, bool loop);
 | 
				
			||||||
 | 
					    virtual Ogre::Vector3 runAnimation(float timepassed);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@
 | 
				
			||||||
#include "../mwbase/environment.hpp"
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
#include "../mwbase/world.hpp"
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
#include "../mwworld/player.hpp"
 | 
					#include "../mwworld/player.hpp"
 | 
				
			||||||
 | 
					#include "../mwworld/class.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "renderconst.hpp"
 | 
					#include "renderconst.hpp"
 | 
				
			||||||
#include "npcanimation.hpp"
 | 
					#include "npcanimation.hpp"
 | 
				
			||||||
| 
						 | 
					@ -120,7 +121,8 @@ namespace MWRender
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void InventoryPreview::update(int sizeX, int sizeY)
 | 
					    void InventoryPreview::update(int sizeX, int sizeY)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mAnimation->forceUpdate ();
 | 
					        mAnimation->forceUpdate();
 | 
				
			||||||
 | 
					        mAnimation->runAnimation(0.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mViewport->setDimensions (0, 0, std::min(1.f, float(sizeX) / float(512)), std::min(1.f, float(sizeY) / float(1024)));
 | 
					        mViewport->setDimensions (0, 0, std::min(1.f, float(sizeX) / float(512)), std::min(1.f, float(sizeY) / float(1024)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,8 +145,7 @@ namespace MWRender
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview);
 | 
					        mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mAnimation->playGroup ("inventoryhandtohand", 0, 1);
 | 
					        mAnimation->play("inventoryhandtohand", "start", "stop", false);
 | 
				
			||||||
        mAnimation->runAnimation (0);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // --------------------------------------------------------------------------------------------------
 | 
					    // --------------------------------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -160,6 +161,7 @@ namespace MWRender
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RaceSelectionPreview::update(float angle)
 | 
					    void RaceSelectionPreview::update(float angle)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        mAnimation->runAnimation(0.0f);
 | 
				
			||||||
        mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL);
 | 
					        mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mNode->setVisible (true);
 | 
					        mNode->setVisible (true);
 | 
				
			||||||
| 
						 | 
					@ -174,4 +176,9 @@ namespace MWRender
 | 
				
			||||||
        rebuild();
 | 
					        rebuild();
 | 
				
			||||||
        update(0);
 | 
					        update(0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void RaceSelectionPreview::onSetup ()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        mAnimation->play("idle", "start", "stop", false);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,6 +85,8 @@ namespace MWRender
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RaceSelectionPreview();
 | 
					        RaceSelectionPreview();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual void onSetup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void update(float angle);
 | 
					        void update(float angle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const ESM::NPC &getPrototype() const {
 | 
					        const ESM::NPC &getPrototype() const {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,70 +8,54 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwbase/world.hpp"
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace Ogre;
 | 
					namespace MWRender
 | 
				
			||||||
using namespace NifOgre;
 | 
					{
 | 
				
			||||||
namespace MWRender{
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
CreatureAnimation::~CreatureAnimation()
 | 
					CreatureAnimation::~CreatureAnimation()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr): Animation()
 | 
					CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
 | 
				
			||||||
 | 
					  : Animation(ptr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mInsert = ptr.getRefData().getBaseNode();
 | 
					    MWWorld::LiveCellRef<ESM::Creature> *ref = mPtr.get<ESM::Creature>();
 | 
				
			||||||
    MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert (ref->mBase != NULL);
 | 
					    assert (ref->mBase != NULL);
 | 
				
			||||||
    if(!ref->mBase->mModel.empty())
 | 
					    if(!ref->mBase->mModel.empty())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::string mesh = "meshes\\" + ref->mBase->mModel;
 | 
					        std::string model = "meshes\\"+ref->mBase->mModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mEntityList = NifOgre::NIFLoader::createEntities(mInsert, &mTextKeys, mesh);
 | 
					        createEntityList(mPtr.getRefData().getBaseNode(), model);
 | 
				
			||||||
        for(size_t i = 0;i < mEntityList.mEntities.size();i++)
 | 
					        for(size_t i = 0;i < mEntityList.mEntities.size();i++)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Ogre::Entity *ent = mEntityList.mEntities[i];
 | 
					            Ogre::Entity *ent = mEntityList.mEntities[i];
 | 
				
			||||||
            ent->setVisibilityFlags(RV_Actors);
 | 
					            ent->setVisibilityFlags(RV_Actors);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            bool transparent = false;
 | 
					            bool transparent = false;
 | 
				
			||||||
            for (unsigned int j=0;j < ent->getNumSubEntities() && !transparent; ++j)
 | 
					            for(unsigned int j=0;!transparent && j < ent->getNumSubEntities(); ++j)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
 | 
					                Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
 | 
				
			||||||
                Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
 | 
					                Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
 | 
				
			||||||
                while (techIt.hasMoreElements() && !transparent)
 | 
					                while(!transparent && techIt.hasMoreElements())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Ogre::Technique* tech = techIt.getNext();
 | 
					                    Ogre::Technique* tech = techIt.getNext();
 | 
				
			||||||
                    Ogre::Technique::PassIterator passIt = tech->getPassIterator();
 | 
					                    Ogre::Technique::PassIterator passIt = tech->getPassIterator();
 | 
				
			||||||
                    while (passIt.hasMoreElements() && !transparent)
 | 
					                    while(!transparent && passIt.hasMoreElements())
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        Ogre::Pass* pass = passIt.getNext();
 | 
					                        Ogre::Pass* pass = passIt.getNext();
 | 
				
			||||||
 | 
					                        transparent = pass->isTransparent();
 | 
				
			||||||
                        if (pass->getDepthWriteEnabled() == false)
 | 
					 | 
				
			||||||
                            transparent = true;
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
 | 
					            ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(mEntityList.mSkelBase)
 | 
					        std::vector<std::string> names;
 | 
				
			||||||
        {
 | 
					        if((ref->mBase->mFlags&ESM::Creature::Biped))
 | 
				
			||||||
            Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
 | 
					            names.push_back("meshes\\base_anim.nif");
 | 
				
			||||||
            Ogre::AnimationStateIterator as = aset->getAnimationStateIterator();
 | 
					        names.push_back(model);
 | 
				
			||||||
            while(as.hasMoreElements())
 | 
					        setAnimationSources(names);
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Ogre::AnimationState *state = as.getNext();
 | 
					 | 
				
			||||||
                state->setEnabled(true);
 | 
					 | 
				
			||||||
                state->setLoop(false);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CreatureAnimation::runAnimation(float timepassed)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Placeholder
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Animation::runAnimation(timepassed);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,18 +3,19 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "animation.hpp"
 | 
					#include "animation.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "components/nifogre/ogre_nif_loader.hpp"
 | 
					namespace MWWorld
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class Ptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWRender
 | 
				
			||||||
namespace MWRender{
 | 
					{
 | 
				
			||||||
 | 
					    class CreatureAnimation : public Animation
 | 
				
			||||||
    class CreatureAnimation: public Animation
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        virtual ~CreatureAnimation();
 | 
					 | 
				
			||||||
        CreatureAnimation(const MWWorld::Ptr& ptr);
 | 
					        CreatureAnimation(const MWWorld::Ptr& ptr);
 | 
				
			||||||
        virtual void runAnimation(float timepassed);
 | 
					        virtual ~CreatureAnimation();
 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,8 @@
 | 
				
			||||||
#include <OgreMaterialManager.h>
 | 
					#include <OgreMaterialManager.h>
 | 
				
			||||||
#include <OgreManualObject.h>
 | 
					#include <OgreManualObject.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openengine/bullet/physic.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <components/esm/loadstat.hpp>
 | 
					#include <components/esm/loadstat.hpp>
 | 
				
			||||||
#include <components/esm/loadpgrd.hpp>
 | 
					#include <components/esm/loadpgrd.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,9 +150,9 @@ ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid)
 | 
				
			||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Debugging::Debugging(SceneNode *mwRoot, OEngine::Physic::PhysicEngine *engine) :
 | 
					Debugging::Debugging(SceneNode *root, OEngine::Physic::PhysicEngine *engine) :
 | 
				
			||||||
    mMwRoot(mwRoot), mEngine(engine),
 | 
					    mRootNode(root), mEngine(engine),
 | 
				
			||||||
    mSceneMgr(mwRoot->getCreator()),
 | 
					    mSceneMgr(root->getCreator()),
 | 
				
			||||||
    mPathgridEnabled(false),
 | 
					    mPathgridEnabled(false),
 | 
				
			||||||
    mInteriorPathgridNode(NULL), mPathGridRoot(NULL),
 | 
					    mInteriorPathgridNode(NULL), mPathGridRoot(NULL),
 | 
				
			||||||
    mGridMatsCreated(false)
 | 
					    mGridMatsCreated(false)
 | 
				
			||||||
| 
						 | 
					@ -206,7 +208,7 @@ void Debugging::togglePathgrid()
 | 
				
			||||||
        createGridMaterials();
 | 
					        createGridMaterials();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // add path grid meshes to already loaded cells
 | 
					        // add path grid meshes to already loaded cells
 | 
				
			||||||
        mPathGridRoot = mMwRoot->createChildSceneNode();
 | 
					        mPathGridRoot = mRootNode->createChildSceneNode();
 | 
				
			||||||
        for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); ++it)
 | 
					        for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); ++it)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            enableCellPathgrid(*it);
 | 
					            enableCellPathgrid(*it);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <utility>
 | 
					#include <utility>
 | 
				
			||||||
#include <openengine/ogre/renderer.hpp>
 | 
					#include <openengine/ogre/renderer.hpp>
 | 
				
			||||||
#include <openengine/bullet/physic.hpp>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
| 
						 | 
					@ -13,6 +12,14 @@ namespace ESM
 | 
				
			||||||
    struct Pathgrid;
 | 
					    struct Pathgrid;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OEngine
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    namespace Physic
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        class PhysicEngine;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ogre
 | 
					namespace Ogre
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class Camera;
 | 
					    class Camera;
 | 
				
			||||||
| 
						 | 
					@ -47,7 +54,7 @@ namespace MWRender
 | 
				
			||||||
        typedef std::vector<MWWorld::CellStore *> CellList;
 | 
					        typedef std::vector<MWWorld::CellStore *> CellList;
 | 
				
			||||||
        CellList mActiveCells;
 | 
					        CellList mActiveCells;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ogre::SceneNode *mMwRoot;
 | 
					        Ogre::SceneNode *mRootNode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ogre::SceneNode *mPathGridRoot;
 | 
					        Ogre::SceneNode *mPathGridRoot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,7 +78,7 @@ namespace MWRender
 | 
				
			||||||
        Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid);
 | 
					        Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid);
 | 
				
			||||||
        Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid);
 | 
					        Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid);
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        Debugging(Ogre::SceneNode* mwRoot, OEngine::Physic::PhysicEngine *engine);
 | 
					        Debugging(Ogre::SceneNode* root, OEngine::Physic::PhysicEngine *engine);
 | 
				
			||||||
        ~Debugging();
 | 
					        ~Debugging();
 | 
				
			||||||
        bool toggleRenderMode (int mode);
 | 
					        bool toggleRenderMode (int mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,7 +190,7 @@ namespace MWRender
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        imageX = float(x / 8192.f - mMinX) / (mMaxX - mMinX + 1);
 | 
					        imageX = float(x / 8192.f - mMinX) / (mMaxX - mMinX + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        imageY = 1.f-float(-z / 8192.f - mMinY) / (mMaxY - mMinY + 1);
 | 
					        imageY = 1.f-float(z / 8192.f - mMinY) / (mMaxY - mMinY + 1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void GlobalMap::cellTopLeftCornerToImageSpace(int x, int y, float& imageX, float& imageY)
 | 
					    void GlobalMap::cellTopLeftCornerToImageSpace(int x, int y, float& imageX, float& imageY)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,9 +28,6 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mCellCamera = mRendering->getScene()->createCamera("CellCamera");
 | 
					    mCellCamera = mRendering->getScene()->createCamera("CellCamera");
 | 
				
			||||||
    mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
 | 
					    mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
 | 
				
			||||||
    // look down -y
 | 
					 | 
				
			||||||
    const float sqrt0pt5 = 0.707106781;
 | 
					 | 
				
			||||||
    mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mCameraNode->attachObject(mCellCamera);
 | 
					    mCameraNode->attachObject(mCellCamera);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -82,8 +79,8 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
 | 
					        Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
 | 
				
			||||||
        Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
 | 
					        Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().y);
 | 
				
			||||||
        Vector2 length = max-min;
 | 
					        Vector2 length = max-min;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // divide into segments
 | 
					        // divide into segments
 | 
				
			||||||
| 
						 | 
					@ -107,6 +104,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
 | 
				
			||||||
    mInterior = false;
 | 
					    mInterior = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mCameraRotNode->setOrientation(Quaternion::IDENTITY);
 | 
					    mCameraRotNode->setOrientation(Quaternion::IDENTITY);
 | 
				
			||||||
 | 
					    mCellCamera->setOrientation(Quaternion(Ogre::Math::Cos(Ogre::Degree(0)/2.f), 0, 0, -Ogre::Math::Sin(Ogre::Degree(0)/2.f)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int x = cell->mCell->getGridX();
 | 
					    int x = cell->mCell->getGridX();
 | 
				
			||||||
    int y = cell->mCell->getGridY();
 | 
					    int y = cell->mCell->getGridY();
 | 
				
			||||||
| 
						 | 
					@ -115,49 +113,60 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mCameraPosNode->setPosition(Vector3(0,0,0));
 | 
					    mCameraPosNode->setPosition(Vector3(0,0,0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render((x+0.5)*sSize, (-y-0.5)*sSize, -10000, 10000, sSize, sSize, name);
 | 
					    render((x+0.5)*sSize, (y+0.5)*sSize, -10000, 10000, sSize, sSize, name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
 | 
					void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
 | 
				
			||||||
                            AxisAlignedBox bounds)
 | 
					                            AxisAlignedBox bounds)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    // if we're in an empty cell, don't bother rendering anything
 | 
				
			||||||
 | 
					    if (bounds.isNull ())
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mInterior = true;
 | 
					    mInterior = true;
 | 
				
			||||||
    mBounds = bounds;
 | 
					    mBounds = bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y);
 | 
					    float zMin = mBounds.getMinimum().z;
 | 
				
			||||||
 | 
					    float zMax = mBounds.getMaximum().z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const Vector2& north = MWBase::Environment::get().getWorld()->getNorthVector(cell);
 | 
					    const Vector2& north = MWBase::Environment::get().getWorld()->getNorthVector(cell);
 | 
				
			||||||
    Radian angle(std::atan2(-north.x, -north.y));
 | 
					    Radian angle = Ogre::Math::ATan2 (north.x, north.y);
 | 
				
			||||||
    mAngle = angle.valueRadians();
 | 
					    mAngle = angle.valueRadians();
 | 
				
			||||||
    mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0));
 | 
					
 | 
				
			||||||
 | 
					    mCellCamera->setOrientation(Quaternion::IDENTITY);
 | 
				
			||||||
 | 
					    mCameraRotNode->setOrientation(Quaternion(Math::Cos(mAngle/2.f), 0, 0, -Math::Sin(mAngle/2.f)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // rotate the cell and merge the rotated corners to the bounding box
 | 
					    // rotate the cell and merge the rotated corners to the bounding box
 | 
				
			||||||
    Vector2 _center(bounds.getCenter().x, bounds.getCenter().z);
 | 
					    Vector2 _center(bounds.getCenter().x, bounds.getCenter().y);
 | 
				
			||||||
    Vector3 _c1 = bounds.getCorner(AxisAlignedBox::NEAR_LEFT_BOTTOM);
 | 
					    Vector3 _c1 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM);
 | 
				
			||||||
    Vector3 _c2 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM);
 | 
					    Vector3 _c2 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM);
 | 
				
			||||||
    Vector3 _c3 = bounds.getCorner(AxisAlignedBox::NEAR_RIGHT_BOTTOM);
 | 
					    Vector3 _c3 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_TOP);
 | 
				
			||||||
    Vector3 _c4 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM);
 | 
					    Vector3 _c4 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_TOP);
 | 
				
			||||||
    Vector2 c1(_c1.x, _c1.z);
 | 
					
 | 
				
			||||||
    Vector2 c2(_c2.x, _c2.z);
 | 
					    Vector2 c1(_c1.x, _c1.y);
 | 
				
			||||||
    Vector2 c3(_c3.x, _c3.z);
 | 
					    Vector2 c2(_c2.x, _c2.y);
 | 
				
			||||||
    Vector2 c4(_c4.x, _c4.z);
 | 
					    Vector2 c3(_c3.x, _c3.y);
 | 
				
			||||||
 | 
					    Vector2 c4(_c4.x, _c4.y);
 | 
				
			||||||
    c1 = rotatePoint(c1, _center, mAngle);
 | 
					    c1 = rotatePoint(c1, _center, mAngle);
 | 
				
			||||||
    c2 = rotatePoint(c2, _center, mAngle);
 | 
					    c2 = rotatePoint(c2, _center, mAngle);
 | 
				
			||||||
    c3 = rotatePoint(c3, _center, mAngle);
 | 
					    c3 = rotatePoint(c3, _center, mAngle);
 | 
				
			||||||
    c4 = rotatePoint(c4, _center, mAngle);
 | 
					    c4 = rotatePoint(c4, _center, mAngle);
 | 
				
			||||||
    mBounds.merge(Vector3(c1.x, 0, c1.y));
 | 
					    mBounds.merge(Vector3(c1.x, c1.y, 0));
 | 
				
			||||||
    mBounds.merge(Vector3(c2.x, 0, c2.y));
 | 
					    mBounds.merge(Vector3(c2.x, c2.y, 0));
 | 
				
			||||||
    mBounds.merge(Vector3(c3.x, 0, c3.y));
 | 
					    mBounds.merge(Vector3(c3.x, c3.y, 0));
 | 
				
			||||||
    mBounds.merge(Vector3(c4.x, 0, c4.y));
 | 
					    mBounds.merge(Vector3(c4.x, c4.y, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vector2 center(mBounds.getCenter().x, mBounds.getCenter().z);
 | 
					    // apply a little padding
 | 
				
			||||||
 | 
					    mBounds.scale ((mBounds.getSize ()+Ogre::Vector3(1000,1000,0)) / mBounds.getSize ());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
 | 
					    Vector2 center(mBounds.getCenter().x, mBounds.getCenter().y);
 | 
				
			||||||
    Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
 | 
					
 | 
				
			||||||
 | 
					    Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
 | 
				
			||||||
 | 
					    Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vector2 length = max-min;
 | 
					    Vector2 length = max-min;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mCameraPosNode->setPosition(Vector3(center.x, 0, center.y));
 | 
					    mCameraPosNode->setPosition(Vector3(center.x, center.y, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // divide into segments
 | 
					    // divide into segments
 | 
				
			||||||
    const int segsX = std::ceil( length.x / sSize );
 | 
					    const int segsX = std::ceil( length.x / sSize );
 | 
				
			||||||
| 
						 | 
					@ -172,7 +181,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
 | 
				
			||||||
            Vector2 start = min + Vector2(sSize*x,sSize*y);
 | 
					            Vector2 start = min + Vector2(sSize*x,sSize*y);
 | 
				
			||||||
            Vector2 newcenter = start + 4096;
 | 
					            Vector2 newcenter = start + 4096;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            render(newcenter.x - center.x, newcenter.y - center.y, z.y, z.x, sSize, sSize,
 | 
					            render(newcenter.x - center.x, newcenter.y - center.y, zMin, zMax, sSize, sSize,
 | 
				
			||||||
                cell->mCell->mName + "_" + coordStr(x,y));
 | 
					                cell->mCell->mName + "_" + coordStr(x,y));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -193,7 +202,7 @@ void LocalMap::render(const float x, const float y,
 | 
				
			||||||
    mRendering->getScene()->setAmbientLight(ColourValue(1,1,1));
 | 
					    mRendering->getScene()->setAmbientLight(ColourValue(1,1,1));
 | 
				
			||||||
    mRenderingManager->disableLights();
 | 
					    mRenderingManager->disableLights();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mCameraNode->setPosition(Vector3(x, zhigh+100000, y));
 | 
					    mCameraNode->setPosition(Vector3(x, y, zhigh+100000));
 | 
				
			||||||
    //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
 | 
					    //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
 | 
				
			||||||
    mCellCamera->setFarClipDistance(0); // infinite
 | 
					    mCellCamera->setFarClipDistance(0); // infinite
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -272,15 +281,15 @@ void LocalMap::render(const float x, const float y,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y)
 | 
					void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle);
 | 
					    pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().y), mAngle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
 | 
					    Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    x = std::ceil((pos.x - min.x)/sSize)-1;
 | 
					    x = std::ceil((pos.x - min.x)/sSize)-1;
 | 
				
			||||||
    y = std::ceil((pos.y - min.y)/sSize)-1;
 | 
					    y = std::ceil((pos.y - min.y)/sSize)-1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nX = (pos.x - min.x - sSize*x)/sSize;
 | 
					    nX = (pos.x - min.x - sSize*x)/sSize;
 | 
				
			||||||
    nY = (pos.y - min.y - sSize*y)/sSize;
 | 
					    nY = 1.0-(pos.y - min.y - sSize*y)/sSize;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool LocalMap::isPositionExplored (float nX, float nY, int x, int y, bool interior)
 | 
					bool LocalMap::isPositionExplored (float nX, float nY, int x, int y, bool interior)
 | 
				
			||||||
| 
						 | 
					@ -311,19 +320,19 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
 | 
				
			||||||
    int x,y;
 | 
					    int x,y;
 | 
				
			||||||
    float u,v;
 | 
					    float u,v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vector2 pos(position.x, position.z);
 | 
					    Vector2 pos(position.x, position.y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (mInterior)
 | 
					    if (mInterior)
 | 
				
			||||||
        getInteriorMapPosition(pos, u,v, x,y);
 | 
					        getInteriorMapPosition(pos, u,v, x,y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis();
 | 
					    Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).yAxis();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
 | 
					    Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!mInterior)
 | 
					    if (!mInterior)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        x = std::ceil(pos.x / sSize)-1;
 | 
					        x = std::ceil(pos.x / sSize)-1;
 | 
				
			||||||
        y = std::ceil(-pos.y / sSize)-1;
 | 
					        y = std::ceil(pos.y / sSize)-1;
 | 
				
			||||||
        mCellX = x;
 | 
					        mCellX = x;
 | 
				
			||||||
        mCellY = y;
 | 
					        mCellY = y;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -337,7 +346,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
 | 
				
			||||||
    if (!mInterior)
 | 
					    if (!mInterior)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        u = std::abs((pos.x - (sSize*x))/sSize);
 | 
					        u = std::abs((pos.x - (sSize*x))/sSize);
 | 
				
			||||||
        v = 1-std::abs((pos.y + (sSize*y))/sSize);
 | 
					        v = 1.0-std::abs((pos.y - (sSize*y))/sSize);
 | 
				
			||||||
        texBaseName = "Cell_";
 | 
					        texBaseName = "Cell_";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
| 
						 | 
					@ -346,15 +355,13 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v);
 | 
					    MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v);
 | 
				
			||||||
    MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, -playerdirection.z);
 | 
					    MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, playerdirection.y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // explore radius (squared)
 | 
					    // explore radius (squared)
 | 
				
			||||||
    const float sqrExploreRadius = (mInterior ? 0.01 : 0.09) * sFogOfWarResolution*sFogOfWarResolution;
 | 
					    const float sqrExploreRadius = (mInterior ? 0.01 : 0.09) * sFogOfWarResolution*sFogOfWarResolution;
 | 
				
			||||||
    const float exploreRadius = (mInterior ? 0.1 : 0.3) * sFogOfWarResolution; // explore radius from 0 to sFogOfWarResolution
 | 
					    const float exploreRadius = (mInterior ? 0.1 : 0.3) * sFogOfWarResolution; // explore radius from 0 to sFogOfWarResolution
 | 
				
			||||||
    const float exploreRadiusUV = exploreRadius / sFogOfWarResolution; // explore radius from 0 to 1 (UV space)
 | 
					    const float exploreRadiusUV = exploreRadius / sFogOfWarResolution; // explore radius from 0 to 1 (UV space)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int intExtMult = mInterior ? 1 : -1; // interior and exterior have reversed Y coordinates (interior: top to bottom)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // change the affected fog of war textures (in a 3x3 grid around the player)
 | 
					    // change the affected fog of war textures (in a 3x3 grid around the player)
 | 
				
			||||||
    for (int mx = -1; mx<2; ++mx)
 | 
					    for (int mx = -1; mx<2; ++mx)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -375,7 +382,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
 | 
				
			||||||
            if (!affected)
 | 
					            if (!affected)
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::string texName = texBaseName + coordStr(x+mx,y+my*intExtMult);
 | 
					            std::string texName = texBaseName + coordStr(x+mx,y+my*-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog");
 | 
					            TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog");
 | 
				
			||||||
            if (!tex.isNull())
 | 
					            if (!tex.isNull())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,295 +5,257 @@
 | 
				
			||||||
#include <OgreSubEntity.h>
 | 
					#include <OgreSubEntity.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwworld/esmstore.hpp"
 | 
					#include "../mwworld/esmstore.hpp"
 | 
				
			||||||
 | 
					#include "../mwworld/inventorystore.hpp"
 | 
				
			||||||
 | 
					#include "../mwworld/class.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwbase/environment.hpp"
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
#include "../mwbase/world.hpp"
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "renderconst.hpp"
 | 
					#include "renderconst.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace Ogre;
 | 
					 | 
				
			||||||
using namespace NifOgre;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWRender{
 | 
					namespace MWRender
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const NpcAnimation::PartInfo NpcAnimation::sPartList[NpcAnimation::sPartListSize] = {
 | 
				
			||||||
 | 
					    { ESM::PRT_Head, "Head" },
 | 
				
			||||||
 | 
					    { ESM::PRT_Hair, "Head" },
 | 
				
			||||||
 | 
					    { ESM::PRT_Neck, "Neck" },
 | 
				
			||||||
 | 
					    { ESM::PRT_Cuirass, "Chest" },
 | 
				
			||||||
 | 
					    { ESM::PRT_Groin, "Groin" },
 | 
				
			||||||
 | 
					    { ESM::PRT_Skirt, "Groin" },
 | 
				
			||||||
 | 
					    { ESM::PRT_RHand, "Right Hand" },
 | 
				
			||||||
 | 
					    { ESM::PRT_LHand, "Left Hand" },
 | 
				
			||||||
 | 
					    { ESM::PRT_RWrist, "Right Wrist" },
 | 
				
			||||||
 | 
					    { ESM::PRT_LWrist, "Left Wrist" },
 | 
				
			||||||
 | 
					    { ESM::PRT_Shield, "Shield" },
 | 
				
			||||||
 | 
					    { ESM::PRT_RForearm, "Right Forearm" },
 | 
				
			||||||
 | 
					    { ESM::PRT_LForearm, "Left Forearm" },
 | 
				
			||||||
 | 
					    { ESM::PRT_RUpperarm, "Right Upper Arm" },
 | 
				
			||||||
 | 
					    { ESM::PRT_LUpperarm, "Left Upper Arm" },
 | 
				
			||||||
 | 
					    { ESM::PRT_RFoot, "Right Foot" },
 | 
				
			||||||
 | 
					    { ESM::PRT_LFoot, "Left Foot" },
 | 
				
			||||||
 | 
					    { ESM::PRT_RAnkle, "Right Ankle" },
 | 
				
			||||||
 | 
					    { ESM::PRT_LAnkle, "Left Ankle" },
 | 
				
			||||||
 | 
					    { ESM::PRT_RKnee, "Right Knee" },
 | 
				
			||||||
 | 
					    { ESM::PRT_LKnee, "Left Knee" },
 | 
				
			||||||
 | 
					    { ESM::PRT_RLeg, "Right Upper Leg" },
 | 
				
			||||||
 | 
					    { ESM::PRT_LLeg, "Left Upper Leg" },
 | 
				
			||||||
 | 
					    { ESM::PRT_RPauldron, "Right Clavicle" },
 | 
				
			||||||
 | 
					    { ESM::PRT_LPauldron, "Left Clavicle" },
 | 
				
			||||||
 | 
					    { ESM::PRT_Weapon, "Weapon" },
 | 
				
			||||||
 | 
					    { ESM::PRT_Tail, "Tail" }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NpcAnimation::~NpcAnimation()
 | 
					NpcAnimation::~NpcAnimation()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    removeEntities(mHead);
 | 
					    for(size_t i = 0;i < sPartListSize;i++)
 | 
				
			||||||
    removeEntities(mHair);
 | 
					        removeEntities(mEntityParts[i]);
 | 
				
			||||||
    removeEntities(mNeck);
 | 
					 | 
				
			||||||
    removeEntities(mChest);
 | 
					 | 
				
			||||||
    removeEntities(mGroin);
 | 
					 | 
				
			||||||
    removeEntities(mSkirt);
 | 
					 | 
				
			||||||
    removeEntities(mHandL);
 | 
					 | 
				
			||||||
    removeEntities(mHandR);
 | 
					 | 
				
			||||||
    removeEntities(mWristL);
 | 
					 | 
				
			||||||
    removeEntities(mWristR);
 | 
					 | 
				
			||||||
    removeEntities(mForearmL);
 | 
					 | 
				
			||||||
    removeEntities(mForearmR);
 | 
					 | 
				
			||||||
    removeEntities(mUpperArmL);
 | 
					 | 
				
			||||||
    removeEntities(mUpperArmR);
 | 
					 | 
				
			||||||
    removeEntities(mFootL);
 | 
					 | 
				
			||||||
    removeEntities(mFootR);
 | 
					 | 
				
			||||||
    removeEntities(mAnkleL);
 | 
					 | 
				
			||||||
    removeEntities(mAnkleR);
 | 
					 | 
				
			||||||
    removeEntities(mKneeL);
 | 
					 | 
				
			||||||
    removeEntities(mKneeR);
 | 
					 | 
				
			||||||
    removeEntities(mUpperLegL);
 | 
					 | 
				
			||||||
    removeEntities(mUpperLegR);
 | 
					 | 
				
			||||||
    removeEntities(mClavicleL);
 | 
					 | 
				
			||||||
    removeEntities(mClavicleR);
 | 
					 | 
				
			||||||
    removeEntities(mTail);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags)
 | 
					NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags)
 | 
				
			||||||
  : Animation(),
 | 
					  : Animation(ptr),
 | 
				
			||||||
    mStateID(-1),
 | 
					    mStateID(-1),
 | 
				
			||||||
    mInv(inv),
 | 
					 | 
				
			||||||
    mTimeToChange(0),
 | 
					    mTimeToChange(0),
 | 
				
			||||||
    mVisibilityFlags(visibilityFlags),
 | 
					    mVisibilityFlags(visibilityFlags),
 | 
				
			||||||
    mRobe(mInv.end()),
 | 
					    mRobe(inv.end()),
 | 
				
			||||||
    mHelmet(mInv.end()),
 | 
					    mHelmet(inv.end()),
 | 
				
			||||||
    mShirt(mInv.end()),
 | 
					    mShirt(inv.end()),
 | 
				
			||||||
    mCuirass(mInv.end()),
 | 
					    mCuirass(inv.end()),
 | 
				
			||||||
    mGreaves(mInv.end()),
 | 
					    mGreaves(inv.end()),
 | 
				
			||||||
    mPauldronL(mInv.end()),
 | 
					    mPauldronL(inv.end()),
 | 
				
			||||||
    mPauldronR(mInv.end()),
 | 
					    mPauldronR(inv.end()),
 | 
				
			||||||
    mBoots(mInv.end()),
 | 
					    mBoots(inv.end()),
 | 
				
			||||||
    mPants(mInv.end()),
 | 
					    mPants(inv.end()),
 | 
				
			||||||
    mGloveL(mInv.end()),
 | 
					    mGloveL(inv.end()),
 | 
				
			||||||
    mGloveR(mInv.end()),
 | 
					    mGloveR(inv.end()),
 | 
				
			||||||
    mSkirtIter(mInv.end())
 | 
					    mSkirtIter(inv.end())
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mNpc = ptr.get<ESM::NPC>()->mBase;
 | 
					    mNpc = mPtr.get<ESM::NPC>()->mBase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int init = 0; init < 27; init++)
 | 
					    for(size_t i = 0;i < sPartListSize;i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mPartslots[init] = -1;  //each slot is empty
 | 
					        mPartslots[i] = -1;  //each slot is empty
 | 
				
			||||||
        mPartPriorities[init] = 0;
 | 
					        mPartPriorities[i] = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const MWWorld::ESMStore &store =
 | 
					    const MWWorld::ESMStore &store =
 | 
				
			||||||
        MWBase::Environment::get().getWorld()->getStore();
 | 
					        MWBase::Environment::get().getWorld()->getStore();
 | 
				
			||||||
    const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace);
 | 
					    const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    float scale = race->mData.mHeight.mMale;
 | 
				
			||||||
 | 
					    if(!mNpc->isMale())
 | 
				
			||||||
 | 
					        scale = race->mData.mHeight.mFemale;
 | 
				
			||||||
 | 
					    node->scale(Ogre::Vector3(scale));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel;
 | 
					    mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel;
 | 
				
			||||||
    mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHair)->mModel;
 | 
					    mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHair)->mModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mBodyPrefix = "b_n_" + mNpc->mRace;
 | 
					    mBodyPrefix = "b_n_" + mNpc->mRace;
 | 
				
			||||||
    Misc::StringUtils::toLower(mBodyPrefix);
 | 
					    Misc::StringUtils::toLower(mBodyPrefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mInsert = node;
 | 
					 | 
				
			||||||
    assert(mInsert);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0;
 | 
					    bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0;
 | 
				
			||||||
    std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif");
 | 
					    std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mEntityList = NifOgre::NIFLoader::createEntities(mInsert, &mTextKeys, smodel);
 | 
					    createEntityList(node, smodel);
 | 
				
			||||||
    for(size_t i = 0;i < mEntityList.mEntities.size();i++)
 | 
					    for(size_t i = 0;i < mEntityList.mEntities.size();i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ogre::Entity *base = mEntityList.mEntities[i];
 | 
					        Ogre::Entity *base = mEntityList.mEntities[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        base->getUserObjectBindings ().setUserAny (Ogre::Any(-1));
 | 
					        base->getUserObjectBindings().setUserAny(Ogre::Any(-1));
 | 
				
			||||||
 | 
					 | 
				
			||||||
        base->setVisibilityFlags(mVisibilityFlags);
 | 
					        base->setVisibilityFlags(mVisibilityFlags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool transparent = false;
 | 
					        bool transparent = false;
 | 
				
			||||||
        for(unsigned int j=0;j < base->getNumSubEntities();++j)
 | 
					        for(unsigned int j=0;!transparent && j < base->getNumSubEntities();++j)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Ogre::MaterialPtr mat = base->getSubEntity(j)->getMaterial();
 | 
					            Ogre::MaterialPtr mat = base->getSubEntity(j)->getMaterial();
 | 
				
			||||||
            Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
 | 
					            Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
 | 
				
			||||||
            while (techIt.hasMoreElements())
 | 
					            while(!transparent && techIt.hasMoreElements())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Ogre::Technique* tech = techIt.getNext();
 | 
					                Ogre::Technique* tech = techIt.getNext();
 | 
				
			||||||
                Ogre::Technique::PassIterator passIt = tech->getPassIterator();
 | 
					                Ogre::Technique::PassIterator passIt = tech->getPassIterator();
 | 
				
			||||||
                while (passIt.hasMoreElements())
 | 
					                while(!transparent && passIt.hasMoreElements())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Ogre::Pass* pass = passIt.getNext();
 | 
					                    Ogre::Pass* pass = passIt.getNext();
 | 
				
			||||||
                    if (pass->getDepthWriteEnabled() == false)
 | 
					                    transparent = pass->isTransparent();
 | 
				
			||||||
                        transparent = true;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
 | 
					        base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(mEntityList.mSkelBase)
 | 
					    std::vector<std::string> skelnames(1, smodel);
 | 
				
			||||||
    {
 | 
					    if(!mNpc->isMale() && !isBeast)
 | 
				
			||||||
        Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
 | 
					        skelnames.push_back("meshes\\base_anim_female.nif");
 | 
				
			||||||
        Ogre::AnimationStateIterator as = aset->getAnimationStateIterator();
 | 
					    else if(mBodyPrefix.find("argonian") != std::string::npos)
 | 
				
			||||||
        while(as.hasMoreElements())
 | 
					        skelnames.push_back("meshes\\argonian_swimkna.nif");
 | 
				
			||||||
        {
 | 
					    if(mNpc->mModel.length() > 0)
 | 
				
			||||||
            Ogre::AnimationState *state = as.getNext();
 | 
					        skelnames.push_back("meshes\\"+Misc::StringUtils::lowerCase(mNpc->mModel));
 | 
				
			||||||
            state->setEnabled(true);
 | 
					    setAnimationSources(skelnames);
 | 
				
			||||||
            state->setLoop(false);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    float scale = race->mData.mHeight.mMale;
 | 
					    updateParts(true);
 | 
				
			||||||
    if (!mNpc->isMale()) {
 | 
					 | 
				
			||||||
        scale = race->mData.mHeight.mFemale;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    mInsert->scale(scale, scale, scale);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    updateParts();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NpcAnimation::updateParts()
 | 
					void NpcAnimation::updateParts(bool forceupdate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    bool apparelChanged = false;
 | 
					    static const struct {
 | 
				
			||||||
 | 
					        int numRemoveParts; // Max: 1
 | 
				
			||||||
 | 
					        ESM::PartReferenceType removeParts[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const struct {
 | 
					        MWWorld::ContainerStoreIterator NpcAnimation::*part;
 | 
				
			||||||
        MWWorld::ContainerStoreIterator *iter;
 | 
					 | 
				
			||||||
        int slot;
 | 
					        int slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int numReserveParts; // Max: 12
 | 
				
			||||||
 | 
					        ESM::PartReferenceType reserveParts[12];
 | 
				
			||||||
    } slotlist[] = {
 | 
					    } slotlist[] = {
 | 
				
			||||||
        { &mRobe, MWWorld::InventoryStore::Slot_Robe },
 | 
					        { 0, { },
 | 
				
			||||||
        { &mSkirtIter, MWWorld::InventoryStore::Slot_Skirt },
 | 
					          &NpcAnimation::mRobe, MWWorld::InventoryStore::Slot_Robe,
 | 
				
			||||||
        { &mHelmet, MWWorld::InventoryStore::Slot_Helmet },
 | 
					          12, { ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg,
 | 
				
			||||||
        { &mCuirass, MWWorld::InventoryStore::Slot_Cuirass },
 | 
					                ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee,
 | 
				
			||||||
        { &mGreaves, MWWorld::InventoryStore::Slot_Greaves },
 | 
					                ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_RPauldron, ESM::PRT_LPauldron }
 | 
				
			||||||
        { &mPauldronL, MWWorld::InventoryStore::Slot_LeftPauldron },
 | 
					        },
 | 
				
			||||||
        { &mPauldronR, MWWorld::InventoryStore::Slot_RightPauldron },
 | 
					
 | 
				
			||||||
        { &mBoots, MWWorld::InventoryStore::Slot_Boots },
 | 
					        { 0, { },
 | 
				
			||||||
        { &mGloveL, MWWorld::InventoryStore::Slot_LeftGauntlet },
 | 
					          &NpcAnimation::mSkirtIter, MWWorld::InventoryStore::Slot_Skirt,
 | 
				
			||||||
        { &mGloveR, MWWorld::InventoryStore::Slot_RightGauntlet },
 | 
					          3, { ESM::PRT_Groin, ESM::PRT_RLeg, ESM::PRT_LLeg }
 | 
				
			||||||
        { &mShirt, MWWorld::InventoryStore::Slot_Shirt },
 | 
					        },
 | 
				
			||||||
        { &mPants, MWWorld::InventoryStore::Slot_Pants },
 | 
					
 | 
				
			||||||
 | 
					        { 1, { ESM::PRT_Hair },
 | 
				
			||||||
 | 
					          &NpcAnimation::mHelmet, MWWorld::InventoryStore::Slot_Helmet,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { 0, { },
 | 
				
			||||||
 | 
					          &NpcAnimation::mCuirass, MWWorld::InventoryStore::Slot_Cuirass,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { 0, { },
 | 
				
			||||||
 | 
					          &NpcAnimation::mGreaves, MWWorld::InventoryStore::Slot_Greaves,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { 0, { },
 | 
				
			||||||
 | 
					          &NpcAnimation::mPauldronL, MWWorld::InventoryStore::Slot_LeftPauldron,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { 0, { },
 | 
				
			||||||
 | 
					          &NpcAnimation::mPauldronR, MWWorld::InventoryStore::Slot_RightPauldron,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { 0, { },
 | 
				
			||||||
 | 
					          &NpcAnimation::mBoots, MWWorld::InventoryStore::Slot_Boots,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { 0, { },
 | 
				
			||||||
 | 
					          &NpcAnimation::mGloveL, MWWorld::InventoryStore::Slot_LeftGauntlet,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { 0, { },
 | 
				
			||||||
 | 
					          &NpcAnimation::mGloveR, MWWorld::InventoryStore::Slot_RightGauntlet,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { 0, { },
 | 
				
			||||||
 | 
					          &NpcAnimation::mShirt, MWWorld::InventoryStore::Slot_Shirt,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { 0, { },
 | 
				
			||||||
 | 
					          &NpcAnimation::mPants, MWWorld::InventoryStore::Slot_Pants,
 | 
				
			||||||
 | 
					          0, { }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    for(size_t i = 0;i < sizeof(slotlist)/sizeof(slotlist[0]);i++)
 | 
					    static const size_t slotlistsize = sizeof(slotlist)/sizeof(slotlist[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MWWorld::InventoryStore &inv = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
 | 
				
			||||||
 | 
					    for(size_t i = 0;!forceupdate && i < slotlistsize;i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWWorld::ContainerStoreIterator iter = mInv.getSlot(slotlist[i].slot);
 | 
					        MWWorld::ContainerStoreIterator iter = inv.getSlot(slotlist[i].slot);
 | 
				
			||||||
        if(*slotlist[i].iter != iter)
 | 
					        if(this->*slotlist[i].part != iter)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            *slotlist[i].iter = iter;
 | 
					            forceupdate = true;
 | 
				
			||||||
            removePartGroup(slotlist[i].slot);
 | 
					            break;
 | 
				
			||||||
            apparelChanged = true;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if(!forceupdate)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(apparelChanged)
 | 
					    for(size_t i = 0;i < slotlistsize;i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if(mRobe != mInv.end())
 | 
					        MWWorld::ContainerStoreIterator iter = inv.getSlot(slotlist[i].slot);
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            MWWorld::Ptr ptr = *mRobe;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const ESM::Clothing *clothes = (ptr.get<ESM::Clothing>())->mBase;
 | 
					        this->*slotlist[i].part = iter;
 | 
				
			||||||
            std::vector<ESM::PartReference> parts = clothes->mParts.mParts;
 | 
					        removePartGroup(slotlist[i].slot);
 | 
				
			||||||
            addPartGroup(MWWorld::InventoryStore::Slot_Robe, 5, parts);
 | 
					
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					        if(this->*slotlist[i].part == inv.end())
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_Skirt, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					            continue;
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_RLeg, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_LLeg, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					        for(int rem = 0;rem < slotlist[i].numRemoveParts;rem++)
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_RUpperarm, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					            removeIndividualPart(slotlist[i].removeParts[rem]);
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_LUpperarm, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_RKnee, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					        int prio = 1;
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_LKnee, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					        MWWorld::ContainerStoreIterator &store = this->*slotlist[i].part;
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_RForearm, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					        if(store->getTypeName() == typeid(ESM::Clothing).name())
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_LForearm, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					        {
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_RPauldron, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					            prio = ((slotlist[i].numReserveParts+1)<<1) + 0;
 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_LPauldron, MWWorld::InventoryStore::Slot_Robe, 5);
 | 
					            const ESM::Clothing *clothes = store->get<ESM::Clothing>()->mBase;
 | 
				
			||||||
 | 
					            addPartGroup(slotlist[i].slot, prio, clothes->mParts.mParts);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if(mSkirtIter != mInv.end())
 | 
					        else if(store->getTypeName() == typeid(ESM::Armor).name())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            MWWorld::Ptr ptr = *mSkirtIter;
 | 
					            prio = ((slotlist[i].numReserveParts+1)<<1) + 1;
 | 
				
			||||||
 | 
					            const ESM::Armor *armor = store->get<ESM::Armor>()->mBase;
 | 
				
			||||||
            const ESM::Clothing *clothes = (ptr.get<ESM::Clothing>())->mBase;
 | 
					            addPartGroup(slotlist[i].slot, prio, armor->mParts.mParts);
 | 
				
			||||||
            std::vector<ESM::PartReference> parts = clothes->mParts.mParts;
 | 
					 | 
				
			||||||
            addPartGroup(MWWorld::InventoryStore::Slot_Skirt, 4, parts);
 | 
					 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Skirt, 4);
 | 
					 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_RLeg, MWWorld::InventoryStore::Slot_Skirt, 4);
 | 
					 | 
				
			||||||
            reserveIndividualPart(ESM::PRT_LLeg, MWWorld::InventoryStore::Slot_Skirt, 4);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(mHelmet != mInv.end())
 | 
					        for(int res = 0;res < slotlist[i].numReserveParts;res++)
 | 
				
			||||||
        {
 | 
					            reserveIndividualPart(slotlist[i].reserveParts[res], slotlist[i].slot, prio);
 | 
				
			||||||
            removeIndividualPart(ESM::PRT_Hair);
 | 
					 | 
				
			||||||
            const ESM::Armor *armor = (mHelmet->get<ESM::Armor>())->mBase;
 | 
					 | 
				
			||||||
            std::vector<ESM::PartReference> parts = armor->mParts.mParts;
 | 
					 | 
				
			||||||
            addPartGroup(MWWorld::InventoryStore::Slot_Helmet, 3, parts);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(mCuirass != mInv.end())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            const ESM::Armor *armor = (mCuirass->get<ESM::Armor>())->mBase;
 | 
					 | 
				
			||||||
            std::vector<ESM::PartReference> parts = armor->mParts.mParts;
 | 
					 | 
				
			||||||
            addPartGroup(MWWorld::InventoryStore::Slot_Cuirass, 3, parts);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(mGreaves != mInv.end())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            const ESM::Armor *armor = (mGreaves->get<ESM::Armor>())->mBase;
 | 
					 | 
				
			||||||
            std::vector<ESM::PartReference> parts = armor->mParts.mParts;
 | 
					 | 
				
			||||||
            addPartGroup(MWWorld::InventoryStore::Slot_Greaves, 3, parts);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(mPauldronL != mInv.end())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            const ESM::Armor *armor = (mPauldronL->get<ESM::Armor>())->mBase;
 | 
					 | 
				
			||||||
            std::vector<ESM::PartReference> parts = armor->mParts.mParts;
 | 
					 | 
				
			||||||
            addPartGroup(MWWorld::InventoryStore::Slot_LeftPauldron, 3, parts);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(mPauldronR != mInv.end())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            const ESM::Armor *armor = (mPauldronR->get<ESM::Armor>())->mBase;
 | 
					 | 
				
			||||||
            std::vector<ESM::PartReference> parts = armor->mParts.mParts;
 | 
					 | 
				
			||||||
            addPartGroup(MWWorld::InventoryStore::Slot_RightPauldron, 3, parts);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(mBoots != mInv.end())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if(mBoots->getTypeName() == typeid(ESM::Clothing).name())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                const ESM::Clothing *clothes = (mBoots->get<ESM::Clothing>())->mBase;
 | 
					 | 
				
			||||||
                std::vector<ESM::PartReference> parts = clothes->mParts.mParts;
 | 
					 | 
				
			||||||
                addPartGroup(MWWorld::InventoryStore::Slot_Boots, 2, parts);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else if(mBoots->getTypeName() == typeid(ESM::Armor).name())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                const ESM::Armor *armor = (mBoots->get<ESM::Armor>())->mBase;
 | 
					 | 
				
			||||||
                std::vector<ESM::PartReference> parts = armor->mParts.mParts;
 | 
					 | 
				
			||||||
                addPartGroup(MWWorld::InventoryStore::Slot_Boots, 3, parts);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(mGloveL != mInv.end())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if(mGloveL->getTypeName() == typeid(ESM::Clothing).name())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                const ESM::Clothing *clothes = (mGloveL->get<ESM::Clothing>())->mBase;
 | 
					 | 
				
			||||||
                std::vector<ESM::PartReference> parts = clothes->mParts.mParts;
 | 
					 | 
				
			||||||
                addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 2, parts);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                const ESM::Armor *armor = (mGloveL->get<ESM::Armor>())->mBase;
 | 
					 | 
				
			||||||
                std::vector<ESM::PartReference> parts = armor->mParts.mParts;
 | 
					 | 
				
			||||||
                addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 3, parts);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(mGloveR != mInv.end())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if(mGloveR->getTypeName() == typeid(ESM::Clothing).name())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                const ESM::Clothing *clothes = (mGloveR->get<ESM::Clothing>())->mBase;
 | 
					 | 
				
			||||||
                std::vector<ESM::PartReference> parts = clothes->mParts.mParts;
 | 
					 | 
				
			||||||
                addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 2, parts);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                const ESM::Armor *armor = (mGloveR->get<ESM::Armor>())->mBase;
 | 
					 | 
				
			||||||
                std::vector<ESM::PartReference> parts = armor->mParts.mParts;
 | 
					 | 
				
			||||||
                addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 3, parts);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(mShirt != mInv.end())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            const ESM::Clothing *clothes = (mShirt->get<ESM::Clothing>())->mBase;
 | 
					 | 
				
			||||||
            std::vector<ESM::PartReference> parts = clothes->mParts.mParts;
 | 
					 | 
				
			||||||
            addPartGroup(MWWorld::InventoryStore::Slot_Shirt, 2, parts);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(mPants != mInv.end())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            const ESM::Clothing *clothes = (mPants->get<ESM::Clothing>())->mBase;
 | 
					 | 
				
			||||||
            std::vector<ESM::PartReference> parts = clothes->mParts.mParts;
 | 
					 | 
				
			||||||
            addPartGroup(MWWorld::InventoryStore::Slot_Pants, 2, parts);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(mPartPriorities[ESM::PRT_Head] < 1)
 | 
					    if(mPartPriorities[ESM::PRT_Head] < 1)
 | 
				
			||||||
| 
						 | 
					@ -333,21 +295,18 @@ void NpcAnimation::updateParts()
 | 
				
			||||||
        if(mPartPriorities[PartTypeList[i].type] < 1)
 | 
					        if(mPartPriorities[PartTypeList[i].type] < 1)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            const ESM::BodyPart *part = NULL;
 | 
					            const ESM::BodyPart *part = NULL;
 | 
				
			||||||
            const MWWorld::Store<ESM::BodyPart> &partStore =
 | 
					            const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
 | 
				
			||||||
                store.get<ESM::BodyPart>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!mNpc->isMale()) {
 | 
					            if(!mNpc->isMale())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[0]);
 | 
					                part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[0]);
 | 
				
			||||||
                if (part == 0) {
 | 
					                if(part == 0)
 | 
				
			||||||
                    part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[1]);
 | 
					                    part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[1]);
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (part == 0) {
 | 
					            if(part == 0)
 | 
				
			||||||
                part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[0]);
 | 
					                part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[0]);
 | 
				
			||||||
            }
 | 
					            if(part == 0)
 | 
				
			||||||
            if (part == 0) {
 | 
					 | 
				
			||||||
                part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[1]);
 | 
					                part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[1]);
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(part)
 | 
					            if(part)
 | 
				
			||||||
                addOrReplaceIndividualPart(PartTypeList[i].type, -1,1, "meshes\\"+part->mModel);
 | 
					                addOrReplaceIndividualPart(PartTypeList[i].type, -1,1, "meshes\\"+part->mModel);
 | 
				
			||||||
| 
						 | 
					@ -357,27 +316,69 @@ void NpcAnimation::updateParts()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int group, const std::string &bonename)
 | 
					NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int group, const std::string &bonename)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    NifOgre::EntityList entities = NIFLoader::createEntities(mEntityList.mSkelBase, bonename,
 | 
					    NifOgre::EntityList entities = NifOgre::Loader::createEntities(mEntityList.mSkelBase, bonename,
 | 
				
			||||||
                                                             mInsert, mesh);
 | 
					                                                                   mInsert, mesh);
 | 
				
			||||||
    std::vector<Ogre::Entity*> &parts = entities.mEntities;
 | 
					    std::vector<Ogre::Entity*> &parts = entities.mEntities;
 | 
				
			||||||
    for(size_t i = 0;i < parts.size();i++)
 | 
					    for(size_t i = 0;i < parts.size();i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
 | 
				
			||||||
        parts[i]->setVisibilityFlags(mVisibilityFlags);
 | 
					        parts[i]->setVisibilityFlags(mVisibilityFlags);
 | 
				
			||||||
        parts[i]->getUserObjectBindings ().setUserAny (Ogre::Any(group));
 | 
					
 | 
				
			||||||
 | 
					        bool transparent = false;
 | 
				
			||||||
 | 
					        for(unsigned int j=0;!transparent && j < parts[i]->getNumSubEntities();++j)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Ogre::MaterialPtr mat = parts[i]->getSubEntity(j)->getMaterial();
 | 
				
			||||||
 | 
					            Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
 | 
				
			||||||
 | 
					            while(!transparent && techIt.hasMoreElements())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Ogre::Technique* tech = techIt.getNext();
 | 
				
			||||||
 | 
					                Ogre::Technique::PassIterator passIt = tech->getPassIterator();
 | 
				
			||||||
 | 
					                while(!transparent && passIt.hasMoreElements())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Ogre::Pass* pass = passIt.getNext();
 | 
				
			||||||
 | 
					                    transparent = pass->isTransparent();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        parts[i]->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(entities.mSkelBase)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Ogre::AnimationStateSet *aset = entities.mSkelBase->getAllAnimationStates();
 | 
				
			||||||
 | 
					        Ogre::AnimationStateIterator asiter = aset->getAnimationStateIterator();
 | 
				
			||||||
 | 
					        while(asiter.hasMoreElements())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Ogre::AnimationState *state = asiter.getNext();
 | 
				
			||||||
 | 
					            state->setEnabled(false);
 | 
				
			||||||
 | 
					            state->setLoop(false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Ogre::SkeletonInstance *skelinst = entities.mSkelBase->getSkeleton();
 | 
				
			||||||
 | 
					        Ogre::Skeleton::BoneIterator boneiter = skelinst->getBoneIterator();
 | 
				
			||||||
 | 
					        while(boneiter.hasMoreElements())
 | 
				
			||||||
 | 
					            boneiter.getNext()->setManuallyControlled(true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return entities;
 | 
					    return entities;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NpcAnimation::runAnimation(float timepassed)
 | 
					Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if(mTimeToChange > .2)
 | 
					    if(mTimeToChange <= 0.0f)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mTimeToChange = 0;
 | 
					        mTimeToChange = 0.2f;
 | 
				
			||||||
        updateParts();
 | 
					        updateParts();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mTimeToChange += timepassed;
 | 
					    mTimeToChange -= timepassed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Animation::runAnimation(timepassed);
 | 
					    Ogre::Vector3 ret = Animation::runAnimation(timepassed);
 | 
				
			||||||
 | 
					    const Ogre::SkeletonInstance *skelsrc = mEntityList.mSkelBase->getSkeleton();
 | 
				
			||||||
 | 
					    for(size_t i = 0;i < sPartListSize;i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Ogre::Entity *ent = mEntityParts[i].mSkelBase;
 | 
				
			||||||
 | 
					        if(!ent) continue;
 | 
				
			||||||
 | 
					        updateSkeletonInstance(skelsrc, ent->getSkeleton());
 | 
				
			||||||
 | 
					        ent->getAllAnimationStates()->_notifyDirty();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NpcAnimation::removeEntities(NifOgre::EntityList &entities)
 | 
					void NpcAnimation::removeEntities(NifOgre::EntityList &entities)
 | 
				
			||||||
| 
						 | 
					@ -399,62 +400,14 @@ void NpcAnimation::removeIndividualPart(int type)
 | 
				
			||||||
    mPartPriorities[type] = 0;
 | 
					    mPartPriorities[type] = 0;
 | 
				
			||||||
    mPartslots[type] = -1;
 | 
					    mPartslots[type] = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(type == ESM::PRT_Head)   //0
 | 
					    for(size_t i = 0;i < sPartListSize;i++)
 | 
				
			||||||
        removeEntities(mHead);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_Hair) //1
 | 
					 | 
				
			||||||
        removeEntities(mHair);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_Neck) //2
 | 
					 | 
				
			||||||
        removeEntities(mNeck);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_Cuirass)//3
 | 
					 | 
				
			||||||
        removeEntities(mChest);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_Groin)//4
 | 
					 | 
				
			||||||
        removeEntities(mGroin);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_Skirt)//5
 | 
					 | 
				
			||||||
        removeEntities(mSkirt);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_RHand)//6
 | 
					 | 
				
			||||||
        removeEntities(mHandR);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_LHand)//7
 | 
					 | 
				
			||||||
        removeEntities(mHandL);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_RWrist)//8
 | 
					 | 
				
			||||||
        removeEntities(mWristR);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_LWrist) //9
 | 
					 | 
				
			||||||
        removeEntities(mWristL);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_Shield) //10
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        if(type == sPartList[i].type)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            removeEntities(mEntityParts[i]);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if(type == ESM::PRT_RForearm) //11
 | 
					 | 
				
			||||||
        removeEntities(mForearmR);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_LForearm) //12
 | 
					 | 
				
			||||||
        removeEntities(mForearmL);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_RUpperarm) //13
 | 
					 | 
				
			||||||
        removeEntities(mUpperArmR);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_LUpperarm) //14
 | 
					 | 
				
			||||||
        removeEntities(mUpperArmL);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_RFoot)                 //15
 | 
					 | 
				
			||||||
        removeEntities(mFootR);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_LFoot)                //16
 | 
					 | 
				
			||||||
        removeEntities(mFootL);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_RAnkle)    //17
 | 
					 | 
				
			||||||
        removeEntities(mAnkleR);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_LAnkle)    //18
 | 
					 | 
				
			||||||
        removeEntities(mAnkleL);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_RKnee)    //19
 | 
					 | 
				
			||||||
        removeEntities(mKneeR);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_LKnee)    //20
 | 
					 | 
				
			||||||
        removeEntities(mKneeL);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_RLeg)    //21
 | 
					 | 
				
			||||||
        removeEntities(mUpperLegR);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_LLeg)    //22
 | 
					 | 
				
			||||||
        removeEntities(mUpperLegL);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_RPauldron)    //23
 | 
					 | 
				
			||||||
        removeEntities(mClavicleR);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_LPauldron)    //24
 | 
					 | 
				
			||||||
        removeEntities(mClavicleL);
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_Weapon)                 //25
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if(type == ESM::PRT_Tail)    //26
 | 
					 | 
				
			||||||
        removeEntities(mTail);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NpcAnimation::reserveIndividualPart(int type, int group, int priority)
 | 
					void NpcAnimation::reserveIndividualPart(int type, int group, int priority)
 | 
				
			||||||
| 
						 | 
					@ -484,96 +437,23 @@ bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority,
 | 
				
			||||||
    removeIndividualPart(type);
 | 
					    removeIndividualPart(type);
 | 
				
			||||||
    mPartslots[type] = group;
 | 
					    mPartslots[type] = group;
 | 
				
			||||||
    mPartPriorities[type] = priority;
 | 
					    mPartPriorities[type] = priority;
 | 
				
			||||||
    switch(type)
 | 
					
 | 
				
			||||||
 | 
					    for(size_t i = 0;i < sPartListSize;i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        case ESM::PRT_Head:                           //0
 | 
					        if(type == sPartList[i].type)
 | 
				
			||||||
            mHead = insertBoundedPart(mesh, group, "Head");
 | 
					        {
 | 
				
			||||||
            break;
 | 
					            mEntityParts[i] = insertBoundedPart(mesh, group, sPartList[i].name);
 | 
				
			||||||
        case ESM::PRT_Hair:                          //1
 | 
					 | 
				
			||||||
            mHair = insertBoundedPart(mesh, group, "Head");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_Neck:                          //2
 | 
					 | 
				
			||||||
            mNeck = insertBoundedPart(mesh, group, "Neck");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_Cuirass:                          //3
 | 
					 | 
				
			||||||
            mChest = insertBoundedPart(mesh, group, "Chest");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_Groin:                          //4
 | 
					 | 
				
			||||||
            mGroin = insertBoundedPart(mesh, group, "Groin");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_Skirt:                          //5
 | 
					 | 
				
			||||||
            mSkirt = insertBoundedPart(mesh, group, "Groin");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_RHand:                         //6
 | 
					 | 
				
			||||||
            mHandR = insertBoundedPart(mesh, group, "Right Hand");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_LHand:                         //7
 | 
					 | 
				
			||||||
            mHandL = insertBoundedPart(mesh, group, "Left Hand");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_RWrist:                          //8
 | 
					 | 
				
			||||||
            mWristR = insertBoundedPart(mesh, group, "Right Wrist");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_LWrist:                          //9
 | 
					 | 
				
			||||||
            mWristL = insertBoundedPart(mesh, group, "Left Wrist");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_Shield:                         //10
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_RForearm:                          //11
 | 
					 | 
				
			||||||
            mForearmR = insertBoundedPart(mesh, group, "Right Forearm");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_LForearm:                          //12
 | 
					 | 
				
			||||||
            mForearmL = insertBoundedPart(mesh, group, "Left Forearm");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_RUpperarm:                          //13
 | 
					 | 
				
			||||||
            mUpperArmR = insertBoundedPart(mesh, group, "Right Upper Arm");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_LUpperarm:                          //14
 | 
					 | 
				
			||||||
            mUpperArmL = insertBoundedPart(mesh, group, "Left Upper Arm");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_RFoot:                             //15
 | 
					 | 
				
			||||||
            mFootR = insertBoundedPart(mesh, group, "Right Foot");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_LFoot:                             //16
 | 
					 | 
				
			||||||
            mFootL = insertBoundedPart(mesh, group, "Left Foot");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_RAnkle:                          //17
 | 
					 | 
				
			||||||
            mAnkleR = insertBoundedPart(mesh, group, "Right Ankle");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_LAnkle:                          //18
 | 
					 | 
				
			||||||
            mAnkleL = insertBoundedPart(mesh, group, "Left Ankle");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_RKnee:                          //19
 | 
					 | 
				
			||||||
            mKneeR = insertBoundedPart(mesh, group, "Right Knee");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_LKnee:                          //20
 | 
					 | 
				
			||||||
            mKneeL = insertBoundedPart(mesh, group, "Left Knee");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_RLeg:                          //21
 | 
					 | 
				
			||||||
            mUpperLegR = insertBoundedPart(mesh, group, "Right Upper Leg");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_LLeg:                          //22
 | 
					 | 
				
			||||||
            mUpperLegL = insertBoundedPart(mesh, group, "Left Upper Leg");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_RPauldron:                          //23
 | 
					 | 
				
			||||||
            mClavicleR = insertBoundedPart(mesh , group, "Right Clavicle");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_LPauldron:                          //24
 | 
					 | 
				
			||||||
            mClavicleL = insertBoundedPart(mesh, group, "Left Clavicle");
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_Weapon:                             //25
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case ESM::PRT_Tail:                              //26
 | 
					 | 
				
			||||||
            mTail = insertBoundedPart(mesh, group, "Tail");
 | 
					 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NpcAnimation::addPartGroup(int group, int priority, std::vector<ESM::PartReference> &parts)
 | 
					void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    for(std::size_t i = 0; i < parts.size(); i++)
 | 
					    for(std::size_t i = 0; i < parts.size(); i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ESM::PartReference &part = parts[i];
 | 
					        const ESM::PartReference &part = parts[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const MWWorld::Store<ESM::BodyPart> &partStore =
 | 
					        const MWWorld::Store<ESM::BodyPart> &partStore =
 | 
				
			||||||
            MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
 | 
					            MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
 | 
				
			||||||
| 
						 | 
					@ -585,15 +465,10 @@ void NpcAnimation::addPartGroup(int group, int priority, std::vector<ESM::PartRe
 | 
				
			||||||
            bodypart = partStore.search(part.mMale);
 | 
					            bodypart = partStore.search(part.mMale);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(bodypart)
 | 
					        if(bodypart)
 | 
				
			||||||
            addOrReplaceIndividualPart(part.mPart, group, priority,"meshes\\" + bodypart->mModel);
 | 
					            addOrReplaceIndividualPart(part.mPart, group, priority, "meshes\\"+bodypart->mModel);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            reserveIndividualPart(part.mPart, group, priority);
 | 
					            reserveIndividualPart(part.mPart, group, priority);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NpcAnimation::forceUpdate ()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    updateParts();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,9 +3,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "animation.hpp"
 | 
					#include "animation.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "components/nifogre/ogre_nif_loader.hpp"
 | 
					 | 
				
			||||||
#include "../mwworld/inventorystore.hpp"
 | 
					 | 
				
			||||||
#include "../mwclass/npc.hpp"
 | 
					 | 
				
			||||||
#include "../mwworld/containerstore.hpp"
 | 
					#include "../mwworld/containerstore.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ESM
 | 
					namespace ESM
 | 
				
			||||||
| 
						 | 
					@ -13,49 +10,36 @@ namespace ESM
 | 
				
			||||||
    struct NPC;
 | 
					    struct NPC;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWRender{
 | 
					namespace MWWorld
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class InventoryStore;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWRender
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NpcAnimation : public Animation
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					struct PartInfo {
 | 
				
			||||||
 | 
					    ESM::PartReferenceType type;
 | 
				
			||||||
 | 
					    const char name[32];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NpcAnimation: public Animation{
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    MWWorld::InventoryStore& mInv;
 | 
					    static const size_t sPartListSize = 27;
 | 
				
			||||||
 | 
					    static const PartInfo sPartList[sPartListSize];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int mStateID;
 | 
					    int mStateID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int mPartslots[27];  //Each part slot is taken by clothing, armor, or is empty
 | 
					    // Bounded Parts
 | 
				
			||||||
    int mPartPriorities[27];
 | 
					    NifOgre::EntityList mEntityParts[sPartListSize];
 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Bounded Parts
 | 
					 | 
				
			||||||
    NifOgre::EntityList mClavicleL;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mClavicleR;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mUpperArmL;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mUpperArmR;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mUpperLegL;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mUpperLegR;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mForearmL;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mForearmR;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mWristL;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mWristR;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mKneeR;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mKneeL;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mNeck;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mAnkleL;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mAnkleR;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mGroin;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mSkirt;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mFootL;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mFootR;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mHair;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mHandL;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mHandR;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mHead;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mChest;
 | 
					 | 
				
			||||||
    NifOgre::EntityList mTail;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const ESM::NPC  *mNpc;
 | 
					    const ESM::NPC  *mNpc;
 | 
				
			||||||
    std::string     mHeadModel;
 | 
					    std::string     mHeadModel;
 | 
				
			||||||
    std::string     mHairModel;
 | 
					    std::string     mHairModel;
 | 
				
			||||||
    std::string     mBodyPrefix;
 | 
					    std::string     mBodyPrefix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    float mTimeToChange;
 | 
					    float mTimeToChange;
 | 
				
			||||||
    MWWorld::ContainerStoreIterator mRobe;
 | 
					    MWWorld::ContainerStoreIterator mRobe;
 | 
				
			||||||
    MWWorld::ContainerStoreIterator mHelmet;
 | 
					    MWWorld::ContainerStoreIterator mHelmet;
 | 
				
			||||||
| 
						 | 
					@ -72,23 +56,32 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int mVisibilityFlags;
 | 
					    int mVisibilityFlags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					    int mPartslots[sPartListSize];  //Each part slot is taken by clothing, armor, or is empty
 | 
				
			||||||
    NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node,
 | 
					    int mPartPriorities[sPartListSize];
 | 
				
			||||||
                 MWWorld::InventoryStore& inv, int visibilityFlags);
 | 
					
 | 
				
			||||||
    virtual ~NpcAnimation();
 | 
					 | 
				
			||||||
    NifOgre::EntityList insertBoundedPart(const std::string &mesh, int group, const std::string &bonename);
 | 
					    NifOgre::EntityList insertBoundedPart(const std::string &mesh, int group, const std::string &bonename);
 | 
				
			||||||
    virtual void runAnimation(float timepassed);
 | 
					
 | 
				
			||||||
    void updateParts();
 | 
					    void updateParts(bool forceupdate = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void removeEntities(NifOgre::EntityList &entities);
 | 
					    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, const std::vector<ESM::PartReference> &parts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void forceUpdate();
 | 
					public:
 | 
				
			||||||
 | 
					    NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node,
 | 
				
			||||||
 | 
					                 MWWorld::InventoryStore& inv, int visibilityFlags);
 | 
				
			||||||
 | 
					    virtual ~NpcAnimation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual Ogre::Vector3 runAnimation(float timepassed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void forceUpdate()
 | 
				
			||||||
 | 
					    { updateParts(true); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,19 +34,37 @@ void Objects::clearSceneNode (Ogre::SceneNode *node)
 | 
				
			||||||
    for (int i=node->numAttachedObjects()-1; i>=0; --i)
 | 
					    for (int i=node->numAttachedObjects()-1; i>=0; --i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ogre::MovableObject *object = node->getAttachedObject (i);
 | 
					        Ogre::MovableObject *object = node->getAttachedObject (i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // for entities, destroy any objects attached to bones
 | 
				
			||||||
 | 
					        if (object->getTypeFlags () == Ogre::SceneManager::ENTITY_TYPE_MASK)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Ogre::Entity* ent = static_cast<Ogre::Entity*>(object);
 | 
				
			||||||
 | 
					            Ogre::Entity::ChildObjectListIterator children = ent->getAttachedObjectIterator ();
 | 
				
			||||||
 | 
					            while (children.hasMoreElements())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                mRenderer.getScene ()->destroyMovableObject (children.getNext ());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        node->detachObject (object);
 | 
					        node->detachObject (object);
 | 
				
			||||||
        mRenderer.getScene()->destroyMovableObject (object);
 | 
					        mRenderer.getScene()->destroyMovableObject (object);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ogre::Node::ChildNodeIterator it = node->getChildIterator ();
 | 
				
			||||||
 | 
					    while (it.hasMoreElements ())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        clearSceneNode(static_cast<Ogre::SceneNode*>(it.getNext ()));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Objects::setMwRoot(Ogre::SceneNode* root)
 | 
					void Objects::setRootNode(Ogre::SceneNode* root)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mMwRoot = root;
 | 
					    mRootNode = root;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
 | 
					void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Ogre::SceneNode* root = mMwRoot;
 | 
					    Ogre::SceneNode* root = mRootNode;
 | 
				
			||||||
    Ogre::SceneNode* cellnode;
 | 
					    Ogre::SceneNode* cellnode;
 | 
				
			||||||
    if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
 | 
					    if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -87,20 +105,16 @@ void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
 | 
				
			||||||
    mIsStatic = static_;
 | 
					    mIsStatic = static_;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
 | 
					void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
 | 
					    Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
 | 
				
			||||||
    assert(insert);
 | 
					    assert(insert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
 | 
					    Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
 | 
				
			||||||
    NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(insert, NULL, mesh);
 | 
					    NifOgre::EntityList entities = NifOgre::Loader::createEntities(insert, mesh);
 | 
				
			||||||
    for(size_t i = 0;i < entities.mEntities.size();i++)
 | 
					    for(size_t i = 0;i < entities.mEntities.size();i++)
 | 
				
			||||||
    {
 | 
					        bounds.merge(entities.mEntities[i]->getWorldBoundingBox(true));
 | 
				
			||||||
        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();
 | 
					    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);
 | 
				
			||||||
| 
						 | 
					@ -116,23 +130,21 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
 | 
				
			||||||
    mBounds[ptr.getCell()].merge(bounds);
 | 
					    mBounds[ptr.getCell()].merge(bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool transparent = false;
 | 
					    bool transparent = false;
 | 
				
			||||||
    for(size_t i = 0;i < entities.mEntities.size();i++)
 | 
					    for(size_t i = 0;!transparent && i < entities.mEntities.size();i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ogre::Entity *ent = entities.mEntities[i];
 | 
					        Ogre::Entity *ent = entities.mEntities[i];
 | 
				
			||||||
        for (unsigned int i=0; i<ent->getNumSubEntities(); ++i)
 | 
					        for(unsigned int i=0;!transparent && i < ent->getNumSubEntities(); ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial();
 | 
					            Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial();
 | 
				
			||||||
            Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
 | 
					            Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
 | 
				
			||||||
            while (techIt.hasMoreElements())
 | 
					            while(!transparent && techIt.hasMoreElements())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Ogre::Technique* tech = techIt.getNext();
 | 
					                Ogre::Technique* tech = techIt.getNext();
 | 
				
			||||||
                Ogre::Technique::PassIterator passIt = tech->getPassIterator();
 | 
					                Ogre::Technique::PassIterator passIt = tech->getPassIterator();
 | 
				
			||||||
                while (passIt.hasMoreElements())
 | 
					                while(!transparent && passIt.hasMoreElements())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Ogre::Pass* pass = passIt.getNext();
 | 
					                    Ogre::Pass* pass = passIt.getNext();
 | 
				
			||||||
 | 
					                    transparent = pass->isTransparent();
 | 
				
			||||||
                    if (pass->getDepthWriteEnabled() == false)
 | 
					 | 
				
			||||||
                        transparent = true;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -193,26 +205,40 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
 | 
					        sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for(size_t i = 0;i < entities.mEntities.size();i++)
 | 
					        std::vector<Ogre::Entity*>::reverse_iterator iter = entities.mEntities.rbegin();
 | 
				
			||||||
 | 
					        while(iter != entities.mEntities.rend())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Ogre::Entity *ent = entities.mEntities[i];
 | 
					            Ogre::Node *node = (*iter)->getParentNode();
 | 
				
			||||||
            insert->detachObject(ent);
 | 
					            sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale());
 | 
				
			||||||
            sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            mRenderer.getScene()->destroyEntity(ent);
 | 
					            (*iter)->detachFromParent();
 | 
				
			||||||
 | 
					            mRenderer.getScene()->destroyEntity(*iter);
 | 
				
			||||||
 | 
					            iter++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (light)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        insertLight(ptr, entities.mSkelBase, bounds.getCenter() - insert->_getDerivedPosition());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius)
 | 
					void Objects::insertLight (const MWWorld::Ptr& ptr, Ogre::Entity* skelBase, Ogre::Vector3 fallbackCenter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Ogre::SceneNode* insert = mRenderer.getScene()->getSceneNode(ptr.getRefData().getHandle());
 | 
					    Ogre::SceneNode* insert = mRenderer.getScene()->getSceneNode(ptr.getRefData().getHandle());
 | 
				
			||||||
    assert(insert);
 | 
					    assert(insert);
 | 
				
			||||||
    Ogre::Light *light = mRenderer.getScene()->createLight();
 | 
					 | 
				
			||||||
    light->setDiffuseColour (r, g, b);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
 | 
					    MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const int color = ref->mBase->mData.mColor;
 | 
				
			||||||
 | 
					    const float r = ((color >> 0) & 0xFF) / 255.0f;
 | 
				
			||||||
 | 
					    const float g = ((color >> 8) & 0xFF) / 255.0f;
 | 
				
			||||||
 | 
					    const float b = ((color >> 16) & 0xFF) / 255.0f;
 | 
				
			||||||
 | 
					    const float radius = float (ref->mBase->mData.mRadius);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ogre::Light *light = mRenderer.getScene()->createLight();
 | 
				
			||||||
 | 
					    light->setDiffuseColour (r, g, b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LightInfo info;
 | 
					    LightInfo info;
 | 
				
			||||||
    info.name = light->getName();
 | 
					    info.name = light->getName();
 | 
				
			||||||
    info.radius = radius;
 | 
					    info.radius = radius;
 | 
				
			||||||
| 
						 | 
					@ -263,7 +289,17 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f
 | 
				
			||||||
        light->setAttenuation(r*10, 0, 0, attenuation);
 | 
					        light->setAttenuation(r*10, 0, 0, attenuation);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    insert->attachObject(light);
 | 
					    // If there's an AttachLight bone, attach the light to that, otherwise attach it to the base scene node
 | 
				
			||||||
 | 
					    if (skelBase && skelBase->getSkeleton ()->hasBone ("AttachLight"))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        skelBase->attachObjectToBone ("AttachLight", light);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Ogre::SceneNode* childNode = insert->createChildSceneNode (fallbackCenter);
 | 
				
			||||||
 | 
					        childNode->attachObject(light);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mLights.push_back(info);
 | 
					    mLights.push_back(info);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -348,9 +384,9 @@ void Objects::enableLights()
 | 
				
			||||||
    std::vector<LightInfo>::iterator it = mLights.begin();
 | 
					    std::vector<LightInfo>::iterator it = mLights.begin();
 | 
				
			||||||
    while (it != mLights.end())
 | 
					    while (it != mLights.end())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (mMwRoot->getCreator()->hasLight(it->name))
 | 
					        if (mRootNode->getCreator()->hasLight(it->name))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            mMwRoot->getCreator()->getLight(it->name)->setVisible(true);
 | 
					            mRootNode->getCreator()->getLight(it->name)->setVisible(true);
 | 
				
			||||||
            ++it;
 | 
					            ++it;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
| 
						 | 
					@ -363,9 +399,9 @@ void Objects::disableLights()
 | 
				
			||||||
    std::vector<LightInfo>::iterator it = mLights.begin();
 | 
					    std::vector<LightInfo>::iterator it = mLights.begin();
 | 
				
			||||||
    while (it != mLights.end())
 | 
					    while (it != mLights.end())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (mMwRoot->getCreator()->hasLight(it->name))
 | 
					        if (mRootNode->getCreator()->hasLight(it->name))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            mMwRoot->getCreator()->getLight(it->name)->setVisible(false);
 | 
					            mRootNode->getCreator()->getLight(it->name)->setVisible(false);
 | 
				
			||||||
            ++it;
 | 
					            ++it;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
| 
						 | 
					@ -418,9 +454,9 @@ void Objects::update(const float dt)
 | 
				
			||||||
    std::vector<LightInfo>::iterator it = mLights.begin();
 | 
					    std::vector<LightInfo>::iterator it = mLights.begin();
 | 
				
			||||||
    while (it != mLights.end())
 | 
					    while (it != mLights.end())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (mMwRoot->getCreator()->hasLight(it->name))
 | 
					        if (mRootNode->getCreator()->hasLight(it->name))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Ogre::Light* light = mMwRoot->getCreator()->getLight(it->name);
 | 
					            Ogre::Light* light = mRootNode->getCreator()->getLight(it->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            float brightness;
 | 
					            float brightness;
 | 
				
			||||||
            float cycle_time;
 | 
					            float cycle_time;
 | 
				
			||||||
| 
						 | 
					@ -502,21 +538,17 @@ void Objects::rebuildStaticGeometry()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Objects::updateObjectCell(const MWWorld::Ptr &ptr)
 | 
					void Objects::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Ogre::SceneNode *node;
 | 
					    Ogre::SceneNode *node;
 | 
				
			||||||
    MWWorld::CellStore *newCell = ptr.getCell();
 | 
					    MWWorld::CellStore *newCell = cur.getCell();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) {
 | 
					    if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) {
 | 
				
			||||||
        node = mMwRoot->createChildSceneNode();
 | 
					        node = mRootNode->createChildSceneNode();
 | 
				
			||||||
        mCellSceneNodes[newCell] = node;
 | 
					        mCellSceneNodes[newCell] = node;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        node = mCellSceneNodes[newCell];
 | 
					        node = mCellSceneNodes[newCell];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    node->addChild(ptr.getRefData().getBaseNode());
 | 
					    node->addChild(cur.getRefData().getBaseNode());
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// \note Still unaware how to move aabb and static w/o full rebuild,
 | 
					 | 
				
			||||||
    /// moving static objects may cause problems
 | 
					 | 
				
			||||||
    insertMesh(ptr, MWWorld::Class::get(ptr).getModel(ptr));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
#define _GAME_RENDER_OBJECTS_H
 | 
					#define _GAME_RENDER_OBJECTS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <OgreColourValue.h>
 | 
					#include <OgreColourValue.h>
 | 
				
			||||||
 | 
					#include <OgreAxisAlignedBox.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <openengine/ogre/renderer.hpp>
 | 
					#include <openengine/ogre/renderer.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +53,7 @@ class Objects{
 | 
				
			||||||
    std::map<MWWorld::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall;
 | 
					    std::map<MWWorld::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall;
 | 
				
			||||||
    std::map<MWWorld::CellStore *, Ogre::AxisAlignedBox> mBounds;
 | 
					    std::map<MWWorld::CellStore *, Ogre::AxisAlignedBox> mBounds;
 | 
				
			||||||
    std::vector<LightInfo> mLights;
 | 
					    std::vector<LightInfo> mLights;
 | 
				
			||||||
    Ogre::SceneNode* mMwRoot;
 | 
					    Ogre::SceneNode* mRootNode;
 | 
				
			||||||
    bool mIsStatic;
 | 
					    bool mIsStatic;
 | 
				
			||||||
    static int uniqueID;
 | 
					    static int uniqueID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,8 +73,8 @@ public:
 | 
				
			||||||
    Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer), mIsStatic(false) {}
 | 
					    Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer), mIsStatic(false) {}
 | 
				
			||||||
    ~Objects(){}
 | 
					    ~Objects(){}
 | 
				
			||||||
    void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
 | 
					    void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
 | 
				
			||||||
    void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);
 | 
					    void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light=false);
 | 
				
			||||||
    void insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius);
 | 
					    void insertLight (const MWWorld::Ptr& ptr, Ogre::Entity *skelBase=0, Ogre::Vector3 fallbackCenter=Ogre::Vector3(0.0f));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void enableLights();
 | 
					    void enableLights();
 | 
				
			||||||
    void disableLights();
 | 
					    void disableLights();
 | 
				
			||||||
| 
						 | 
					@ -89,12 +90,12 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void removeCell(MWWorld::CellStore* store);
 | 
					    void removeCell(MWWorld::CellStore* store);
 | 
				
			||||||
    void buildStaticGeometry(MWWorld::CellStore &cell);
 | 
					    void buildStaticGeometry(MWWorld::CellStore &cell);
 | 
				
			||||||
    void setMwRoot(Ogre::SceneNode* root);
 | 
					    void setRootNode(Ogre::SceneNode* root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void rebuildStaticGeometry();
 | 
					    void rebuildStaticGeometry();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Updates containing cell for object rendering data
 | 
					    /// Updates containing cell for object rendering data
 | 
				
			||||||
    void updateObjectCell(const MWWorld::Ptr &ptr);
 | 
					    void updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,11 +113,6 @@ namespace MWRender
 | 
				
			||||||
        Ogre::Vector3 dir = mCamera->getRealDirection();
 | 
					        Ogre::Vector3 dir = mCamera->getRealDirection();
 | 
				
			||||||
        Ogre::Vector3 up  = mCamera->getRealUp();
 | 
					        Ogre::Vector3 up  = mCamera->getRealUp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ogre::Real xch;
 | 
					 | 
				
			||||||
        xch = pos.y, pos.y = -pos.z, pos.z = xch;
 | 
					 | 
				
			||||||
        xch = dir.y, dir.y = -dir.z, dir.z = xch;
 | 
					 | 
				
			||||||
        xch = up.y,  up.y  = -up.z,  up.z = xch;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir, up);
 | 
					        MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir, up);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,14 +124,8 @@ namespace MWRender
 | 
				
			||||||
        MWBase::Environment::get().getWindowManager ()->showCrosshair
 | 
					        MWBase::Environment::get().getWindowManager ()->showCrosshair
 | 
				
			||||||
                (!MWBase::Environment::get().getWindowManager ()->isGuiMode () && (mFirstPersonView && !mVanity.enabled && !mPreviewMode));
 | 
					                (!MWBase::Environment::get().getWindowManager ()->isGuiMode () && (mFirstPersonView && !mVanity.enabled && !mPreviewMode));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (mAnimation) {
 | 
					        /// \fixme We shouldn't hide the whole model, just certain components of the character (head, chest, feet, etc)
 | 
				
			||||||
            mAnimation->runAnimation(duration);
 | 
					        mPlayerNode->setVisible(mVanity.enabled || mPreviewMode || !mFirstPersonView);
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        mPlayerNode->setVisible(
 | 
					 | 
				
			||||||
            mVanity.enabled || mPreviewMode || !mFirstPersonView,
 | 
					 | 
				
			||||||
            false
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (mFirstPersonView && !mVanity.enabled) {
 | 
					        if (mFirstPersonView && !mVanity.enabled) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -313,10 +302,7 @@ namespace MWRender
 | 
				
			||||||
        delete mAnimation;
 | 
					        delete mAnimation;
 | 
				
			||||||
        mAnimation = anim;
 | 
					        mAnimation = anim;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mPlayerNode->setVisible(
 | 
					        mPlayerNode->setVisible(mVanity.enabled || mPreviewMode || !mFirstPersonView);
 | 
				
			||||||
            mVanity.enabled || mPreviewMode || !mFirstPersonView,
 | 
					 | 
				
			||||||
            false
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Player::setHeight(float height)
 | 
					    void Player::setHeight(float height)
 | 
				
			||||||
| 
						 | 
					@ -332,10 +318,8 @@ namespace MWRender
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera)
 | 
					    bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        float xch;
 | 
					 | 
				
			||||||
        mCamera->getParentSceneNode ()->needUpdate(true);
 | 
					        mCamera->getParentSceneNode ()->needUpdate(true);
 | 
				
			||||||
        camera = mCamera->getRealPosition();
 | 
					        camera = mCamera->getRealPosition();
 | 
				
			||||||
        xch = camera.z, camera.z = camera.y, camera.y = -xch;
 | 
					 | 
				
			||||||
        player = mPlayerNode->getPosition();
 | 
					        player = mPlayerNode->getPosition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return mFirstPersonView && !mVanity.enabled && !mPreviewMode;
 | 
					        return mFirstPersonView && !mVanity.enabled && !mPreviewMode;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,7 +95,9 @@ namespace MWRender
 | 
				
			||||||
        /// Restore default camera distance for current mode.
 | 
					        /// Restore default camera distance for current mode.
 | 
				
			||||||
        void setCameraDistance();
 | 
					        void setCameraDistance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void setAnimation(MWRender::NpcAnimation *anim);
 | 
					        void setAnimation(NpcAnimation *anim);
 | 
				
			||||||
 | 
					        NpcAnimation *getAnimation() const
 | 
				
			||||||
 | 
					        { return mAnimation; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void setHeight(float height);
 | 
					        void setHeight(float height);
 | 
				
			||||||
        float getHeight();
 | 
					        float getHeight();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,9 +18,12 @@
 | 
				
			||||||
#include <extern/shiny/Main/Factory.hpp>
 | 
					#include <extern/shiny/Main/Factory.hpp>
 | 
				
			||||||
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
 | 
					#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openengine/bullet/physic.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <components/esm/loadstat.hpp>
 | 
					#include <components/esm/loadstat.hpp>
 | 
				
			||||||
#include "../mwworld/esmstore.hpp"
 | 
					 | 
				
			||||||
#include <components/settings/settings.hpp>
 | 
					#include <components/settings/settings.hpp>
 | 
				
			||||||
 | 
					#include "../mwworld/esmstore.hpp"
 | 
				
			||||||
 | 
					#include "../mwworld/class.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone
 | 
					#include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone
 | 
				
			||||||
#include "../mwbase/environment.hpp"
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
| 
						 | 
					@ -138,26 +141,20 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    applyCompositors();
 | 
					    applyCompositors();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Turn the entire scene (represented by the 'root' node) -90
 | 
					 | 
				
			||||||
    // degrees around the x axis. This makes Z go upwards, and Y go into
 | 
					 | 
				
			||||||
    // the screen (when x is to the right.) This is the orientation that
 | 
					 | 
				
			||||||
    // Morrowind uses, and it automagically makes everything work as it
 | 
					 | 
				
			||||||
    // should.
 | 
					 | 
				
			||||||
    SceneNode *rt = mRendering.getScene()->getRootSceneNode();
 | 
					    SceneNode *rt = mRendering.getScene()->getRootSceneNode();
 | 
				
			||||||
    mMwRoot = rt->createChildSceneNode("mwRoot");
 | 
					    mRootNode = rt;
 | 
				
			||||||
    mMwRoot->pitch(Degree(-90));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mObjects.setMwRoot(mMwRoot);
 | 
					    mObjects.setRootNode(mRootNode);
 | 
				
			||||||
    mActors.setMwRoot(mMwRoot);
 | 
					    mActors.setRootNode(mRootNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player");
 | 
					    Ogre::SceneNode *playerNode = mRootNode->createChildSceneNode ("player");
 | 
				
			||||||
    mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
 | 
					    mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mShadows = new Shadows(&mRendering);
 | 
					    mShadows = new Shadows(&mRendering);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mTerrainManager = new TerrainManager(mRendering.getScene(), this);
 | 
					    mTerrainManager = new TerrainManager(mRendering.getScene(), this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera());
 | 
					    mSkyManager = new SkyManager(mRootNode, mRendering.getCamera());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
 | 
					    mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,7 +163,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mSun = 0;
 | 
					    mSun = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mDebugging = new Debugging(mMwRoot, engine);
 | 
					    mDebugging = new Debugging(mRootNode, engine);
 | 
				
			||||||
    mLocalMap = new MWRender::LocalMap(&mRendering, this);
 | 
					    mLocalMap = new MWRender::LocalMap(&mRendering, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
 | 
					    setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
 | 
				
			||||||
| 
						 | 
					@ -252,8 +249,7 @@ void RenderingManager::removeObject (const MWWorld::Ptr& ptr)
 | 
				
			||||||
void RenderingManager::moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position)
 | 
					void RenderingManager::moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /// \todo move this to the rendering-subsystems
 | 
					    /// \todo move this to the rendering-subsystems
 | 
				
			||||||
    mRendering.getScene()->getSceneNode (ptr.getRefData().getHandle())->
 | 
					    ptr.getRefData().getBaseNode()->setPosition(position);
 | 
				
			||||||
            setPosition (position);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale)
 | 
					void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale)
 | 
				
			||||||
| 
						 | 
					@ -300,23 +296,19 @@ bool RenderingManager::rotateObject( const MWWorld::Ptr &ptr, Ogre::Vector3 &rot
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
RenderingManager::moveObjectToCell(
 | 
					RenderingManager::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
 | 
				
			||||||
    const MWWorld::Ptr& ptr,
 | 
					 | 
				
			||||||
    const Ogre::Vector3& pos,
 | 
					 | 
				
			||||||
    MWWorld::CellStore *store)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Ogre::SceneNode *child =
 | 
					    Ogre::SceneNode *child =
 | 
				
			||||||
        mRendering.getScene()->getSceneNode(ptr.getRefData().getHandle());
 | 
					        mRendering.getScene()->getSceneNode(old.getRefData().getHandle());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ogre::SceneNode *parent = child->getParentSceneNode();
 | 
					    Ogre::SceneNode *parent = child->getParentSceneNode();
 | 
				
			||||||
    parent->removeChild(child);
 | 
					    parent->removeChild(child);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (MWWorld::Class::get(ptr).isActor()) {
 | 
					    if (MWWorld::Class::get(old).isActor()) {
 | 
				
			||||||
        mActors.updateObjectCell(ptr);
 | 
					        mActors.updateObjectCell(old, cur);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        mObjects.updateObjectCell(ptr);
 | 
					        mObjects.updateObjectCell(old, cur);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    child->setPosition(pos);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RenderingManager::update (float duration, bool paused)
 | 
					void RenderingManager::update (float duration, bool paused)
 | 
				
			||||||
| 
						 | 
					@ -324,7 +316,7 @@ void RenderingManager::update (float duration, bool paused)
 | 
				
			||||||
    Ogre::Vector3 orig, dest;
 | 
					    Ogre::Vector3 orig, dest;
 | 
				
			||||||
    mPlayer->setCameraDistance();
 | 
					    mPlayer->setCameraDistance();
 | 
				
			||||||
    if (!mPlayer->getPosition(orig, dest)) {
 | 
					    if (!mPlayer->getPosition(orig, dest)) {
 | 
				
			||||||
        orig.z += mPlayer->getHeight() * mMwRoot->getScale().z;
 | 
					        orig.z += mPlayer->getHeight() * mRootNode->getScale().z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        btVector3 btOrig(orig.x, orig.y, orig.z);
 | 
					        btVector3 btOrig(orig.x, orig.y, orig.z);
 | 
				
			||||||
        btVector3 btDest(dest.x, dest.y, dest.z);
 | 
					        btVector3 btDest(dest.x, dest.y, dest.z);
 | 
				
			||||||
| 
						 | 
					@ -368,11 +360,13 @@ void RenderingManager::update (float duration, bool paused)
 | 
				
			||||||
    float *fpos = data.getPosition().pos;
 | 
					    float *fpos = data.getPosition().pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // only for LocalMap::updatePlayer()
 | 
					    // only for LocalMap::updatePlayer()
 | 
				
			||||||
    Ogre::Vector3 pos(fpos[0], -fpos[2], -fpos[1]);
 | 
					    Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ogre::SceneNode *node = data.getBaseNode();
 | 
					    Ogre::SceneNode *node = data.getBaseNode();
 | 
				
			||||||
 | 
					    //Ogre::Quaternion orient =
 | 
				
			||||||
 | 
					        //node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
 | 
				
			||||||
    Ogre::Quaternion orient =
 | 
					    Ogre::Quaternion orient =
 | 
				
			||||||
        node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
 | 
					node->_getDerivedOrientation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mLocalMap->updatePlayer(pos, orient);
 | 
					    mLocalMap->updatePlayer(pos, orient);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -383,8 +377,8 @@ void RenderingManager::update (float duration, bool paused)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mWater->updateUnderwater(
 | 
					        mWater->updateUnderwater(
 | 
				
			||||||
            world->isUnderwater(
 | 
					            world->isUnderwater(
 | 
				
			||||||
                *world->getPlayer().getPlayer().getCell()->mCell,
 | 
					                world->getPlayer().getPlayer().getCell(),
 | 
				
			||||||
                Ogre::Vector3(cam.x, -cam.z, cam.y))
 | 
					                cam)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        mWater->update(duration);
 | 
					        mWater->update(duration);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -580,17 +574,6 @@ void RenderingManager::toggleLight()
 | 
				
			||||||
    setAmbientMode();
 | 
					    setAmbientMode();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RenderingManager::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName,
 | 
					 | 
				
			||||||
     int mode, int number)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    mActors.playAnimationGroup(ptr, groupName, mode, number);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    mActors.skipAnimation(ptr);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void RenderingManager::setSunColour(const Ogre::ColourValue& colour)
 | 
					void RenderingManager::setSunColour(const Ogre::ColourValue& colour)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!mSunEnabled) return;
 | 
					    if (!mSunEnabled) return;
 | 
				
			||||||
| 
						 | 
					@ -627,8 +610,7 @@ void RenderingManager::sunDisable()
 | 
				
			||||||
void RenderingManager::setSunDirection(const Ogre::Vector3& direction)
 | 
					void RenderingManager::setSunDirection(const Ogre::Vector3& direction)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // direction * -1 (because 'direction' is camera to sun vector and not sun to camera),
 | 
					    // direction * -1 (because 'direction' is camera to sun vector and not sun to camera),
 | 
				
			||||||
    // then convert from MW to ogre coordinates (swap y,z and make y negative)
 | 
					    if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.y, -direction.z));
 | 
				
			||||||
    if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.z, direction.y));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mSkyManager->setSunDirection(direction);
 | 
					    mSkyManager->setSunDirection(direction);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -929,6 +911,15 @@ void RenderingManager::setupExternalRendering (MWRender::ExternalRendering& rend
 | 
				
			||||||
    rendering.setup (mRendering.getScene());
 | 
					    rendering.setup (mRendering.getScene());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Animation* RenderingManager::getAnimation(const MWWorld::Ptr &ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Animation *anim = mActors.getAnimation(ptr);
 | 
				
			||||||
 | 
					    if(!anim && ptr.getRefData().getHandle() == "player")
 | 
				
			||||||
 | 
					        anim = mPlayer->getAnimation();
 | 
				
			||||||
 | 
					    return anim;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RenderingManager::playVideo(const std::string& name, bool allowSkipping)
 | 
					void RenderingManager::playVideo(const std::string& name, bool allowSkipping)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mVideoPlayer->playVideo ("video/" + name, allowSkipping);
 | 
					    mVideoPlayer->playVideo ("video/" + name, allowSkipping);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,6 +46,7 @@ namespace MWRender
 | 
				
			||||||
    class ExternalRendering;
 | 
					    class ExternalRendering;
 | 
				
			||||||
    class GlobalMap;
 | 
					    class GlobalMap;
 | 
				
			||||||
    class VideoPlayer;
 | 
					    class VideoPlayer;
 | 
				
			||||||
 | 
					    class Animation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener {
 | 
					class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,9 +123,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
 | 
				
			||||||
    void setWaterHeight(const float height);
 | 
					    void setWaterHeight(const float height);
 | 
				
			||||||
    void toggleWater();
 | 
					    void toggleWater();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Moves object rendering part to proper container
 | 
					    /// Updates object rendering after cell change
 | 
				
			||||||
    /// \param store Cell the object was in previously (\a ptr has already been updated to the new cell).
 | 
					    /// \param old Object reference in previous cell
 | 
				
			||||||
    void moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Vector3& position, MWWorld::CellStore *store);
 | 
					    /// \param cur Object reference in new cell
 | 
				
			||||||
 | 
					    void updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void update (float duration, bool paused);
 | 
					    void update (float duration, bool paused);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,18 +168,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
 | 
				
			||||||
    /// configure fog manually
 | 
					    /// configure fog manually
 | 
				
			||||||
    void configureFog(const float density, const Ogre::ColourValue& colour);
 | 
					    void configureFog(const float density, const Ogre::ColourValue& colour);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode,
 | 
					 | 
				
			||||||
        int number = 1);
 | 
					 | 
				
			||||||
    ///< Run animation for a MW-reference. Calls to this function for references that are currently not
 | 
					 | 
				
			||||||
    /// in the rendered scene should be ignored.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// \param mode: 0 normal, 1 immediate start, 2 immediate loop
 | 
					 | 
				
			||||||
    /// \param number How offen the animation should be run
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void skipAnimation (const MWWorld::Ptr& ptr);
 | 
					 | 
				
			||||||
    ///< Skip the animation for the given MW-reference for one frame. Calls to this function for
 | 
					 | 
				
			||||||
    /// references that are currently not in the rendered scene should be ignored.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Ogre::Vector4 boundingBoxToScreen(Ogre::AxisAlignedBox bounds);
 | 
					    Ogre::Vector4 boundingBoxToScreen(Ogre::AxisAlignedBox bounds);
 | 
				
			||||||
    ///< transform the specified bounding box (in world coordinates) into screen coordinates.
 | 
					    ///< transform the specified bounding box (in world coordinates) into screen coordinates.
 | 
				
			||||||
    /// @return packed vector4 (min_x, min_y, max_x, max_y)
 | 
					    /// @return packed vector4 (min_x, min_y, max_x, max_y)
 | 
				
			||||||
| 
						 | 
					@ -196,6 +186,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void setupExternalRendering (MWRender::ExternalRendering& rendering);
 | 
					    void setupExternalRendering (MWRender::ExternalRendering& rendering);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Animation* getAnimation(const MWWorld::Ptr &ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void playVideo(const std::string& name, bool allowSkipping);
 | 
					    void playVideo(const std::string& name, bool allowSkipping);
 | 
				
			||||||
    void stopVideo();
 | 
					    void stopVideo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -236,10 +228,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
 | 
				
			||||||
    Ogre::ColourValue mAmbientColor;
 | 
					    Ogre::ColourValue mAmbientColor;
 | 
				
			||||||
    Ogre::Light* mSun;
 | 
					    Ogre::Light* mSun;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Root node for all objects added to the scene. This is rotated so
 | 
					    Ogre::SceneNode *mRootNode;
 | 
				
			||||||
    /// that the OGRE coordinate system matches that used internally in
 | 
					 | 
				
			||||||
    /// Morrowind.
 | 
					 | 
				
			||||||
    Ogre::SceneNode *mMwRoot;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    OEngine::Physic::PhysicEngine* mPhysicsEngine;
 | 
					    OEngine::Physic::PhysicEngine* mPhysicsEngine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -110,7 +110,7 @@ void BillboardObject::setPosition(const Vector3& pPosition)
 | 
				
			||||||
Vector3 BillboardObject::getPosition() const
 | 
					Vector3 BillboardObject::getPosition() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Vector3 p = mNode->_getDerivedPosition() - mNode->getParentSceneNode()->_getDerivedPosition();
 | 
					    Vector3 p = mNode->_getDerivedPosition() - mNode->getParentSceneNode()->_getDerivedPosition();
 | 
				
			||||||
    return Vector3(p.x, -p.z, p.y);
 | 
					    return p;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void BillboardObject::setVisibilityFlags(int flags)
 | 
					void BillboardObject::setVisibilityFlags(int flags)
 | 
				
			||||||
| 
						 | 
					@ -203,7 +203,7 @@ unsigned int Moon::getPhaseInt() const
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
 | 
					SkyManager::SkyManager (SceneNode* root, Camera* pCamera)
 | 
				
			||||||
    : mHour(0.0f)
 | 
					    : mHour(0.0f)
 | 
				
			||||||
    , mDay(0)
 | 
					    , mDay(0)
 | 
				
			||||||
    , mMonth(0)
 | 
					    , mMonth(0)
 | 
				
			||||||
| 
						 | 
					@ -234,9 +234,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
 | 
				
			||||||
    , mCloudAnimationTimer(0.f)
 | 
					    , mCloudAnimationTimer(0.f)
 | 
				
			||||||
    , mMoonRed(false)
 | 
					    , mMoonRed(false)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mSceneMgr = pMwRoot->getCreator();
 | 
					    mSceneMgr = root->getCreator();
 | 
				
			||||||
    mRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
 | 
					    mRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
 | 
				
			||||||
    mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates
 | 
					 | 
				
			||||||
    mRootNode->setInheritOrientation(false);
 | 
					    mRootNode->setInheritOrientation(false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -282,7 +281,7 @@ void SkyManager::create()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Stars
 | 
					    // Stars
 | 
				
			||||||
    mAtmosphereNight = mRootNode->createChildSceneNode();
 | 
					    mAtmosphereNight = mRootNode->createChildSceneNode();
 | 
				
			||||||
    NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(mAtmosphereNight, NULL, "meshes\\sky_night_01.nif");
 | 
					    NifOgre::EntityList entities = NifOgre::Loader::createEntities(mAtmosphereNight, "meshes\\sky_night_01.nif");
 | 
				
			||||||
    for(size_t i = 0, matidx = 0;i < entities.mEntities.size();i++)
 | 
					    for(size_t i = 0, matidx = 0;i < entities.mEntities.size();i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Entity* night1_ent = entities.mEntities[i];
 | 
					        Entity* night1_ent = entities.mEntities[i];
 | 
				
			||||||
| 
						 | 
					@ -307,26 +306,28 @@ void SkyManager::create()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Atmosphere (day)
 | 
					    // Atmosphere (day)
 | 
				
			||||||
    mAtmosphereDay = mRootNode->createChildSceneNode();
 | 
					    mAtmosphereDay = mRootNode->createChildSceneNode();
 | 
				
			||||||
    entities = NifOgre::NIFLoader::createEntities(mAtmosphereDay, NULL, "meshes\\sky_atmosphere.nif");
 | 
					    entities = NifOgre::Loader::createEntities(mAtmosphereDay, "meshes\\sky_atmosphere.nif");
 | 
				
			||||||
    for(size_t i = 0;i < entities.mEntities.size();i++)
 | 
					    for(size_t i = 0;i < entities.mEntities.size();i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Entity* atmosphere_ent = entities.mEntities[i];
 | 
					        Entity* atmosphere_ent = entities.mEntities[i];
 | 
				
			||||||
        atmosphere_ent->setCastShadows(false);
 | 
					        atmosphere_ent->setCastShadows(false);
 | 
				
			||||||
        atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
 | 
					        atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
 | 
				
			||||||
        atmosphere_ent->setVisibilityFlags(RV_Sky);
 | 
					        atmosphere_ent->setVisibilityFlags(RV_Sky);
 | 
				
			||||||
        atmosphere_ent->getSubEntity (0)->setMaterialName ("openmw_atmosphere");
 | 
					        for(unsigned int j = 0;j < atmosphere_ent->getNumSubEntities();j++)
 | 
				
			||||||
 | 
					            atmosphere_ent->getSubEntity (j)->setMaterialName("openmw_atmosphere");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Clouds
 | 
					    // Clouds
 | 
				
			||||||
    SceneNode* clouds_node = mRootNode->createChildSceneNode();
 | 
					    SceneNode* clouds_node = mRootNode->createChildSceneNode();
 | 
				
			||||||
    entities = NifOgre::NIFLoader::createEntities(clouds_node, NULL, "meshes\\sky_clouds_01.nif");
 | 
					    entities = NifOgre::Loader::createEntities(clouds_node, "meshes\\sky_clouds_01.nif");
 | 
				
			||||||
    for(size_t i = 0;i < entities.mEntities.size();i++)
 | 
					    for(size_t i = 0;i < entities.mEntities.size();i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Entity* clouds_ent = entities.mEntities[i];
 | 
					        Entity* clouds_ent = entities.mEntities[i];
 | 
				
			||||||
        clouds_ent->setVisibilityFlags(RV_Sky);
 | 
					        clouds_ent->setVisibilityFlags(RV_Sky);
 | 
				
			||||||
        clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
 | 
					        clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
 | 
				
			||||||
        clouds_ent->getSubEntity(0)->setMaterialName ("openmw_clouds");
 | 
					        for(unsigned int j = 0;j < clouds_ent->getNumSubEntities();j++)
 | 
				
			||||||
 | 
					            clouds_ent->getSubEntity(j)->setMaterialName("openmw_clouds");
 | 
				
			||||||
        clouds_ent->setCastShadows(false);
 | 
					        clouds_ent->setCastShadows(false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -389,7 +390,6 @@ void SkyManager::update(float duration)
 | 
				
			||||||
        // increase the strength of the sun glare effect depending
 | 
					        // increase the strength of the sun glare effect depending
 | 
				
			||||||
        // on how directly the player is looking at the sun
 | 
					        // on how directly the player is looking at the sun
 | 
				
			||||||
        Vector3 sun = mSunGlare->getPosition();
 | 
					        Vector3 sun = mSunGlare->getPosition();
 | 
				
			||||||
        sun = Vector3(sun.x, sun.z, -sun.y);
 | 
					 | 
				
			||||||
        Vector3 cam = mCamera->getRealDirection();
 | 
					        Vector3 cam = mCamera->getRealDirection();
 | 
				
			||||||
        const Degree angle = sun.angleBetween( cam );
 | 
					        const Degree angle = sun.angleBetween( cam );
 | 
				
			||||||
        float val = 1- (angle.valueDegrees() / 180.f);
 | 
					        float val = 1- (angle.valueDegrees() / 180.f);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,7 +112,7 @@ namespace MWRender
 | 
				
			||||||
    class SkyManager
 | 
					    class SkyManager
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera);
 | 
					        SkyManager(Ogre::SceneNode* root, Ogre::Camera* pCamera);
 | 
				
			||||||
        ~SkyManager();
 | 
					        ~SkyManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void update(float duration);
 | 
					        void update(float duration);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ namespace MWRender
 | 
				
			||||||
    //----------------------------------------------------------------------------------------------
 | 
					    //----------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) :
 | 
					    TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) :
 | 
				
			||||||
         mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend)
 | 
					         mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Y, mLandSize, mWorldSize)), mRendering(rend)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
 | 
					        mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,8 +54,8 @@ namespace MWRender
 | 
				
			||||||
        mTerrainGlobals->setCompositeMapDistance(mWorldSize*2);
 | 
					        mTerrainGlobals->setCompositeMapDistance(mWorldSize*2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mTerrainGroup.setOrigin(Vector3(mWorldSize/2,
 | 
					        mTerrainGroup.setOrigin(Vector3(mWorldSize/2,
 | 
				
			||||||
                                         0,
 | 
					                                         mWorldSize/2,
 | 
				
			||||||
                                         -mWorldSize/2));
 | 
					                                         0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Terrain::ImportData& importSettings = mTerrainGroup.getDefaultImportSettings();
 | 
					        Terrain::ImportData& importSettings = mTerrainGroup.getDefaultImportSettings();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -404,6 +404,8 @@ public:
 | 
				
			||||||
            *type = MWSound::SampleType_UInt8;
 | 
					            *type = MWSound::SampleType_UInt8;
 | 
				
			||||||
        else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_S16)
 | 
					        else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_S16)
 | 
				
			||||||
            *type = MWSound::SampleType_Int16;
 | 
					            *type = MWSound::SampleType_Int16;
 | 
				
			||||||
 | 
					        else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_FLT)
 | 
				
			||||||
 | 
					            *type = MWSound::SampleType_Float32;
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            fail(std::string("Unsupported sample format: ")+
 | 
					            fail(std::string("Unsupported sample format: ")+
 | 
				
			||||||
                 av_get_sample_fmt_name(mAVStream->codec->sample_fmt));
 | 
					                 av_get_sample_fmt_name(mAVStream->codec->sample_fmt));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,9 +42,9 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mIsUnderwater = false;
 | 
					    mIsUnderwater = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mWaterPlane = Plane(Vector3::UNIT_Y, 0);
 | 
					    mWaterPlane = Plane(Vector3::UNIT_Z, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,  mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Z);
 | 
					    MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,  mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mWater = mSceneManager->createEntity("water");
 | 
					    mWater = mSceneManager->createEntity("water");
 | 
				
			||||||
    mWater->setVisibilityFlags(RV_Water);
 | 
					    mWater->setVisibilityFlags(RV_Water);
 | 
				
			||||||
| 
						 | 
					@ -168,12 +168,12 @@ void Water::setHeight(const float height)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mTop = height;
 | 
					    mTop = height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mWaterPlane = Plane(Vector3::UNIT_Y, height);
 | 
					    mWaterPlane = Plane(Vector3::UNIT_Z, height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // small error due to reflection texture size & reflection distortion
 | 
					    // small error due to reflection texture size & reflection distortion
 | 
				
			||||||
    mErrorPlane = Plane(Vector3::UNIT_Y, height - 5);
 | 
					    mErrorPlane = Plane(Vector3::UNIT_Z, height - 5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mWaterNode->setPosition(0, height, 0);
 | 
					    mWaterNode->setPosition(0, 0, height);
 | 
				
			||||||
    sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height)));
 | 
					    sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -199,7 +199,7 @@ Water::updateUnderwater(bool underwater)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY)
 | 
					Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), mTop, -gridY * CELL_SIZE - (CELL_SIZE / 2));
 | 
					    return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), gridY * CELL_SIZE + (CELL_SIZE / 2), mTop);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
 | 
					void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
 | 
				
			||||||
| 
						 | 
					@ -216,7 +216,7 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
 | 
				
			||||||
        mReflectionRenderActive = true;
 | 
					        mReflectionRenderActive = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Vector3 pos = mCamera->getRealPosition();
 | 
					        Vector3 pos = mCamera->getRealPosition();
 | 
				
			||||||
        pos.y = mTop*2 - pos.y;
 | 
					        pos.z = mTop*2 - pos.z;
 | 
				
			||||||
        mSky->setSkyPosition(pos);
 | 
					        mSky->setSkyPosition(pos);
 | 
				
			||||||
        mReflectionCamera->enableReflection(mWaterPlane);
 | 
					        mReflectionCamera->enableReflection(mWaterPlane);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@
 | 
				
			||||||
#include <components/interpreter/runtime.hpp>
 | 
					#include <components/interpreter/runtime.hpp>
 | 
				
			||||||
#include <components/interpreter/opcodes.hpp>
 | 
					#include <components/interpreter/opcodes.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwbase/world.hpp"
 | 
					#include "../mwbase/mechanicsmanager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "interpretercontext.hpp"
 | 
					#include "interpretercontext.hpp"
 | 
				
			||||||
#include "ref.hpp"
 | 
					#include "ref.hpp"
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ namespace MWScript
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    MWWorld::Ptr ptr = R()(runtime);
 | 
					                    MWWorld::Ptr ptr = R()(runtime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    MWBase::Environment::get().getWorld()->skipAnimation (ptr);
 | 
					                    MWBase::Environment::get().getMechanicsManager()->skipAnimation (ptr);
 | 
				
			||||||
               }
 | 
					               }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ namespace MWScript
 | 
				
			||||||
                            throw std::runtime_error ("animation mode out of range");
 | 
					                            throw std::runtime_error ("animation mode out of range");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    MWBase::Environment::get().getWorld()->playAnimationGroup (ptr, group, mode, 1);
 | 
					                    MWBase::Environment::get().getMechanicsManager()->playAnimationGroup (ptr, group, mode, 1);
 | 
				
			||||||
               }
 | 
					               }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ namespace MWScript
 | 
				
			||||||
                            throw std::runtime_error ("animation mode out of range");
 | 
					                            throw std::runtime_error ("animation mode out of range");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    MWBase::Environment::get().getWorld()->playAnimationGroup (ptr, group, mode, loops);
 | 
					                    MWBase::Environment::get().getMechanicsManager()->playAnimationGroup (ptr, group, mode, loops);
 | 
				
			||||||
               }
 | 
					               }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,25 +140,42 @@ namespace MWScript
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Compiler::Locals& ScriptManager::getLocals (const std::string& name)
 | 
					    Compiler::Locals& ScriptManager::getLocals (const std::string& name)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ScriptCollection::iterator iter = mScripts.find (name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (iter==mScripts.end())
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!compile (name))
 | 
					            ScriptCollection::iterator iter = mScripts.find (name);
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                /// \todo Handle case of cyclic member variable access. Currently this could look up
 | 
					 | 
				
			||||||
                /// the whole application in an endless recursion.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // failed -> ignore script from now on.
 | 
					            if (iter!=mScripts.end())
 | 
				
			||||||
                std::vector<Interpreter::Type_Code> empty;
 | 
					                return iter->second.second;
 | 
				
			||||||
                mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));
 | 
					 | 
				
			||||||
                throw std::runtime_error ("failed to compile script " + name);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            iter = mScripts.find (name);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return iter->second.second;
 | 
					        {
 | 
				
			||||||
 | 
					            std::map<std::string, Compiler::Locals>::iterator iter = mOtherLocals.find (name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (iter!=mOtherLocals.end())
 | 
				
			||||||
 | 
					                return iter->second;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Compiler::Locals locals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (const ESM::Script *script = mStore.get<ESM::Script>().find (name))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (int i=0; i<script->mData.mNumShorts; ++i)
 | 
				
			||||||
 | 
					                locals.declare ('s', script->mVarNames[index++]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (int i=0; i<script->mData.mNumLongs; ++i)
 | 
				
			||||||
 | 
					                locals.declare ('l', script->mVarNames[index++]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (int i=0; i<script->mData.mNumFloats; ++i)
 | 
				
			||||||
 | 
					                locals.declare ('f', script->mVarNames[index++]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            std::map<std::string, Compiler::Locals>::iterator iter =
 | 
				
			||||||
 | 
					                mOtherLocals.insert (std::make_pair (name, locals)).first;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return iter->second;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        throw std::logic_error ("script " + name + " does not exist");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GlobalScripts& ScriptManager::getGlobalScripts()
 | 
					    GlobalScripts& ScriptManager::getGlobalScripts()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,7 @@ namespace MWScript
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ScriptCollection mScripts;
 | 
					            ScriptCollection mScripts;
 | 
				
			||||||
            GlobalScripts mGlobalScripts;
 | 
					            GlobalScripts mGlobalScripts;
 | 
				
			||||||
 | 
					            std::map<std::string, Compiler::Locals> mOtherLocals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public:
 | 
					        public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,6 +134,18 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length)
 | 
				
			||||||
    return dec;
 | 
					    return dec;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static AVSampleFormat ffmpegNonPlanarSampleFormat (AVSampleFormat format)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (format)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    case AV_SAMPLE_FMT_U8P:  return AV_SAMPLE_FMT_U8;
 | 
				
			||||||
 | 
					    case AV_SAMPLE_FMT_S16P: return AV_SAMPLE_FMT_S16;
 | 
				
			||||||
 | 
					    case AV_SAMPLE_FMT_S32P: return AV_SAMPLE_FMT_S32;
 | 
				
			||||||
 | 
					    case AV_SAMPLE_FMT_FLTP: return AV_SAMPLE_FMT_FLT;
 | 
				
			||||||
 | 
					    case AV_SAMPLE_FMT_DBLP: return AV_SAMPLE_FMT_DBL;
 | 
				
			||||||
 | 
					    default:return format;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FFmpeg_Decoder::open(const std::string &fname)
 | 
					void FFmpeg_Decoder::open(const std::string &fname)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -160,7 +172,6 @@ void FFmpeg_Decoder::open(const std::string &fname)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if(mFormatCtx->streams[j]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
 | 
					            if(mFormatCtx->streams[j]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                mFormatCtx->streams[j]->codec->request_sample_fmt = AV_SAMPLE_FMT_S16;
 | 
					 | 
				
			||||||
                mStream = &mFormatCtx->streams[j];
 | 
					                mStream = &mFormatCtx->streams[j];
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -168,6 +179,8 @@ void FFmpeg_Decoder::open(const std::string &fname)
 | 
				
			||||||
        if(!mStream)
 | 
					        if(!mStream)
 | 
				
			||||||
            fail("No audio streams in "+fname);
 | 
					            fail("No audio streams in "+fname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (*mStream)->codec->request_sample_fmt = ffmpegNonPlanarSampleFormat ((*mStream)->codec->sample_fmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        AVCodec *codec = avcodec_find_decoder((*mStream)->codec->codec_id);
 | 
					        AVCodec *codec = avcodec_find_decoder((*mStream)->codec->codec_id);
 | 
				
			||||||
        if(!codec)
 | 
					        if(!codec)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -220,6 +233,8 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
 | 
				
			||||||
        *type = SampleType_UInt8;
 | 
					        *type = SampleType_UInt8;
 | 
				
			||||||
    else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16)
 | 
					    else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16)
 | 
				
			||||||
        *type = SampleType_Int16;
 | 
					        *type = SampleType_Int16;
 | 
				
			||||||
 | 
					    else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLT)
 | 
				
			||||||
 | 
					        *type = SampleType_Float32;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        fail(std::string("Unsupported sample format: ")+
 | 
					        fail(std::string("Unsupported sample format: ")+
 | 
				
			||||||
             av_get_sample_fmt_name((*mStream)->codec->sample_fmt));
 | 
					             av_get_sample_fmt_name((*mStream)->codec->sample_fmt));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,6 +88,51 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if(alIsExtensionPresent("AL_EXT_FLOAT32"))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        static const struct {
 | 
				
			||||||
 | 
					            char name[32];
 | 
				
			||||||
 | 
					            ChannelConfig chans;
 | 
				
			||||||
 | 
					            SampleType type;
 | 
				
			||||||
 | 
					        } fltfmtlist[] = {
 | 
				
			||||||
 | 
					            { "AL_FORMAT_MONO_FLOAT32",   ChannelConfig_Mono,   SampleType_Float32 },
 | 
				
			||||||
 | 
					            { "AL_FORMAT_STEREO_FLOAT32", ChannelConfig_Stereo, SampleType_Float32 },
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        static const size_t fltfmtlistsize = sizeof(fltfmtlist)/sizeof(fltfmtlist[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(size_t i = 0;i < fltfmtlistsize;i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if(fltfmtlist[i].chans == chans && fltfmtlist[i].type == type)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ALenum format = alGetEnumValue(fltfmtlist[i].name);
 | 
				
			||||||
 | 
					                if(format != 0 && format != -1)
 | 
				
			||||||
 | 
					                    return format;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            static const struct {
 | 
				
			||||||
 | 
					                char name[32];
 | 
				
			||||||
 | 
					                ChannelConfig chans;
 | 
				
			||||||
 | 
					                SampleType type;
 | 
				
			||||||
 | 
					            } fltmcfmtlist[] = {
 | 
				
			||||||
 | 
					                { "AL_FORMAT_QUAD32",  ChannelConfig_Quad,    SampleType_Float32 },
 | 
				
			||||||
 | 
					                { "AL_FORMAT_51CHN32", ChannelConfig_5point1, SampleType_Float32 },
 | 
				
			||||||
 | 
					                { "AL_FORMAT_71CHN32", ChannelConfig_7point1, SampleType_Float32 },
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            static const size_t fltmcfmtlistsize = sizeof(fltmcfmtlist)/sizeof(fltmcfmtlist[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for(size_t i = 0;i < fltmcfmtlistsize;i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if(fltmcfmtlist[i].chans == chans && fltmcfmtlist[i].type == type)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ALenum format = alGetEnumValue(fltmcfmtlist[i].name);
 | 
				
			||||||
 | 
					                    if(format != 0 && format != -1)
 | 
				
			||||||
 | 
					                        return format;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fail(std::string("Unsupported sound format (")+getChannelConfigName(chans)+", "+getSampleTypeName(type)+")");
 | 
					    fail(std::string("Unsupported sound format (")+getChannelConfigName(chans)+", "+getSampleTypeName(type)+")");
 | 
				
			||||||
    return AL_NONE;
 | 
					    return AL_NONE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,8 @@ namespace MWSound
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    enum SampleType {
 | 
					    enum SampleType {
 | 
				
			||||||
        SampleType_UInt8,
 | 
					        SampleType_UInt8,
 | 
				
			||||||
        SampleType_Int16
 | 
					        SampleType_Int16,
 | 
				
			||||||
 | 
					        SampleType_Float32
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    const char *getSampleTypeName(SampleType type);
 | 
					    const char *getSampleTypeName(SampleType type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -607,6 +607,7 @@ namespace MWSound
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            case SampleType_UInt8: return "U8";
 | 
					            case SampleType_UInt8: return "U8";
 | 
				
			||||||
            case SampleType_Int16: return "S16";
 | 
					            case SampleType_Int16: return "S16";
 | 
				
			||||||
 | 
					            case SampleType_Float32: return "Float32";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return "(unknown sample type)";
 | 
					        return "(unknown sample type)";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -638,6 +639,7 @@ namespace MWSound
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            case SampleType_UInt8: frames *= 1; break;
 | 
					            case SampleType_UInt8: frames *= 1; break;
 | 
				
			||||||
            case SampleType_Int16: frames *= 2; break;
 | 
					            case SampleType_Int16: frames *= 2; break;
 | 
				
			||||||
 | 
					            case SampleType_Float32: frames *= 4; break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return frames;
 | 
					        return frames;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,7 @@ MWWorld::Ptr MWWorld::Cells::getPtrAndCache (const std::string& name, Ptr::CellS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MWWorld::Cells::Cells (const MWWorld::ESMStore& store, std::vector<ESM::ESMReader>& reader)
 | 
					MWWorld::Cells::Cells (const MWWorld::ESMStore& store, std::vector<ESM::ESMReader>& reader)
 | 
				
			||||||
: mStore (store), mReader (reader),
 | 
					: mStore (store), mReader (reader),
 | 
				
			||||||
  mIdCache (20, std::pair<std::string, Ptr::CellStore *> ("", (Ptr::CellStore*)0)), /// \todo make cache size configurable
 | 
					  mIdCache (40, std::pair<std::string, Ptr::CellStore *> ("", (Ptr::CellStore*)0)), /// \todo make cache size configurable
 | 
				
			||||||
  mIdCacheIndex (0)
 | 
					  mIdCacheIndex (0)
 | 
				
			||||||
{}
 | 
					{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,6 +122,11 @@ namespace MWWorld
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    float Class::getJump (const Ptr& ptr) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
 | 
					    MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        throw std::runtime_error ("movement settings not supported by class");
 | 
					        throw std::runtime_error ("movement settings not supported by class");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,6 +140,9 @@ namespace MWWorld
 | 
				
			||||||
            virtual float getSpeed (const Ptr& ptr) const;
 | 
					            virtual float getSpeed (const Ptr& ptr) const;
 | 
				
			||||||
            ///< Return movement speed.
 | 
					            ///< Return movement speed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual float getJump(const MWWorld::Ptr &ptr) const;
 | 
				
			||||||
 | 
					            ///< Return jump velocity (not accounting for movement)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
 | 
					            virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
 | 
				
			||||||
            ///< Return desired movement.
 | 
					            ///< Return desired movement.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,10 @@
 | 
				
			||||||
#include <OgreCamera.h>
 | 
					#include <OgreCamera.h>
 | 
				
			||||||
#include <OgreTextureManager.h>
 | 
					#include <OgreTextureManager.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openengine/bullet/trace.h>
 | 
				
			||||||
 | 
					#include <openengine/bullet/physic.hpp>
 | 
				
			||||||
 | 
					#include <openengine/ogre/renderer.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <components/nifbullet/bullet_nif_loader.hpp>
 | 
					#include <components/nifbullet/bullet_nif_loader.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//#include "../mwbase/world.hpp" // FIXME
 | 
					//#include "../mwbase/world.hpp" // FIXME
 | 
				
			||||||
| 
						 | 
					@ -21,23 +25,191 @@ using namespace Ogre;
 | 
				
			||||||
namespace MWWorld
 | 
					namespace MWWorld
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
 | 
					    static const float sMaxSlope = 60.0f;
 | 
				
			||||||
        mRender(_rend), mEngine(0), mFreeFly (true)
 | 
					    static const float sStepSize = 30.0f;
 | 
				
			||||||
    {
 | 
					    // Arbitrary number. To prevent infinite loops. They shouldn't happen but it's good to be prepared.
 | 
				
			||||||
 | 
					    static const int sMaxIterations = 50;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        playerphysics = new playerMove;
 | 
					    class MovementSolver
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        static bool stepMove(Ogre::Vector3& position, const Ogre::Vector3 &velocity, float remainingTime,
 | 
				
			||||||
 | 
					                             const Ogre::Vector3 &halfExtents, bool isInterior,
 | 
				
			||||||
 | 
					                             OEngine::Physic::PhysicEngine *engine)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            traceResults trace; // no initialization needed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            newtrace(&trace, position, position+Ogre::Vector3(0.0f,0.0f,sStepSize),
 | 
				
			||||||
 | 
					                     halfExtents, isInterior, engine);
 | 
				
			||||||
 | 
					            if(trace.fraction == 0.0f)
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            newtrace(&trace, trace.endpos, trace.endpos + velocity*remainingTime,
 | 
				
			||||||
 | 
					                     halfExtents, isInterior, engine);
 | 
				
			||||||
 | 
					            if(trace.fraction == 0.0f || (trace.fraction != 1.0f && getSlope(trace.planenormal) > sMaxSlope))
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            newtrace(&trace, trace.endpos, trace.endpos-Ogre::Vector3(0.0f,0.0f,sStepSize), halfExtents, isInterior, engine);
 | 
				
			||||||
 | 
					            if(getSlope(trace.planenormal) <= sMaxSlope)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // only step down onto semi-horizontal surfaces. don't step down onto the side of a house or a wall.
 | 
				
			||||||
 | 
					                position = trace.endpos;
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static void clipVelocity(Ogre::Vector3& inout, const Ogre::Vector3& normal, float overbounce=1.0f)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //Math stuff. Basically just project the velocity vector onto the plane represented by the normal.
 | 
				
			||||||
 | 
					            //More specifically, it projects velocity onto the normal, takes that result, multiplies it by overbounce and then subtracts it from velocity.
 | 
				
			||||||
 | 
					            float backoff = inout.dotProduct(normal);
 | 
				
			||||||
 | 
					            if(backoff < 0.0f)
 | 
				
			||||||
 | 
					                backoff *= overbounce;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                backoff /= overbounce;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            inout -= normal*backoff;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static void projectVelocity(Ogre::Vector3& velocity, const Ogre::Vector3& direction)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Ogre::Vector3 normalizedDirection(direction);
 | 
				
			||||||
 | 
					            normalizedDirection.normalise();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // no divide by normalizedDirection.length necessary because it's normalized
 | 
				
			||||||
 | 
					            velocity = normalizedDirection * velocity.dotProduct(normalizedDirection);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static float getSlope(const Ogre::Vector3 &normal)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return normal.angleBetween(Ogre::Vector3(0.0f,0.0f,1.0f)).valueDegrees();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        static Ogre::Vector3 move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time,
 | 
				
			||||||
 | 
					                                  bool gravity, OEngine::Physic::PhysicEngine *engine)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            const ESM::Position &refpos = ptr.getRefData().getPosition();
 | 
				
			||||||
 | 
					            Ogre::Vector3 position(refpos.pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Anything to collide with? */
 | 
				
			||||||
 | 
					            OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle());
 | 
				
			||||||
 | 
					            if(!physicActor || !physicActor->getCollisionMode())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // FIXME: This works, but it's inconcsistent with how the rotations are applied elsewhere. Why?
 | 
				
			||||||
 | 
					                return position + (Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
 | 
				
			||||||
 | 
					                                   Ogre::Quaternion(Ogre::Radian( refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
 | 
				
			||||||
 | 
					                                   Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
 | 
				
			||||||
 | 
					                                  movement;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            traceResults trace; //no initialization needed
 | 
				
			||||||
 | 
					            bool onground = false;
 | 
				
			||||||
 | 
					            float remainingTime = time;
 | 
				
			||||||
 | 
					            bool isInterior = !ptr.getCell()->isExterior();
 | 
				
			||||||
 | 
					            Ogre::Vector3 halfExtents = physicActor->getHalfExtents();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Ogre::Vector3 velocity;
 | 
				
			||||||
 | 
					            if(!gravity)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                velocity = (Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
 | 
				
			||||||
 | 
					                            Ogre::Quaternion(Ogre::Radian( refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
 | 
				
			||||||
 | 
					                            Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
 | 
				
			||||||
 | 
					                           movement / time;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if(!(movement.z > 0.0f))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    newtrace(&trace, position, position-Ogre::Vector3(0,0,4), halfExtents, isInterior, engine);
 | 
				
			||||||
 | 
					                    if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
 | 
				
			||||||
 | 
					                        onground = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z) *
 | 
				
			||||||
 | 
					                           movement / time;
 | 
				
			||||||
 | 
					                velocity.z += physicActor->getVerticalForce();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Ogre::Vector3 clippedVelocity(velocity);
 | 
				
			||||||
 | 
					            if(onground)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // if we're on the ground, force velocity to track it
 | 
				
			||||||
 | 
					                clippedVelocity.z = velocity.z = std::max(0.0f, velocity.z);
 | 
				
			||||||
 | 
					                clipVelocity(clippedVelocity, trace.planenormal);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const Ogre::Vector3 up(0.0f, 0.0f, 1.0f);
 | 
				
			||||||
 | 
					            Ogre::Vector3 newPosition = position;
 | 
				
			||||||
 | 
					            int iterations = 0;
 | 
				
			||||||
 | 
					            do {
 | 
				
			||||||
 | 
					                // trace to where character would go if there were no obstructions
 | 
				
			||||||
 | 
					                newtrace(&trace, newPosition, newPosition+clippedVelocity*remainingTime, halfExtents, isInterior, engine);
 | 
				
			||||||
 | 
					                newPosition = trace.endpos;
 | 
				
			||||||
 | 
					                remainingTime = remainingTime * (1.0f-trace.fraction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // check for obstructions
 | 
				
			||||||
 | 
					                if(trace.fraction < 1.0f)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    //std::cout<<"angle: "<<getSlope(trace.planenormal)<<"\n";
 | 
				
			||||||
 | 
					                    if(getSlope(trace.planenormal) <= sMaxSlope)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // We hit a slope we can walk on. Update velocity accordingly.
 | 
				
			||||||
 | 
					                        clipVelocity(clippedVelocity, trace.planenormal);
 | 
				
			||||||
 | 
					                        // We're only on the ground if gravity is affecting us
 | 
				
			||||||
 | 
					                        onground = gravity;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // Can't walk on this. Try to step up onto it.
 | 
				
			||||||
 | 
					                        if((gravity && !onground) ||
 | 
				
			||||||
 | 
					                           !stepMove(newPosition, velocity, remainingTime, halfExtents, isInterior, engine))
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            Ogre::Vector3 resultantDirection = trace.planenormal.crossProduct(up);
 | 
				
			||||||
 | 
					                            resultantDirection.normalise();
 | 
				
			||||||
 | 
					                            clippedVelocity = velocity;
 | 
				
			||||||
 | 
					                            projectVelocity(clippedVelocity, resultantDirection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            // just this isn't enough sometimes. It's the same problem that causes steps to be necessary on even uphill terrain.
 | 
				
			||||||
 | 
					                            clippedVelocity += trace.planenormal*clippedVelocity.length()/50.0f;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                iterations++;
 | 
				
			||||||
 | 
					            } while(iterations < sMaxIterations && remainingTime > 0.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(onground)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                newtrace(&trace, newPosition, newPosition-Ogre::Vector3(0,0,sStepSize+4.0f), halfExtents, isInterior, engine);
 | 
				
			||||||
 | 
					                if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
 | 
				
			||||||
 | 
					                    newPosition.z = trace.endpos.z + 2.0f;
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    onground = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            physicActor->setOnGround(onground);
 | 
				
			||||||
 | 
					            physicActor->setVerticalForce(!onground ? clippedVelocity.z - time*627.2f : 0.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return newPosition;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
 | 
				
			||||||
 | 
					        mRender(_rend), mEngine(0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        // Create physics. shapeLoader is deleted by the physic engine
 | 
					        // Create physics. shapeLoader is deleted by the physic engine
 | 
				
			||||||
        NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
 | 
					        NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
 | 
				
			||||||
        mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
 | 
					        mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
 | 
				
			||||||
        playerphysics->mEngine = mEngine;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PhysicsSystem::~PhysicsSystem()
 | 
					    PhysicsSystem::~PhysicsSystem()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        delete mEngine;
 | 
					        delete mEngine;
 | 
				
			||||||
        delete playerphysics;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine()
 | 
					    OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return mEngine;
 | 
					        return mEngine;
 | 
				
			||||||
| 
						 | 
					@ -92,9 +264,8 @@ namespace MWWorld
 | 
				
			||||||
        Ogre::Vector3 to = ray.getPoint(queryDistance);
 | 
					        Ogre::Vector3 to = ray.getPoint(queryDistance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        btVector3 _from, _to;
 | 
					        btVector3 _from, _to;
 | 
				
			||||||
        // OGRE to MW coordinates
 | 
					        _from = btVector3(from.x, from.y, from.z);
 | 
				
			||||||
        _from = btVector3(from.x, -from.z, from.y);
 | 
					        _to = btVector3(to.x, to.y, to.z);
 | 
				
			||||||
        _to = btVector3(to.x, -to.z, to.y);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::vector < std::pair <float, std::string> > results;
 | 
					        std::vector < std::pair <float, std::string> > results;
 | 
				
			||||||
        /* auto */ results = mEngine->rayTest2(_from,_to);
 | 
					        /* auto */ results = mEngine->rayTest2(_from,_to);
 | 
				
			||||||
| 
						 | 
					@ -106,15 +277,7 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight)
 | 
					    void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        playerphysics->hasWater = hasWater;
 | 
					        // TODO: store and use
 | 
				
			||||||
        if(hasWater){
 | 
					 | 
				
			||||||
            playerphysics->waterHeight = waterHeight;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            it->second->setCurrentWater(hasWater, waterHeight);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    btVector3 PhysicsSystem::getRayPoint(float extent)
 | 
					    btVector3 PhysicsSystem::getRayPoint(float extent)
 | 
				
			||||||
| 
						 | 
					@ -123,7 +286,7 @@ namespace MWWorld
 | 
				
			||||||
        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
 | 
					        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
 | 
				
			||||||
        mRender.getViewport()->getWidth()/2,
 | 
					        mRender.getViewport()->getWidth()/2,
 | 
				
			||||||
        mRender.getViewport()->getHeight()/2);
 | 
					        mRender.getViewport()->getHeight()/2);
 | 
				
			||||||
        btVector3 result(centerRay.getPoint(extent).x,-centerRay.getPoint(extent).z,centerRay.getPoint(extent).y);
 | 
					        btVector3 result(centerRay.getPoint(extent).x,centerRay.getPoint(extent).y,centerRay.getPoint(extent).z);
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,7 +294,7 @@ namespace MWWorld
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        //get a ray pointing to the center of the viewport
 | 
					        //get a ray pointing to the center of the viewport
 | 
				
			||||||
        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY);
 | 
					        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY);
 | 
				
			||||||
        btVector3 result(centerRay.getPoint(extent).x,-centerRay.getPoint(extent).z,centerRay.getPoint(extent).y);
 | 
					        btVector3 result(centerRay.getPoint(extent).x,centerRay.getPoint(extent).y,centerRay.getPoint(extent).z);
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,9 +334,8 @@ namespace MWWorld
 | 
				
			||||||
        Ogre::Vector3 to = ray.getPoint(200); /// \todo make this distance (ray length) configurable
 | 
					        Ogre::Vector3 to = ray.getPoint(200); /// \todo make this distance (ray length) configurable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        btVector3 _from, _to;
 | 
					        btVector3 _from, _to;
 | 
				
			||||||
        // OGRE to MW coordinates
 | 
					        _from = btVector3(from.x, from.y, from.z);
 | 
				
			||||||
        _from = btVector3(from.x, -from.z, from.y);
 | 
					        _to = btVector3(to.x, to.y, to.z);
 | 
				
			||||||
        _to = btVector3(to.x, -to.z, to.y);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
 | 
					        std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -185,71 +347,11 @@ namespace MWWorld
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void PhysicsSystem::doPhysics(float dt, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
 | 
					    Ogre::Vector3 PhysicsSystem::move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time, bool gravity)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        //set the DebugRenderingMode. To disable it,set it to 0
 | 
					        return MovementSolver::move(ptr, movement, time, gravity, mEngine);
 | 
				
			||||||
        //eng->setDebugRenderingMode(1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //set the movement keys to 0 (no movement) for every actor)
 | 
					 | 
				
			||||||
        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            OEngine::Physic::PhysicActor* act = it->second;
 | 
					 | 
				
			||||||
            act->setMovement(0,0,0);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        playerMove::playercmd& pm_ref = playerphysics->cmd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        pm_ref.rightmove = 0;
 | 
					 | 
				
			||||||
        pm_ref.forwardmove = 0;
 | 
					 | 
				
			||||||
        pm_ref.upmove = 0;
 | 
					 | 
				
			||||||
       
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		//playerphysics->ps.move_type = PM_NOCLIP;
 | 
					 | 
				
			||||||
        for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
 | 
					 | 
				
			||||||
            iter!=actors.end(); ++iter)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            //dirty stuff to get the camera orientation. Must be changed!
 | 
					 | 
				
			||||||
            if (iter->first == "player") {
 | 
					 | 
				
			||||||
                playerphysics->ps.viewangles.x =
 | 
					 | 
				
			||||||
                    Ogre::Radian(mPlayerData.pitch).valueDegrees();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                playerphysics->ps.viewangles.y =
 | 
					 | 
				
			||||||
                    Ogre::Radian(mPlayerData.yaw).valueDegrees() + 90;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                pm_ref.rightmove = iter->second.x;
 | 
					 | 
				
			||||||
                pm_ref.forwardmove = -iter->second.y;
 | 
					 | 
				
			||||||
                pm_ref.upmove = iter->second.z;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        mEngine->stepSimulation(dt);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysicsFixed (
 | 
					 | 
				
			||||||
        const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Pmove(playerphysics);
 | 
					 | 
				
			||||||
       
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::vector< std::pair<std::string, Ogre::Vector3> > response;
 | 
					 | 
				
			||||||
        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Ogre::Vector3 coord = it->second->getPosition();
 | 
					 | 
				
			||||||
            if(it->first == "player"){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                coord = playerphysics->ps.origin ;
 | 
					 | 
				
			||||||
                 
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            response.push_back(std::pair<std::string, Ogre::Vector3>(it->first, coord));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return response;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void PhysicsSystem::addHeightField (float* heights,
 | 
					    void PhysicsSystem::addHeightField (float* heights,
 | 
				
			||||||
                int x, int y, float yoffset,
 | 
					                int x, int y, float yoffset,
 | 
				
			||||||
| 
						 | 
					@ -291,46 +393,20 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void PhysicsSystem::moveObject (const Ptr& ptr)
 | 
					    void PhysicsSystem::moveObject (const Ptr& ptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
 | 
					        Ogre::SceneNode *node = ptr.getRefData().getBaseNode();
 | 
				
			||||||
        std::string handle = node->getName();
 | 
					        const std::string &handle = node->getName();
 | 
				
			||||||
        Ogre::Vector3 position = node->getPosition();
 | 
					        const Ogre::Vector3 &position = node->getPosition();
 | 
				
			||||||
        if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
 | 
					        if(OEngine::Physic::RigidBody *body = mEngine->getRigidBody(handle))
 | 
				
			||||||
        {
 | 
					            body->getWorldTransform().setOrigin(btVector3(position.x,position.y,position.z));
 | 
				
			||||||
            // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
 | 
					        else if(OEngine::Physic::PhysicActor *physact = mEngine->getCharacter(handle))
 | 
				
			||||||
            // start positions others than 0, 0, 0
 | 
					            physact->setPosition(position);
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL){
 | 
					 | 
				
			||||||
                btTransform tr = body->getWorldTransform();
 | 
					 | 
				
			||||||
                tr.setOrigin(btVector3(position.x,position.y,position.z));
 | 
					 | 
				
			||||||
                body->setWorldTransform(tr);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else{
 | 
					 | 
				
			||||||
                //For objects that contain a box shape.  
 | 
					 | 
				
			||||||
                //Do any such objects exist?  Perhaps animated objects?
 | 
					 | 
				
			||||||
                mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, position, node->getOrientation());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
 | 
					 | 
				
			||||||
            // start positions others than 0, 0, 0
 | 
					 | 
				
			||||||
            if (handle == "player")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                playerphysics->ps.origin = position;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                act->setPosition(position);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void PhysicsSystem::rotateObject (const Ptr& ptr)
 | 
					    void PhysicsSystem::rotateObject (const Ptr& ptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
 | 
					        Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
 | 
				
			||||||
        std::string handle = node->getName();
 | 
					        const std::string &handle = node->getName();
 | 
				
			||||||
        Ogre::Quaternion rotation = node->getOrientation();
 | 
					        const Ogre::Quaternion &rotation = node->getOrientation();
 | 
				
			||||||
        if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
 | 
					        if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            //Needs to be changed
 | 
					            //Needs to be changed
 | 
				
			||||||
| 
						 | 
					@ -348,7 +424,7 @@ namespace MWWorld
 | 
				
			||||||
    void PhysicsSystem::scaleObject (const Ptr& ptr)
 | 
					    void PhysicsSystem::scaleObject (const Ptr& ptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
 | 
					        Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
 | 
				
			||||||
        std::string handle = node->getName();
 | 
					        const std::string &handle = node->getName();
 | 
				
			||||||
        if(handleToMesh.find(handle) != handleToMesh.end())
 | 
					        if(handleToMesh.find(handle) != handleToMesh.end())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            removeObject(handle);
 | 
					            removeObject(handle);
 | 
				
			||||||
| 
						 | 
					@ -361,7 +437,6 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool PhysicsSystem::toggleCollisionMode()
 | 
					    bool PhysicsSystem::toggleCollisionMode()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        playerphysics->ps.move_type = (playerphysics->ps.move_type == PM_NOCLIP ? PM_NORMAL : PM_NOCLIP);
 | 
					 | 
				
			||||||
        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
 | 
					        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (it->first=="player")
 | 
					            if (it->first=="player")
 | 
				
			||||||
| 
						 | 
					@ -372,12 +447,10 @@ namespace MWWorld
 | 
				
			||||||
                if(cmode)
 | 
					                if(cmode)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    act->enableCollisions(false);
 | 
					                    act->enableCollisions(false);
 | 
				
			||||||
                    mFreeFly = true;
 | 
					 | 
				
			||||||
                    return false;
 | 
					                    return false;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    mFreeFly = false;
 | 
					 | 
				
			||||||
                    act->enableCollisions(true);
 | 
					                    act->enableCollisions(true);
 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,27 @@
 | 
				
			||||||
#ifndef GAME_MWWORLD_PHYSICSSYSTEM_H
 | 
					#ifndef GAME_MWWORLD_PHYSICSSYSTEM_H
 | 
				
			||||||
#define GAME_MWWORLD_PHYSICSSYSTEM_H
 | 
					#define GAME_MWWORLD_PHYSICSSYSTEM_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <openengine/ogre/renderer.hpp>
 | 
					#include <OgreVector3.h>
 | 
				
			||||||
#include "ptr.hpp"
 | 
					
 | 
				
			||||||
#include <openengine/bullet/pmove.h>
 | 
					#include <btBulletCollisionCommon.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OEngine
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    namespace Render
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        class OgreRenderer;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    namespace Physic
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        class PhysicEngine;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWWorld
 | 
					namespace MWWorld
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    class World;
 | 
				
			||||||
 | 
					    class Ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class PhysicsSystem
 | 
					    class PhysicsSystem
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -14,12 +29,6 @@ namespace MWWorld
 | 
				
			||||||
            PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
 | 
					            PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
 | 
				
			||||||
            ~PhysicsSystem ();
 | 
					            ~PhysicsSystem ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void doPhysics(float duration, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
 | 
					 | 
				
			||||||
            ///< do physics with dt - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            std::vector< std::pair<std::string, Ogre::Vector3> > doPhysicsFixed (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
 | 
					 | 
				
			||||||
            ///< do physics with fixed timestep - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            void addObject (const MWWorld::Ptr& ptr);
 | 
					            void addObject (const MWWorld::Ptr& ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void addActor (const MWWorld::Ptr& ptr);
 | 
					            void addActor (const MWWorld::Ptr& ptr);
 | 
				
			||||||
| 
						 | 
					@ -41,6 +50,8 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            bool toggleCollisionMode();
 | 
					            bool toggleCollisionMode();
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            Ogre::Vector3 move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time, bool gravity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::pair<float, std::string> getFacedHandle (MWWorld::World& world, float queryDistance);
 | 
					            std::pair<float, std::string> getFacedHandle (MWWorld::World& world, float queryDistance);
 | 
				
			||||||
            std::vector < std::pair <float, std::string> > getFacedHandles (float queryDistance);
 | 
					            std::vector < std::pair <float, std::string> > getFacedHandles (float queryDistance);
 | 
				
			||||||
            std::vector < std::pair <float, std::string> > getFacedHandles (float mouseX, float mouseY, float queryDistance);
 | 
					            std::vector < std::pair <float, std::string> > getFacedHandles (float mouseX, float mouseY, float queryDistance);
 | 
				
			||||||
| 
						 | 
					@ -74,8 +85,6 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            OEngine::Render::OgreRenderer &mRender;
 | 
					            OEngine::Render::OgreRenderer &mRender;
 | 
				
			||||||
            OEngine::Physic::PhysicEngine* mEngine;
 | 
					            OEngine::Physic::PhysicEngine* mEngine;
 | 
				
			||||||
            bool mFreeFly;
 | 
					 | 
				
			||||||
            playerMove* playerphysics;
 | 
					 | 
				
			||||||
            std::map<std::string, std::string> handleToMesh;
 | 
					            std::map<std::string, std::string> handleToMesh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PhysicsSystem (const PhysicsSystem&);
 | 
					            PhysicsSystem (const PhysicsSystem&);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,6 +71,12 @@ namespace MWWorld
 | 
				
			||||||
        MWWorld::Class::get (ptr).getMovementSettings (ptr).mUpDown = value;
 | 
					        MWWorld::Class::get (ptr).getMovementSettings (ptr).mUpDown = value;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void Player::setRunState(bool run)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MWWorld::Ptr ptr = getPlayer();
 | 
				
			||||||
 | 
					        MWWorld::Class::get(ptr).setStance(ptr, MWWorld::Class::Run, run);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Player::toggleRunning()
 | 
					    void Player::toggleRunning()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWWorld::Ptr ptr = getPlayer();
 | 
					        MWWorld::Ptr ptr = getPlayer();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,7 @@ namespace MWWorld
 | 
				
			||||||
        void setForwardBackward (int value);
 | 
					        void setForwardBackward (int value);
 | 
				
			||||||
        void setUpDown(int value);
 | 
					        void setUpDown(int value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void setRunState(bool run);
 | 
				
			||||||
        void toggleRunning();
 | 
					        void toggleRunning();
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
#include "scene.hpp"
 | 
					#include "scene.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <components/nif/nif_file.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwbase/environment.hpp"
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
#include "../mwbase/world.hpp" /// FIXME
 | 
					#include "../mwbase/world.hpp" /// FIXME
 | 
				
			||||||
| 
						 | 
					@ -7,9 +8,11 @@
 | 
				
			||||||
#include "../mwbase/mechanicsmanager.hpp"
 | 
					#include "../mwbase/mechanicsmanager.hpp"
 | 
				
			||||||
#include "../mwbase/windowmanager.hpp"
 | 
					#include "../mwbase/windowmanager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "physicssystem.hpp"
 | 
				
			||||||
#include "player.hpp"
 | 
					#include "player.hpp"
 | 
				
			||||||
#include "localscripts.hpp"
 | 
					#include "localscripts.hpp"
 | 
				
			||||||
#include "esmstore.hpp"
 | 
					#include "esmstore.hpp"
 | 
				
			||||||
 | 
					#include "class.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "cellfunctors.hpp"
 | 
					#include "cellfunctors.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,13 +27,10 @@ namespace
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            const MWWorld::Class& class_ =
 | 
					            const MWWorld::Class& class_ =
 | 
				
			||||||
                MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.mList.begin(), &cell));
 | 
					                MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.mList.begin(), &cell));
 | 
				
			||||||
 | 
					 | 
				
			||||||
            int numRefs = cellRefList.mList.size();
 | 
					 | 
				
			||||||
            int current = 0;
 | 
					            int current = 0;
 | 
				
			||||||
            for (typename T::List::iterator it = cellRefList.mList.begin();
 | 
					            for (typename T::List::iterator it = cellRefList.mList.begin();
 | 
				
			||||||
                it != cellRefList.mList.end(); it++)
 | 
					                it != cellRefList.mList.end(); it++)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 1, current, numRefs);
 | 
					 | 
				
			||||||
                ++current;
 | 
					                ++current;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (it->mData.getCount() || it->mData.isEnabled())
 | 
					                if (it->mData.getCount() || it->mData.isEnabled())
 | 
				
			||||||
| 
						 | 
					@ -52,10 +52,6 @@ namespace
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 1, 0, 1);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -98,7 +94,7 @@ namespace MWWorld
 | 
				
			||||||
       //mPhysics->removeObject("Unnamed_43");
 | 
					       //mPhysics->removeObject("Unnamed_43");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MWBase::Environment::get().getWorld()->getLocalScripts().clearCell (*iter);
 | 
					        MWBase::Environment::get().getWorld()->getLocalScripts().clearCell (*iter);
 | 
				
			||||||
        MWBase::Environment::get().getMechanicsManager()->dropActors (*iter);
 | 
					        MWBase::Environment::get().getMechanicsManager()->drop (*iter);
 | 
				
			||||||
        MWBase::Environment::get().getSoundManager()->stopSound (*iter);
 | 
					        MWBase::Environment::get().getSoundManager()->stopSound (*iter);
 | 
				
			||||||
        mActiveCells.erase(*iter);
 | 
					        mActiveCells.erase(*iter);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -164,7 +160,7 @@ namespace MWWorld
 | 
				
			||||||
        MWBase::MechanicsManager *mechMgr =
 | 
					        MWBase::MechanicsManager *mechMgr =
 | 
				
			||||||
            MWBase::Environment::get().getMechanicsManager();
 | 
					            MWBase::Environment::get().getMechanicsManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mechMgr->addActor(player);
 | 
					        mechMgr->add(player);
 | 
				
			||||||
        mechMgr->watchActor(player);
 | 
					        mechMgr->watchActor(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
 | 
					        MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
 | 
				
			||||||
| 
						 | 
					@ -173,11 +169,17 @@ namespace MWWorld
 | 
				
			||||||
    void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos)
 | 
					    void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Nif::NIFFile::CacheLock cachelock;
 | 
					        Nif::NIFFile::CacheLock cachelock;
 | 
				
			||||||
 | 
					        const MWWorld::Store<ESM::GameSetting> &gmst =
 | 
				
			||||||
 | 
					            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mRendering.preCellChange(mCurrentCell);
 | 
					        mRendering.preCellChange(mCurrentCell);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // remove active
 | 
					        // remove active
 | 
				
			||||||
        MWBase::Environment::get().getMechanicsManager()->removeActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
 | 
					        MWBase::Environment::get().getMechanicsManager()->remove(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::string loadingExteriorText;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        loadingExteriorText = gmst.find ("sLoadingMessage3")->getString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CellStoreCollection::iterator active = mActiveCells.begin();
 | 
					        CellStoreCollection::iterator active = mActiveCells.begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,8 +215,6 @@ namespace MWWorld
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload);
 | 
					 | 
				
			||||||
            unloadCell (active++);
 | 
					            unloadCell (active++);
 | 
				
			||||||
            ++current;
 | 
					            ++current;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -263,7 +263,9 @@ namespace MWWorld
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y);
 | 
					                    CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, current, numLoad);
 | 
					                    //Loading Exterior loading text
 | 
				
			||||||
 | 
					                    MWBase::Environment::get().getWindowManager ()->setLoadingProgress (loadingExteriorText, 0, current, numLoad);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    loadCell (cell);
 | 
					                    loadCell (cell);
 | 
				
			||||||
                    ++current;
 | 
					                    ++current;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -322,6 +324,13 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
 | 
					    void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const MWWorld::Store<ESM::GameSetting> &gmst =
 | 
				
			||||||
 | 
					            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::string loadingInteriorText;
 | 
				
			||||||
 | 
					        loadingInteriorText = gmst.find ("sLoadingMessage2")->getString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName);
 | 
					        CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName);
 | 
				
			||||||
        bool loadcell = (mCurrentCell == NULL);
 | 
					        bool loadcell = (mCurrentCell == NULL);
 | 
				
			||||||
        if(!loadcell)
 | 
					        if(!loadcell)
 | 
				
			||||||
| 
						 | 
					@ -357,8 +366,6 @@ namespace MWWorld
 | 
				
			||||||
        active = mActiveCells.begin();
 | 
					        active = mActiveCells.begin();
 | 
				
			||||||
        while (active!=mActiveCells.end())
 | 
					        while (active!=mActiveCells.end())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            unloadCell (active++);
 | 
					            unloadCell (active++);
 | 
				
			||||||
            ++current;
 | 
					            ++current;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -366,7 +373,9 @@ namespace MWWorld
 | 
				
			||||||
        // Load cell.
 | 
					        // Load cell.
 | 
				
			||||||
        std::cout << "cellName: " << cell->mCell->mName << std::endl;
 | 
					        std::cout << "cellName: " << cell->mCell->mName << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, 0, 1);
 | 
					        //Loading Interior loading text
 | 
				
			||||||
 | 
					        MWBase::Environment::get().getWindowManager ()->setLoadingProgress (loadingInteriorText, 0, 0, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        loadCell (cell);
 | 
					        loadCell (cell);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mCurrentCell = cell;
 | 
					        mCurrentCell = cell;
 | 
				
			||||||
| 
						 | 
					@ -441,7 +450,7 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Scene::removeObjectFromScene (const Ptr& ptr)
 | 
					    void Scene::removeObjectFromScene (const Ptr& ptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWBase::Environment::get().getMechanicsManager()->removeActor (ptr);
 | 
					        MWBase::Environment::get().getMechanicsManager()->remove (ptr);
 | 
				
			||||||
        MWBase::Environment::get().getSoundManager()->stopSound3D (ptr);
 | 
					        MWBase::Environment::get().getSoundManager()->stopSound3D (ptr);
 | 
				
			||||||
        mPhysics->removeObject (ptr.getRefData().getHandle());
 | 
					        mPhysics->removeObject (ptr.getRefData().getHandle());
 | 
				
			||||||
        mRendering.removeObject (ptr);
 | 
					        mRendering.removeObject (ptr);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwrender/renderingmanager.hpp"
 | 
					#include "../mwrender/renderingmanager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "physicssystem.hpp"
 | 
					#include "ptr.hpp"
 | 
				
			||||||
#include "globals.hpp"
 | 
					#include "globals.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ogre
 | 
					namespace Ogre
 | 
				
			||||||
| 
						 | 
					@ -34,9 +34,9 @@ namespace MWRender
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWWorld
 | 
					namespace MWWorld
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    class PhysicsSystem;
 | 
				
			||||||
    class Player;
 | 
					    class Player;
 | 
				
			||||||
    class CellStore;
 | 
					    class CellStore;
 | 
				
			||||||
    class Ptr;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Scene
 | 
					    class Scene
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ namespace MWWorld
 | 
				
			||||||
        virtual void setUp() {}
 | 
					        virtual void setUp() {}
 | 
				
			||||||
        virtual void listIdentifier(std::vector<std::string> &list) const {}
 | 
					        virtual void listIdentifier(std::vector<std::string> &list) const {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual int getSize() const = 0;
 | 
					        virtual size_t getSize() const = 0;
 | 
				
			||||||
        virtual void load(ESM::ESMReader &esm, const std::string &id) = 0;
 | 
					        virtual void load(ESM::ESMReader &esm, const std::string &id) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual bool eraseStatic(const std::string &id) {return false;}
 | 
					        virtual bool eraseStatic(const std::string &id) {return false;}
 | 
				
			||||||
| 
						 | 
					@ -158,7 +158,7 @@ namespace MWWorld
 | 
				
			||||||
            return mShared.end();
 | 
					            return mShared.end();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int getSize() const {
 | 
					        size_t getSize() const {
 | 
				
			||||||
            return mShared.size();
 | 
					            return mShared.size();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -220,9 +220,15 @@ namespace MWWorld
 | 
				
			||||||
    template <>
 | 
					    template <>
 | 
				
			||||||
    inline void Store<ESM::Dialogue>::load(ESM::ESMReader &esm, const std::string &id) {
 | 
					    inline void Store<ESM::Dialogue>::load(ESM::ESMReader &esm, const std::string &id) {
 | 
				
			||||||
        std::string idLower = Misc::StringUtils::lowerCase(id);
 | 
					        std::string idLower = Misc::StringUtils::lowerCase(id);
 | 
				
			||||||
        mStatic[idLower] = ESM::Dialogue();
 | 
					
 | 
				
			||||||
        mStatic[idLower].mId = id; // don't smash case here, as this line is printed... I think
 | 
					        std::map<std::string, ESM::Dialogue>::iterator it = mStatic.find(idLower);
 | 
				
			||||||
        mStatic[idLower].load(esm);
 | 
					        if (it == mStatic.end()) {
 | 
				
			||||||
 | 
					            it = mStatic.insert( std::make_pair( idLower, ESM::Dialogue() ) ).first;
 | 
				
			||||||
 | 
					            it->second.mId = id; // don't smash case here, as this line is printed... I think
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //I am not sure is it need to load the dialog from a plugin if it was already loaded from prevois plugins
 | 
				
			||||||
 | 
					        it->second.load(esm);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template <>
 | 
					    template <>
 | 
				
			||||||
| 
						 | 
					@ -269,11 +275,11 @@ namespace MWWorld
 | 
				
			||||||
            return ptr;
 | 
					            return ptr;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int getSize() const {
 | 
					        size_t getSize() const {
 | 
				
			||||||
            return mStatic.size();
 | 
					            return mStatic.size();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int getSize(size_t plugin) const {
 | 
					        size_t getSize(size_t plugin) const {
 | 
				
			||||||
            assert(plugin < mStatic.size());
 | 
					            assert(plugin < mStatic.size());
 | 
				
			||||||
            return mStatic[plugin].size();
 | 
					            return mStatic[plugin].size();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -338,7 +344,7 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int getSize() const {
 | 
					        size_t getSize() const {
 | 
				
			||||||
            return mStatic.size();
 | 
					            return mStatic.size();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -567,7 +573,7 @@ namespace MWWorld
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int getSize() const {
 | 
					        size_t getSize() const {
 | 
				
			||||||
            return mSharedInt.size() + mSharedExt.size();
 | 
					            return mSharedInt.size() + mSharedExt.size();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -701,7 +707,7 @@ namespace MWWorld
 | 
				
			||||||
            mStatic.back().load(esm);
 | 
					            mStatic.back().load(esm);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int getSize() const {
 | 
					        size_t getSize() const {
 | 
				
			||||||
            return mStatic.size();
 | 
					            return mStatic.size();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -930,7 +936,7 @@ namespace MWWorld
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int getSize() const {
 | 
					        size_t getSize() const {
 | 
				
			||||||
            return mStatic.size();
 | 
					            return mStatic.size();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,7 @@
 | 
				
			||||||
#include "worldimp.hpp"
 | 
					#include "worldimp.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <libs/openengine/bullet/physic.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <components/bsa/bsa_archive.hpp>
 | 
					#include <components/bsa/bsa_archive.hpp>
 | 
				
			||||||
#include <components/files/collections.hpp>
 | 
					#include <components/files/collections.hpp>
 | 
				
			||||||
#include <components/compiler/locals.hpp>
 | 
					#include <components/compiler/locals.hpp>
 | 
				
			||||||
| 
						 | 
					@ -10,6 +12,8 @@
 | 
				
			||||||
#include "../mwbase/windowmanager.hpp"
 | 
					#include "../mwbase/windowmanager.hpp"
 | 
				
			||||||
#include "../mwbase/scriptmanager.hpp"
 | 
					#include "../mwbase/scriptmanager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwmechanics/creaturestats.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwrender/sky.hpp"
 | 
					#include "../mwrender/sky.hpp"
 | 
				
			||||||
#include "../mwrender/player.hpp"
 | 
					#include "../mwrender/player.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +22,7 @@
 | 
				
			||||||
#include "player.hpp"
 | 
					#include "player.hpp"
 | 
				
			||||||
#include "manualref.hpp"
 | 
					#include "manualref.hpp"
 | 
				
			||||||
#include "cellfunctors.hpp"
 | 
					#include "cellfunctors.hpp"
 | 
				
			||||||
 | 
					#include "containerstore.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace Ogre;
 | 
					using namespace Ogre;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,6 +188,8 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mRendering = new MWRender::RenderingManager(renderer, resDir, cacheDir, mPhysEngine);
 | 
					        mRendering = new MWRender::RenderingManager(renderer, resDir, cacheDir, mPhysEngine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mPhysEngine->setSceneManager(renderer.getScene());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mWeatherManager = new MWWorld::WeatherManager(mRendering);
 | 
					        mWeatherManager = new MWWorld::WeatherManager(mRendering);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int idx = 0;
 | 
					        int idx = 0;
 | 
				
			||||||
| 
						 | 
					@ -732,6 +739,7 @@ namespace MWWorld
 | 
				
			||||||
        removeContainerScripts(ptr);
 | 
					        removeContainerScripts(ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (isPlayer)
 | 
					            if (isPlayer)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                if (!newCell.isExterior())
 | 
					                if (!newCell.isExterior())
 | 
				
			||||||
                    changeToInteriorCell(Misc::StringUtils::lowerCase(newCell.mCell->mName), pos);
 | 
					                    changeToInteriorCell(Misc::StringUtils::lowerCase(newCell.mCell->mName), pos);
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
| 
						 | 
					@ -740,13 +748,18 @@ namespace MWWorld
 | 
				
			||||||
                    int cellY = newCell.mCell->getGridY();
 | 
					                    int cellY = newCell.mCell->getGridY();
 | 
				
			||||||
                    mWorldScene->changeCell(cellX, cellY, pos, false);
 | 
					                    mWorldScene->changeCell(cellX, cellY, pos, false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (!mWorldScene->isCellActive(*currCell))
 | 
					                if (!mWorldScene->isCellActive(*currCell))
 | 
				
			||||||
                    copyObjectToCell(ptr, newCell, pos);
 | 
					                    copyObjectToCell(ptr, newCell, pos);
 | 
				
			||||||
                else if (!mWorldScene->isCellActive(newCell))
 | 
					                else if (!mWorldScene->isCellActive(newCell))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
 | 
					                    MWWorld::Class::get(ptr)
 | 
				
			||||||
 | 
					                        .copyToCell(ptr, newCell)
 | 
				
			||||||
 | 
					                        .getRefData()
 | 
				
			||||||
 | 
					                        .setBaseNode(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    mWorldScene->removeObjectFromScene(ptr);
 | 
					                    mWorldScene->removeObjectFromScene(ptr);
 | 
				
			||||||
                    mLocalScripts.remove(ptr);
 | 
					                    mLocalScripts.remove(ptr);
 | 
				
			||||||
                    removeContainerScripts (ptr);
 | 
					                    removeContainerScripts (ptr);
 | 
				
			||||||
| 
						 | 
					@ -757,7 +770,10 @@ namespace MWWorld
 | 
				
			||||||
                    MWWorld::Ptr copy =
 | 
					                    MWWorld::Ptr copy =
 | 
				
			||||||
                        MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
 | 
					                        MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    mRendering->moveObjectToCell(copy, vec, currCell);
 | 
					                    mRendering->updateObjectCell(ptr, copy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    MWBase::MechanicsManager *mechMgr = MWBase::Environment::get().getMechanicsManager();
 | 
				
			||||||
 | 
					                    mechMgr->updateCell(ptr, copy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    std::string script =
 | 
					                    std::string script =
 | 
				
			||||||
                        MWWorld::Class::get(ptr).getScript(ptr);
 | 
					                        MWWorld::Class::get(ptr).getScript(ptr);
 | 
				
			||||||
| 
						 | 
					@ -768,15 +784,6 @@ namespace MWWorld
 | 
				
			||||||
                        mLocalScripts.add(script, copy);
 | 
					                        mLocalScripts.add(script, copy);
 | 
				
			||||||
                        addContainerScripts (copy, &newCell);
 | 
					                        addContainerScripts (copy, &newCell);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (MWWorld::Class::get(ptr).isActor())
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        MWBase::MechanicsManager *mechMgr =
 | 
					 | 
				
			||||||
                            MWBase::Environment::get().getMechanicsManager();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        mechMgr->removeActor(ptr);
 | 
					 | 
				
			||||||
                        mechMgr->addActor(copy);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                ptr.getRefData().setCount(0);
 | 
					                ptr.getRefData().setCount(0);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -825,16 +832,16 @@ namespace MWWorld
 | 
				
			||||||
        rot.y = Ogre::Degree(y).valueRadians();
 | 
					        rot.y = Ogre::Degree(y).valueRadians();
 | 
				
			||||||
        rot.z = Ogre::Degree(z).valueRadians();
 | 
					        rot.z = Ogre::Degree(z).valueRadians();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        float *objRot = ptr.getRefData().getPosition().rot;
 | 
					        if (mRendering->rotateObject(ptr, rot, adjust))
 | 
				
			||||||
        if(ptr.getRefData().getBaseNode() == 0 || !mRendering->rotateObject(ptr, rot, adjust))
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            objRot[0] = (adjust ? objRot[0] + rot.x : rot.x), objRot[1] = (adjust ? objRot[1] + rot.y : rot.y), objRot[2] = (adjust ? objRot[2] + rot.z : rot.z);
 | 
					            // rotate physically iff renderer confirm so
 | 
				
			||||||
            return;
 | 
					            float *objRot = ptr.getRefData().getPosition().rot;
 | 
				
			||||||
         }
 | 
					            objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // do this after rendering rotated the object so it gets changed by Class->adjustRotation
 | 
					            if (ptr.getRefData().getBaseNode() != 0) {
 | 
				
			||||||
        objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
 | 
					                mPhysics->rotateObject(ptr);
 | 
				
			||||||
        mPhysics->rotateObject(ptr);
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)
 | 
					    void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)
 | 
				
			||||||
| 
						 | 
					@ -871,53 +878,33 @@ namespace MWWorld
 | 
				
			||||||
            --cellY;
 | 
					            --cellY;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void World::doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
 | 
					    void World::doPhysics(const PtrMovementList &actors, float duration)
 | 
				
			||||||
        float duration)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mPhysics->doPhysics(duration, actors);
 | 
					        /* No duration? Shouldn't be any movement, then. */
 | 
				
			||||||
 | 
					        if(duration <= 0.0f)
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const int tick = 16; // 16 ms ^= 60 Hz
 | 
					        PtrMovementList::const_iterator player(actors.end());
 | 
				
			||||||
 | 
					        for(PtrMovementList::const_iterator iter(actors.begin());iter != actors.end();iter++)
 | 
				
			||||||
        // Game clock part of the loop, contains everything that has to be executed in a fixed timestep
 | 
					 | 
				
			||||||
        long long dt = mTimer.getMilliseconds() - lastTick;
 | 
					 | 
				
			||||||
        if (dt >= 100)
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            //  throw away wall clock time if necessary to keep the framerate above the minimum of 10 fps
 | 
					            if(iter->first.getRefData().getHandle() == "player")
 | 
				
			||||||
            lastTick += (dt - 100);
 | 
					            {
 | 
				
			||||||
            dt = 100;
 | 
					                /* Handle player last, in case a cell transition occurs */
 | 
				
			||||||
 | 
					                player = iter;
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Ogre::Vector3 vec = mPhysics->move(iter->first, iter->second, duration,
 | 
				
			||||||
 | 
					                                               !isSwimming(iter->first) && !isFlying(iter->first));
 | 
				
			||||||
 | 
					            moveObjectImp(iter->first, vec.x, vec.y, vec.z);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        while (dt >= tick)
 | 
					        if(player != actors.end())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            dt -= tick;
 | 
					            Ogre::Vector3 vec = mPhysics->move(player->first, player->second, duration,
 | 
				
			||||||
            lastTick += tick;
 | 
					                                               !isSwimming(player->first) && !isFlying(player->first));
 | 
				
			||||||
 | 
					            moveObjectImp(player->first, vec.x, vec.y, vec.z);
 | 
				
			||||||
            std::vector< std::pair<std::string, Ogre::Vector3> > vectors = mPhysics->doPhysicsFixed (actors);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            std::vector< std::pair<std::string, Ogre::Vector3> >::iterator player = vectors.end();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            for (std::vector< std::pair<std::string, Ogre::Vector3> >::iterator it = vectors.begin();
 | 
					 | 
				
			||||||
                it!= vectors.end(); ++it)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (it->first=="player")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    player = it;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    MWWorld::Ptr ptr = getPtrViaHandle (it->first);
 | 
					 | 
				
			||||||
                    moveObjectImp (ptr, it->second.x, it->second.y, it->second.z);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Make sure player is moved last (otherwise the cell might change in the middle of an update
 | 
					 | 
				
			||||||
            // loop)
 | 
					 | 
				
			||||||
            if (player!=vectors.end())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (moveObjectImp (getPtrViaHandle (player->first),
 | 
					 | 
				
			||||||
                    player->second.x, player->second.y, player->second.z) == true)
 | 
					 | 
				
			||||||
                    return; // abort the current loop if the cell has changed
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        // the only purpose this has currently is to update the debug drawer
 | 
				
			||||||
 | 
					        mPhysEngine->stepSimulation (duration);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool World::toggleCollisionMode()
 | 
					    bool World::toggleCollisionMode()
 | 
				
			||||||
| 
						 | 
					@ -985,17 +972,6 @@ namespace MWWorld
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void World::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode,
 | 
					 | 
				
			||||||
        int number)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        mRendering->playAnimationGroup (ptr, groupName, mode, number);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void World::skipAnimation (const MWWorld::Ptr& ptr)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        mRendering->skipAnimation (ptr);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void World::update (float duration, bool paused)
 | 
					    void World::update (float duration, bool paused)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mWorldScene->update (duration, paused);
 | 
					        mWorldScene->update (duration, paused);
 | 
				
			||||||
| 
						 | 
					@ -1048,7 +1024,6 @@ namespace MWWorld
 | 
				
			||||||
            // currently its here because we need to access the physics system
 | 
					            // currently its here because we need to access the physics system
 | 
				
			||||||
            float* p = mPlayer->getPlayer().getRefData().getPosition().pos;
 | 
					            float* p = mPlayer->getPlayer().getRefData().getPosition().pos;
 | 
				
			||||||
            Vector3 sun = mRendering->getSkyManager()->getRealSunPos();
 | 
					            Vector3 sun = mRendering->getSkyManager()->getRealSunPos();
 | 
				
			||||||
            sun = Vector3(sun.x, -sun.z, sun.y);
 | 
					 | 
				
			||||||
            mRendering->getSkyManager()->setGlare(!mPhysics->castRay(Ogre::Vector3(p[0], p[1], p[2]), sun));
 | 
					            mRendering->getSkyManager()->setGlare(!mPhysics->castRay(Ogre::Vector3(p[0], p[1], p[2]), sun));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1146,7 +1121,7 @@ namespace MWWorld
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            p = mPhysics->getRayPoint(results.front().first);
 | 
					            p = mPhysics->getRayPoint(results.front().first);
 | 
				
			||||||
        Ogre::Vector3 pos(p.x(), p.z(), -p.y());
 | 
					        Ogre::Vector3 pos(p.x(), p.y(), p.z());
 | 
				
			||||||
        Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
 | 
					        Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //std::cout << "Num facing 1 : " << mFaced1Name <<  std::endl;
 | 
					        //std::cout << "Num facing 1 : " << mFaced1Name <<  std::endl;
 | 
				
			||||||
| 
						 | 
					@ -1174,7 +1149,7 @@ namespace MWWorld
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            p = mPhysics->getRayPoint(results.at (1).first);
 | 
					            p = mPhysics->getRayPoint(results.at (1).first);
 | 
				
			||||||
        Ogre::Vector3 pos(p.x(), p.z(), -p.y());
 | 
					        Ogre::Vector3 pos(p.x(), p.y(), p.z());
 | 
				
			||||||
        Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode();
 | 
					        Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode();
 | 
				
			||||||
        Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode();
 | 
					        Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1252,8 +1227,8 @@ namespace MWWorld
 | 
				
			||||||
        if (!ref)
 | 
					        if (!ref)
 | 
				
			||||||
            return Vector2(0, 1);
 | 
					            return Vector2(0, 1);
 | 
				
			||||||
        Ogre::SceneNode* node = ref->mData.getBaseNode();
 | 
					        Ogre::SceneNode* node = ref->mData.getBaseNode();
 | 
				
			||||||
        Vector3 dir = node->_getDerivedOrientation().yAxis();
 | 
					        Vector3 dir = node->_getDerivedOrientation() * Ogre::Vector3(0,1,0);
 | 
				
			||||||
        Vector2 d = Vector2(dir.x, dir.z);
 | 
					        Vector2 d = Vector2(dir.x, dir.y);
 | 
				
			||||||
        return d;
 | 
					        return d;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1323,7 +1298,7 @@ namespace MWWorld
 | 
				
			||||||
        if (isCellExterior())
 | 
					        if (isCellExterior())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int cellX, cellY;
 | 
					            int cellX, cellY;
 | 
				
			||||||
            positionToIndex(result.second[0], -result.second[2], cellX, cellY);
 | 
					            positionToIndex(result.second[0], result.second[1], cellX, cellY);
 | 
				
			||||||
            cell = mCells.getExterior(cellX, cellY);
 | 
					            cell = mCells.getExterior(cellX, cellY);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
| 
						 | 
					@ -1331,8 +1306,8 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ESM::Position pos = getPlayer().getPlayer().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[1];
 | 
				
			||||||
        pos.pos[2] = result.second[1];
 | 
					        pos.pos[2] = result.second[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ptr dropped = copyObjectToCell(object, *cell, pos);
 | 
					        Ptr dropped = copyObjectToCell(object, *cell, pos);
 | 
				
			||||||
        PCDropped(dropped);
 | 
					        PCDropped(dropped);
 | 
				
			||||||
| 
						 | 
					@ -1416,25 +1391,42 @@ namespace MWWorld
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool
 | 
					    bool
 | 
				
			||||||
    World::isSwimming(const MWWorld::Ptr &object)
 | 
					    World::isFlying(const MWWorld::Ptr &ptr) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const MWWorld::Class &cls = MWWorld::Class::get(ptr);
 | 
				
			||||||
 | 
					        if(cls.isActor() && cls.getCreatureStats(ptr).getMagicEffects().get(MWMechanics::EffectKey(10/*levitate*/)).mMagnitude > 0)
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool
 | 
				
			||||||
 | 
					    World::isSwimming(const MWWorld::Ptr &object) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /// \todo add check ifActor() - only actors can swim
 | 
					        /// \todo add check ifActor() - only actors can swim
 | 
				
			||||||
        float *fpos = object.getRefData().getPosition().pos;
 | 
					        float *fpos = object.getRefData().getPosition().pos;
 | 
				
			||||||
        Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
 | 
					        Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// \fixme should rely on object height
 | 
					        /// \fixme 3/4ths submerged?
 | 
				
			||||||
        pos.z += 30;
 | 
					        const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(object.getRefData().getHandle());
 | 
				
			||||||
 | 
					        if(actor) pos.z += actor->getHalfExtents().z * 1.5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return isUnderwater(*object.getCell()->mCell, pos);
 | 
					        return isUnderwater(object.getCell(), pos);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool
 | 
					    bool
 | 
				
			||||||
    World::isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos)
 | 
					    World::isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (!(cell.mData.mFlags & ESM::Cell::HasWater)) {
 | 
					        if (!(cell->mCell->mData.mFlags & ESM::Cell::HasWater)) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return pos.z < cell.mWater;
 | 
					        return pos.z < cell->mWaterLevel;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool World::isOnGround(const MWWorld::Ptr &ptr) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        RefData &refdata = ptr.getRefData();
 | 
				
			||||||
 | 
					        const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
 | 
				
			||||||
 | 
					        return physactor && physactor->getOnGround();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void World::renderPlayer()
 | 
					    void World::renderPlayer()
 | 
				
			||||||
| 
						 | 
					@ -1451,24 +1443,21 @@ namespace MWWorld
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
 | 
					        Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ogre::Vector3 playerPos;
 | 
					        RefData &refdata = mPlayer->getPlayer().getRefData();
 | 
				
			||||||
        float* pos = mPlayer->getPlayer ().getRefData ().getPosition ().pos;
 | 
					        Ogre::Vector3 playerPos(refdata.getPosition().pos);
 | 
				
			||||||
        playerPos.x = pos[0];
 | 
					 | 
				
			||||||
        playerPos.y = pos[1];
 | 
					 | 
				
			||||||
        playerPos.z = pos[2];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::pair<bool, Ogre::Vector3> hit =
 | 
					        const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
 | 
				
			||||||
                mPhysics->castRay(playerPos, Ogre::Vector3(0,0,-1), 50);
 | 
					        if(!physactor->getOnGround() || isUnderwater(currentCell, playerPos))
 | 
				
			||||||
        bool isOnGround = (hit.first ? (hit.second.distance (playerPos) < 25) : false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!isOnGround || isUnderwater (*currentCell->mCell, playerPos))
 | 
					 | 
				
			||||||
            return 2;
 | 
					            return 2;
 | 
				
			||||||
 | 
					        if((currentCell->mCell->mData.mFlags&ESM::Cell::NoSleep))
 | 
				
			||||||
        if (currentCell->mCell->mData.mFlags & ESM::Cell::NoSleep)
 | 
					 | 
				
			||||||
            return 1;
 | 
					            return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MWRender::Animation* World::getAnimation(const MWWorld::Ptr &ptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return mRendering->getAnimation(ptr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void World::playVideo (const std::string &name, bool allowSkipping)
 | 
					    void World::playVideo (const std::string &name, bool allowSkipping)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@ namespace MWRender
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class SkyManager;
 | 
					    class SkyManager;
 | 
				
			||||||
    class CellRender;
 | 
					    class CellRender;
 | 
				
			||||||
 | 
					    class Animation;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWWorld
 | 
					namespace MWWorld
 | 
				
			||||||
| 
						 | 
					@ -264,8 +265,7 @@ namespace MWWorld
 | 
				
			||||||
            virtual void positionToIndex (float x, float y, int &cellX, int &cellY) const;
 | 
					            virtual void positionToIndex (float x, float y, int &cellX, int &cellY) const;
 | 
				
			||||||
            ///< Convert position to cell numbers
 | 
					            ///< Convert position to cell numbers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
 | 
					            virtual void doPhysics(const PtrMovementList &actors, float duration);
 | 
				
			||||||
                float duration);
 | 
					 | 
				
			||||||
            ///< Run physics simulation and modify \a world accordingly.
 | 
					            ///< Run physics simulation and modify \a world accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual bool toggleCollisionMode();
 | 
					            virtual bool toggleCollisionMode();
 | 
				
			||||||
| 
						 | 
					@ -298,18 +298,6 @@ namespace MWWorld
 | 
				
			||||||
            /// \return pointer to created record
 | 
					            /// \return pointer to created record
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName,
 | 
					 | 
				
			||||||
                int mode, int number = 1);
 | 
					 | 
				
			||||||
            ///< Run animation for a MW-reference. Calls to this function for references that are
 | 
					 | 
				
			||||||
            /// currently not in the rendered scene should be ignored.
 | 
					 | 
				
			||||||
            ///
 | 
					 | 
				
			||||||
            /// \param mode: 0 normal, 1 immediate start, 2 immediate loop
 | 
					 | 
				
			||||||
            /// \param number How offen the animation should be run
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            virtual void skipAnimation (const MWWorld::Ptr& ptr);
 | 
					 | 
				
			||||||
            ///< Skip the animation for the given MW-reference for one frame. Calls to this function for
 | 
					 | 
				
			||||||
            /// references that are currently not in the rendered scene should be ignored.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            virtual void update (float duration, bool paused);
 | 
					            virtual void update (float duration, bool paused);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual bool placeObject (const Ptr& object, float cursorX, float cursorY);
 | 
					            virtual bool placeObject (const Ptr& object, float cursorX, float cursorY);
 | 
				
			||||||
| 
						 | 
					@ -326,8 +314,10 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void processChangedSettings(const Settings::CategorySettingVector& settings);
 | 
					            virtual void processChangedSettings(const Settings::CategorySettingVector& settings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual bool isSwimming(const MWWorld::Ptr &object);
 | 
					            virtual bool isFlying(const MWWorld::Ptr &ptr) const;
 | 
				
			||||||
            virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos);
 | 
					            virtual bool isSwimming(const MWWorld::Ptr &object) const;
 | 
				
			||||||
 | 
					            virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const;
 | 
				
			||||||
 | 
					            virtual bool isOnGround(const MWWorld::Ptr &ptr) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void togglePOV() {
 | 
					            virtual void togglePOV() {
 | 
				
			||||||
                mRendering->togglePOV();
 | 
					                mRendering->togglePOV();
 | 
				
			||||||
| 
						 | 
					@ -360,6 +350,9 @@ namespace MWWorld
 | 
				
			||||||
            /// 2 - player is underwater \n
 | 
					            /// 2 - player is underwater \n
 | 
				
			||||||
            /// 3 - enemies are nearby (not implemented)
 | 
					            /// 3 - enemies are nearby (not implemented)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// \todo Probably shouldn't be here
 | 
				
			||||||
 | 
					            virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /// \todo this does not belong here
 | 
					            /// \todo this does not belong here
 | 
				
			||||||
            virtual void playVideo(const std::string& name, bool allowSkipping);
 | 
					            virtual void playVideo(const std::string& name, bool allowSkipping);
 | 
				
			||||||
            virtual void stopVideo();
 | 
					            virtual void stopVideo();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue