Merged next

actorid
Alexander "Ace" Olofsson 13 years ago
commit b1af18e98d

@ -15,7 +15,7 @@ include (OpenMWMacros)
# Version
set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 13)
set (OPENMW_VERSION_MINOR 14)
set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
@ -27,6 +27,11 @@ configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
# Apps and tools
option(BUILD_ESMTOOL "build ESM inspector" ON)
option(BUILD_LAUNCHER "build Launcher" ON)
option(BUILD_MWINIIMPORTER "build MWiniImporter" ON)
# Sound source selection
option(USE_FFMPEG "use ffmpeg for sound" OFF)
option(USE_AUDIERE "use audiere for sound" OFF)
@ -97,6 +102,7 @@ set(OENGINE_OGRE
${LIBDIR}/openengine/ogre/renderer.cpp
${LIBDIR}/openengine/ogre/mouselook.cpp
${LIBDIR}/openengine/ogre/fader.cpp
${LIBDIR}/openengine/ogre/imagerotate.cpp
)
set(OENGINE_GUI
${LIBDIR}/openengine/gui/events.cpp
@ -116,6 +122,7 @@ set(OENGINE_BULLET
${LIBDIR}/openengine/bullet/physic.hpp
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
${LIBDIR}/openengine/bullet/BulletShapeLoader.h
)
set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET})
@ -203,16 +210,16 @@ include_directories("."
link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
if(APPLE)
if (APPLE)
# List used Ogre plugins
SET(USED_OGRE_PLUGINS "RenderSystem_GL"
"Plugin_OctreeSceneManager"
"Plugin_CgProgramManager"
"Plugin_ParticleFX")
endif(APPLE)
SET(USED_OGRE_PLUGINS ${OGRE_RenderSystem_GL_LIBRARY_REL}
${OGRE_Plugin_OctreeSceneManager_LIBRARY_REL}
${OGRE_Plugin_CgProgramManager_LIBRARY_REL}
${OGRE_Plugin_ParticleFX_LIBRARY_REL})
endif (APPLE)
add_subdirectory( files/)
add_subdirectory( files/mygui )
add_subdirectory(files/)
add_subdirectory(files/mygui)
# Specify build paths
@ -227,6 +234,9 @@ endif (APPLE)
configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
"${OpenMW_BINARY_DIR}/settings-default.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/transparency-overrides.cfg
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
"${OpenMW_BINARY_DIR}/openmw.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
@ -240,37 +250,42 @@ endif (WIN32)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.linux
"${OpenMW_BINARY_DIR}/plugins.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
"${OpenMW_BINARY_DIR}/openmw.desktop")
endif()
if (APPLE)
if (${OGRE_PLUGIN_DIR_REL}})
set(OGRE_PLUGINS_REL_FOUND TRUE)
endif ()
if (${OGRE_PLUGIN_DIR_DBG})
set(OGRE_PLUGINS_DBG_FOUND TRUE)
endif ()
if (${OGRE_PLUGINS_REL_FOUND})
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
else ()
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG})
endif ()
set(OGRE_PLUGIN_DIR "${OGRE_PLUGIN_DIR}/")
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac
"${OpenMW_BINARY_DIR}/plugins.cfg")
set(OGRE_PLUGIN_DIR_2 ${OGRE_PLUGIN_DIR})
set(OGRE_PLUGIN_DIR "")
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac
"${OpenMW_BINARY_DIR}/plugins.cfg.install")
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_2})
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
"${APP_BUNDLE_DIR}/Contents/Info.plist")
configure_file(${OpenMW_SOURCE_DIR}/files/mac/openmw.icns
"${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY)
# prepare plugins
if (${CMAKE_BUILD_TYPE} MATCHES "Release")
set(OPENMW_RELEASE_BUILD 1)
endif()
if (${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo")
set(OPENMW_RELEASE_BUILD 1)
endif()
if (${OPENMW_RELEASE_BUILD})
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
else()
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG})
endif()
foreach(plugin ${USED_OGRE_PLUGINS})
configure_file("${OGRE_PLUGIN_DIR}/${plugin}.dylib"
"${APP_BUNDLE_DIR}/Contents/Plugins/${plugin}.dylib"
COPYONLY)
endforeach()
endif (APPLE)
@ -303,11 +318,12 @@ if(DPKG_PROGRAM)
endif()
#Install icon and desktop file
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
#Install global configuration files
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
@ -343,10 +359,18 @@ if(DPKG_PROGRAM)
endif(DPKG_PROGRAM)
if(WIN32)
FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*")
INSTALL(FILES ${files} DESTINATION ".")
FILE(GLOB dll_files "${OpenMW_BINARY_DIR}/Release/*.dll")
INSTALL(FILES ${dll_files} DESTINATION ".")
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg")
INSTALL(FILES "${OpenMW_SOURCE_DIR}/readme.txt" DESTINATION ".")
INSTALL(FILES
"${OpenMW_BINARY_DIR}/plugins.cfg"
"${OpenMW_SOURCE_DIR}/readme.txt"
"${OpenMW_BINARY_DIR}/launcher.qss"
"${OpenMW_BINARY_DIR}/settings-default.cfg"
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
"${OpenMW_BINARY_DIR}/Release/omwlauncher.exe"
"${OpenMW_BINARY_DIR}/Release/openmw.exe"
DESTINATION ".")
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
SET(CPACK_GENERATOR "NSIS")
@ -356,8 +380,12 @@ if(WIN32)
SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher")
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'")
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;omwlauncher;OpenMW Launcher")
SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'")
SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
!insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Readme.lnk\\\"
")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
@ -367,7 +395,7 @@ if(WIN32)
SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.ico")
SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.ico")
# SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp")
SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp")
SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe")
if(EXISTS ${VCREDIST32})
@ -401,17 +429,14 @@ add_subdirectory (components)
# Apps and tools
add_subdirectory( apps/openmw )
option(BUILD_ESMTOOL "build ESM inspector" ON)
if (BUILD_ESMTOOL)
add_subdirectory( apps/esmtool )
endif()
option(BUILD_LAUNCHER "build Launcher inspector" ON)
if (BUILD_LAUNCHER)
add_subdirectory( apps/launcher )
endif()
option(BUILD_MWINIIMPORTER "build MWiniImporter inspector" ON)
if (BUILD_MWINIIMPORTER)
add_subdirectory( apps/mwiniimporter )
endif()
@ -503,10 +528,12 @@ if (APPLE)
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg.install" RENAME "plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
set(CPACK_GENERATOR "DragNDrop")
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
@ -515,22 +542,25 @@ if (APPLE)
set(APPS "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}")
set(PLUGINS "")
set(ABSOLUTE_PLUGINS "")
# Scan Plugins dir for *.dylibs
set(PLUGIN_SEARCH_ROOT "${APP_BUNDLE_DIR}/Contents/Plugins")
file(GLOB_RECURSE ALL_PLUGINS "${PLUGIN_SEARCH_ROOT}/*.dylib")
foreach (PLUGIN ${USED_OGRE_PLUGINS})
get_filename_component(PLUGIN_ABS ${PLUGIN} REALPATH)
set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS})
endforeach ()
set(PLUGIN_INSTALL_BASE "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins")
foreach(PLUGIN ${ALL_PLUGINS})
string(REPLACE "${PLUGIN_SEARCH_ROOT}/" "" PLUGIN_RELATIVE "${PLUGIN}")
install(FILES ${ABSOLUTE_PLUGINS} DESTINATION "${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins" COMPONENT Runtime)
foreach (PLUGIN ${ABSOLUTE_PLUGINS})
get_filename_component(PLUGIN_RELATIVE ${PLUGIN} NAME)
set(PLUGINS ${PLUGINS} "${PLUGIN_INSTALL_BASE}/${PLUGIN_RELATIVE}")
endforeach()
endforeach ()
#For now, search unresolved dependencies only in default system paths, so if you put unresolveable (i.e. with @executable_path in id name) lib or framework somewhere else, it would fail
set(DIRS "")
# Overriding item resolving during installation, it needed if
# some library already has be "fixed up", i.e. its id name contains @executable_path,
# some library already has been "fixed up", i.e. its id name contains @executable_path,
# but library is not embedded in bundle. For example, it's Ogre.framework from Ogre SDK.
# Current implementation of GetPrerequsities/BundleUtilities doesn't handle that case.
#
@ -548,17 +578,22 @@ if (APPLE)
if (item MATCHES \"Frameworks\") # if it is a framework
# get last segment of path
get_filename_component(fname \"\${item}\" NAME_WE)
find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} /Library/Frameworks)
find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} \${CMAKE_SYSTEM_FRAMEWORK_PATH})
if (ri)
message(STATUS \"found \${ri} for \${item}\")
string(REGEX REPLACE \"^.*/Frameworks/.*\\\\.framework\" \"\" item_part \${item})
set(ri \"\${ri}\${item_part}\")
set(\${resolved_item_var} \${ri} PARENT_SCOPE)
set(\${resolved_var} 1 PARENT_SCOPE)
set(OPENMW_RESOLVED_ITEMS \${_OPENMW_RESOLVED_ITEMS} \${ri})
endif()
else()
# code path for standard (non-framework) libs (ogre & qt pugins)
get_filename_component(fname \"\${item}\" NAME_WE)
string(REGEX REPLACE \"^lib\" \"\" fname \${fname})
find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} /usr/lib /usr/local/lib)
if (ri)
set(\${resolved_item_var} \${ri} PARENT_SCOPE)
set(\${resolved_var} 1 PARENT_SCOPE)
endif ()
endif()
endif()
endfunction(gp_resolve_item_override)
@ -568,10 +603,5 @@ if (APPLE)
include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"${PLUGINS}\" \"${DIRS}\")
" COMPONENT Runtime)
include(CPack)
set(CMAKE_EXE_LINKER_FLAGS "-arch i386")
set(CMAKE_CXX_FLAGS "-arch i386")
include(CPack)
endif (APPLE)

@ -15,7 +15,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
renderinginterface localmap occlusionquery terrain terrainmaterial water
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows shaderhelper
)
add_openmw_dir (mwinput
@ -25,6 +25,7 @@ add_openmw_dir (mwinput
add_openmw_dir (mwgui
layouts text_input widgets race class birth review window_manager console dialogue
dialogue_history window_base stats_window messagebox journalwindow charactercreation
map_window window_pinnable_base cursorreplace
)
add_openmw_dir (mwdialogue
@ -43,7 +44,7 @@ add_openmw_dir (mwsound
)
add_openmw_dir (mwworld
refdata world physicssystem scene environment globals class action nullaction actionteleport
refdata world physicssystem scene globals class action nullaction actionteleport
containerstore actiontalk actiontake manualref player cellfunctors
cells localscripts customdata weather inventorystore ptr
)
@ -54,7 +55,11 @@ add_openmw_dir (mwclass
)
add_openmw_dir (mwmechanics
mechanicsmanager stat creaturestats magiceffects movement
mechanicsmanager stat creaturestats magiceffects movement actors drawstate spells
)
add_openmw_dir (mwbase
environment
)
# Main executable

@ -21,6 +21,7 @@
#include <components/files/fixedpath.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/settings/settings.hpp>
#include <components/nifoverrides/nifoverrides.hpp>
#include <components/nifbullet/bullet_nif_loader.hpp>
#include <components/nifogre/ogre_nif_loader.hpp>
@ -28,6 +29,7 @@
#include "mwinput/inputmanager.hpp"
#include "mwgui/window_manager.hpp"
#include "mwgui/cursorreplace.hpp"
#include "mwscript/scriptmanager.hpp"
#include "mwscript/compilercontext.hpp"
@ -48,10 +50,12 @@
#include "mwmechanics/mechanicsmanager.hpp"
#include "mwbase/environment.hpp"
void OMW::Engine::executeLocalScripts()
{
MWWorld::LocalScripts& localScripts = mEnvironment.mWorld->getLocalScripts();
MWWorld::LocalScripts& localScripts = MWBase::Environment::get().getWorld()->getLocalScripts();
localScripts.startIteration();
@ -59,11 +63,11 @@ void OMW::Engine::executeLocalScripts()
{
std::pair<std::string, MWWorld::Ptr> script = localScripts.getNext();
MWScript::InterpreterContext interpreterContext (mEnvironment,
MWScript::InterpreterContext interpreterContext (
&script.second.getRefData().getLocals(), script.second);
mEnvironment.mScriptManager->run (script.first, interpreterContext);
MWBase::Environment::get().getScriptManager()->run (script.first, interpreterContext);
if (mEnvironment.mWorld->hasCellChanged())
if (MWBase::Environment::get().getWorld()->hasCellChanged())
break;
}
@ -79,7 +83,7 @@ void OMW::Engine::updateFocusReport (float duration)
std::string name;
std::string handle = mEnvironment.mWorld->getFacedHandle();
std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle();
if (!handle.empty())
{
@ -88,7 +92,7 @@ void OMW::Engine::updateFocusReport (float duration)
// therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case
try
{
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle);
if (!ptr.isEmpty()){
name = MWWorld::Class::get (ptr).getName (ptr);
@ -122,27 +126,27 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
{
try
{
mEnvironment.mFrameDuration = evt.timeSinceLastFrame;
mEnvironment.setFrameDuration (evt.timeSinceLastFrame);
// update input
mEnvironment.mInputManager->update();
MWBase::Environment::get().getInputManager()->update();
// sound
if (mUseSound)
mEnvironment.mSoundManager->update (evt.timeSinceLastFrame);
MWBase::Environment::get().getSoundManager()->update (evt.timeSinceLastFrame);
// update GUI
Ogre::RenderWindow* window = mOgre->getWindow();
mEnvironment.mWindowManager->wmUpdateFps(window->getLastFPS(),
MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(),
window->getTriangleCount(),
window->getBatchCount());
mEnvironment.mWindowManager->onFrame(mEnvironment.mFrameDuration);
MWBase::Environment::get().getWindowManager()->onFrame(mEnvironment.getFrameDuration());
// global scripts
mEnvironment.mGlobalScripts->run (mEnvironment);
MWBase::Environment::get().getScriptManager()->getGlobalScripts().run();
bool changed = mEnvironment.mWorld->hasCellChanged();
bool changed = MWBase::Environment::get().getWorld()->hasCellChanged();
// local scripts
executeLocalScripts(); // This does not handle the case where a global script causes a cell
@ -150,27 +154,28 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
// frame.
// passing of time
if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game)
mEnvironment.mWorld->advanceTime (
mEnvironment.mFrameDuration*mEnvironment.mWorld->getTimeScaleFactor()/3600);
if (MWBase::Environment::get().getWindowManager()->getMode()==MWGui::GM_Game)
MWBase::Environment::get().getWorld()->advanceTime (
mEnvironment.getFrameDuration()*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600);
if (changed) // keep change flag for another frame, if cell changed happend in local script
mEnvironment.mWorld->markCellAsUnchanged();
MWBase::Environment::get().getWorld()->markCellAsUnchanged();
// update actors
std::vector<std::pair<std::string, Ogre::Vector3> > movement;
mEnvironment.mMechanicsManager->update (movement);
MWBase::Environment::get().getMechanicsManager()->update (movement, mEnvironment.getFrameDuration(),
MWBase::Environment::get().getWindowManager()->getMode()!=MWGui::GM_Game);
if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game)
mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration);
if (MWBase::Environment::get().getWindowManager()->getMode()==MWGui::GM_Game)
MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration());
// update world
mEnvironment.mWorld->update (evt.timeSinceLastFrame);
MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame);
// report focus object (for debugging)
if (mReportFocus)
updateFocusReport (mEnvironment.mFrameDuration);
updateFocusReport (mEnvironment.getFrameDuration());
}
catch (const std::exception& e)
{
@ -200,13 +205,13 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
OMW::Engine::~Engine()
{
delete mEnvironment.mWorld;
delete mEnvironment.mSoundManager;
delete mEnvironment.mGlobalScripts;
delete mEnvironment.mMechanicsManager;
delete mEnvironment.mDialogueManager;
delete mEnvironment.mJournal;
delete mEnvironment.mScriptManager;
delete MWBase::Environment::get().getInputManager();
delete MWBase::Environment::get().getSoundManager();
delete MWBase::Environment::get().getMechanicsManager();
delete MWBase::Environment::get().getDialogueManager();
delete MWBase::Environment::get().getJournal();
delete MWBase::Environment::get().getScriptManager();
delete MWBase::Environment::get().getWorld();
delete mScriptContext;
delete mOgre;
}
@ -216,7 +221,7 @@ OMW::Engine::~Engine()
void OMW::Engine::loadBSA()
{
const Files::MultiDirCollection& bsa = mFileCollections.getCollection (".bsa");
for (Files::MultiDirCollection::TIter iter(bsa.begin()); iter!=bsa.end(); ++iter)
{
std::cout << "Adding " << iter->second.string() << std::endl;
@ -310,7 +315,6 @@ void OMW::Engine::setReportFocus (bool report)
void OMW::Engine::go()
{
mFocusTDiff = 0;
assert (!mEnvironment.mWorld);
assert (!mCellName.empty());
assert (!mMaster.empty());
assert (!mOgre);
@ -348,6 +352,13 @@ void OMW::Engine::go()
mFpsLevel = settings.getInt("fps", "HUD");
// load nif overrides
NifOverrides::Overrides nifOverrides;
if (boost::filesystem::exists(mCfgMgr.getLocalPath().string() + "/transparency-overrides.cfg"))
nifOverrides.loadTransparencyOverrides(mCfgMgr.getLocalPath().string() + "/transparency-overrides.cfg");
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"))
nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg");
mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()),
mCfgMgr.getOgreConfigPath().string(),
mCfgMgr.getLogPath().string(),
@ -357,79 +368,81 @@ void OMW::Engine::go()
// to find core.xml here.
//addResourcesDirectory(mResDir);
addResourcesDirectory(mResDir / "mygui");
addResourcesDirectory(mResDir / "water");
addResourcesDirectory(mResDir / "gbuffer");
addResourcesDirectory(mResDir / "shadows");
// Create the window
mOgre->createWindow("OpenMW");
loadBSA();
// cursor replacer (converts the cursor from the bsa so they can be used by mygui)
MWGui::CursorReplace replacer;
// Create the world
mEnvironment.mWorld = new MWWorld::World (*mOgre, mFileCollections, mMaster,
mResDir, mNewGame, mEnvironment, mEncoding, mFallbackMap);
mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster,
mResDir, mNewGame, mEncoding, mFallbackMap));
// Create window manager - this manages all the MW-specific GUI windows
MWScript::registerExtensions (mExtensions);
mEnvironment.mWindowManager = new MWGui::WindowManager(mEnvironment,
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"));
mEnvironment.setWindowManager (new MWGui::WindowManager(
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/")));
// Create sound system
mEnvironment.mSoundManager = new MWSound::SoundManager(mUseSound, mEnvironment);
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
// Create script system
mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full,
mEnvironment);
mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full);
mScriptContext->setExtensions (&mExtensions);
mEnvironment.mScriptManager = new MWScript::ScriptManager (mEnvironment.mWorld->getStore(),
mVerboseScripts, *mScriptContext);
mEnvironment.mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(),
*mEnvironment.mScriptManager);
mEnvironment.setScriptManager (new MWScript::ScriptManager (MWBase::Environment::get().getWorld()->getStore(),
mVerboseScripts, *mScriptContext));
// Create game mechanics system
mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (mEnvironment);
mEnvironment.setMechanicsManager (new MWMechanics::MechanicsManager);
// Create dialog system
mEnvironment.mJournal = new MWDialogue::Journal (mEnvironment);
mEnvironment.mDialogueManager = new MWDialogue::DialogueManager (mEnvironment,mExtensions);
mEnvironment.setJournal (new MWDialogue::Journal);
mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions));
// load cell
ESM::Position pos;
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
pos.pos[2] = 0;
if (const ESM::Cell *exterior = mEnvironment.mWorld->getExterior (mCellName))
if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName))
{
mEnvironment.mWorld->indexToPosition (exterior->data.gridX, exterior->data.gridY,
MWBase::Environment::get().getWorld()->indexToPosition (exterior->data.gridX, exterior->data.gridY,
pos.pos[0], pos.pos[1], true);
mEnvironment.mWorld->changeToExteriorCell (pos);
MWBase::Environment::get().getWorld()->changeToExteriorCell (pos);
}
else
{
pos.pos[0] = pos.pos[1] = 0;
mEnvironment.mWorld->changeToInteriorCell (mCellName, pos);
MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, pos);
}
// Sets up the input system
MWInput::MWInputManager input(*mOgre, mEnvironment.mWorld->getPlayer(),
*mEnvironment.mWindowManager, mDebug, *this);
mEnvironment.mInputManager = &input;
mEnvironment.setInputManager (new MWInput::MWInputManager (*mOgre,
MWBase::Environment::get().getWorld()->getPlayer(),
*MWBase::Environment::get().getWindowManager(), mDebug, *this));
std::cout << "\nPress Q/ESC or close window to exit.\n";
mOgre->getRoot()->addFrameListener (this);
// Play some good 'ol tunes
mEnvironment.mSoundManager->playPlaylist(std::string("Explore"));
MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore"));
// scripts
if (mCompileAll)
{
std::pair<int, int> result = mEnvironment.mScriptManager->compileAll();
std::pair<int, int> result = MWBase::Environment::get().getScriptManager()->compileAll();
if (result.first)
std::cout
@ -450,10 +463,10 @@ void OMW::Engine::go()
void OMW::Engine::activate()
{
if (mEnvironment.mWindowManager->getMode()!=MWGui::GM_Game)
if (MWBase::Environment::get().getWindowManager()->getMode()!=MWGui::GM_Game)
return;
std::string handle = mEnvironment.mWorld->getFacedHandle();
std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle();
if (handle.empty())
return;
@ -464,7 +477,7 @@ void OMW::Engine::activate()
MWWorld::Ptr ptr;
try
{
ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle);
if (ptr.isEmpty())
return;
@ -474,12 +487,10 @@ void OMW::Engine::activate()
return;
}
MWScript::InterpreterContext interpreterContext (mEnvironment,
&ptr.getRefData().getLocals(), ptr);
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);
boost::shared_ptr<MWWorld::Action> action =
MWWorld::Class::get (ptr).activate (ptr, mEnvironment.mWorld->getPlayer().getPlayer(),
mEnvironment);
MWWorld::Class::get (ptr).activate (ptr, MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
interpreterContext.activate (ptr, action);
@ -487,8 +498,8 @@ void OMW::Engine::activate()
if (!script.empty())
{
mEnvironment.mWorld->getLocalScripts().setIgnore (ptr);
mEnvironment.mScriptManager->run (script, interpreterContext);
MWBase::Environment::get().getWorld()->getLocalScripts().setIgnore (ptr);
MWBase::Environment::get().getScriptManager()->run (script, interpreterContext);
}
if (!interpreterContext.hasActivationBeenHandled())

@ -10,7 +10,8 @@
#include <components/compiler/extensions.hpp>
#include <components/files/collections.hpp>
#include "mwworld/environment.hpp"
#include "mwbase/environment.hpp"
#include "mwworld/ptr.hpp"
namespace Compiler
@ -78,7 +79,7 @@ namespace OMW
std::string mFocusName;
std::map<std::string,std::string> mFallbackMap;
MWWorld::Environment mEnvironment;
MWBase::Environment mEnvironment;
Compiler::Extensions mExtensions;
Compiler::Context *mScriptContext;

@ -0,0 +1,123 @@
#include "environment.hpp"
#include <cassert>
MWBase::Environment *MWBase::Environment::sThis = 0;
MWBase::Environment::Environment()
: mWorld (0), mSoundManager (0), mScriptManager (0), mWindowManager (0),
mMechanicsManager (0), mDialogueManager (0), mJournal (0), mInputManager (0), mFrameDuration (0)
{
assert (!sThis);
sThis = this;
}
MWBase::Environment::~Environment()
{
sThis = 0;
}
void MWBase::Environment::setWorld (MWWorld::World *world)
{
mWorld = world;
}
void MWBase::Environment::setSoundManager (MWSound::SoundManager *soundManager)
{
mSoundManager = soundManager;
}
void MWBase::Environment::setScriptManager (MWScript::ScriptManager *scriptManager)
{
mScriptManager = scriptManager;
}
void MWBase::Environment::setWindowManager (MWGui::WindowManager *windowManager)
{
mWindowManager = windowManager;
}
void MWBase::Environment::setMechanicsManager (MWMechanics::MechanicsManager *mechanicsManager)
{
mMechanicsManager = mechanicsManager;
}
void MWBase::Environment::setDialogueManager (MWDialogue::DialogueManager *dialogueManager)
{
mDialogueManager = dialogueManager;
}
void MWBase::Environment::setJournal (MWDialogue::Journal *journal)
{
mJournal = journal;
}
void MWBase::Environment::setInputManager (MWInput::MWInputManager *inputManager)
{
mInputManager = inputManager;
}
void MWBase::Environment::setFrameDuration (float duration)
{
mFrameDuration = duration;
}
MWWorld::World *MWBase::Environment::getWorld() const
{
assert (mWorld);
return mWorld;
}
MWSound::SoundManager *MWBase::Environment::getSoundManager() const
{
assert (mSoundManager);
return mSoundManager;
}
MWScript::ScriptManager *MWBase::Environment::getScriptManager() const
{
assert (mScriptManager);
return mScriptManager;
}
MWGui::WindowManager *MWBase::Environment::getWindowManager() const
{
assert (mWindowManager);
return mWindowManager;
}
MWMechanics::MechanicsManager *MWBase::Environment::getMechanicsManager() const
{
assert (mMechanicsManager);
return mMechanicsManager;
}
MWDialogue::DialogueManager *MWBase::Environment::getDialogueManager() const
{
assert (mDialogueManager);
return mDialogueManager;
}
MWDialogue::Journal *MWBase::Environment::getJournal() const
{
assert (mJournal);
return mJournal;
}
MWInput::MWInputManager *MWBase::Environment::getInputManager() const
{
assert (mInputManager);
return mInputManager;
}
float MWBase::Environment::getFrameDuration() const
{
return mFrameDuration;
}
const MWBase::Environment& MWBase::Environment::get()
{
assert (sThis);
return *sThis;
}

@ -0,0 +1,116 @@
#ifndef GAME_BASE_INVIRONMENT_H
#define GAME_BASE_INVIRONMENT_H
namespace MWSound
{
class SoundManager;
}
namespace MWScript
{
class ScriptManager;
}
namespace MWGui
{
class WindowManager;
}
namespace MWMechanics
{
class MechanicsManager;
}
namespace MWDialogue
{
class DialogueManager;
class Journal;
}
namespace MWInput
{
struct MWInputManager;
}
namespace MWWorld
{
class World;
}
namespace MWBase
{
/// \brief Central hub for mw-subsystems
///
/// This class allows each mw-subsystem to access any others subsystem's top-level manager class.
///
/// \attention Environment does not take ownership of the manager class instances it is handed over in
/// the set* functions.
class Environment
{
static Environment *sThis;
MWWorld::World *mWorld;
MWSound::SoundManager *mSoundManager;
MWScript::ScriptManager *mScriptManager;
MWGui::WindowManager *mWindowManager;
MWMechanics::MechanicsManager *mMechanicsManager;
MWDialogue::DialogueManager *mDialogueManager;
MWDialogue::Journal *mJournal;
MWInput::MWInputManager *mInputManager;
float mFrameDuration;
Environment (const Environment&);
///< not implemented
Environment& operator= (const Environment&);
///< not implemented
public:
Environment();
~Environment();
void setWorld (MWWorld::World *world);
void setSoundManager (MWSound::SoundManager *soundManager);
void setScriptManager (MWScript::ScriptManager *scriptManager);
void setWindowManager (MWGui::WindowManager *windowManager);
void setMechanicsManager (MWMechanics::MechanicsManager *mechanicsManager);
void setDialogueManager (MWDialogue::DialogueManager *dialogueManager);
void setJournal (MWDialogue::Journal *journal);
void setInputManager (MWInput::MWInputManager *inputManager);
void setFrameDuration (float duration);
///< Set length of current frame in seconds.
MWWorld::World *getWorld() const;
MWSound::SoundManager *getSoundManager() const;
MWScript::ScriptManager *getScriptManager() const;
MWGui::WindowManager *getWindowManager() const;
MWMechanics::MechanicsManager *getMechanicsManager() const;
MWDialogue::DialogueManager *getDialogueManager() const;
MWDialogue::Journal *getJournal() const;
MWInput::MWInputManager *getInputManager() const;
float getFrameDuration() const;
static const Environment& get();
///< Return instance of this class.
};
}
#endif

@ -18,7 +18,7 @@ namespace MWClass
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects();
@ -27,7 +27,7 @@ namespace MWClass
}
}
void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Activator, MWWorld::RefData> *ref =
ptr.get<ESM::Activator>();

@ -12,7 +12,7 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.hpp"
@ -31,7 +32,7 @@ namespace MWClass
}
}
void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
ptr.get<ESM::Apparatus>();
@ -54,9 +55,9 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Apparatus::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -70,6 +71,14 @@ namespace MWClass
return ref->base->script;
}
int Apparatus::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->data.value;
}
void Apparatus::registerSelf()
{
boost::shared_ptr<Class> instance (new Apparatus);

@ -12,19 +12,22 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;

@ -9,11 +9,11 @@
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwrender/objects.hpp"
#include "../mwsound/soundmanager.hpp"
@ -36,7 +36,7 @@ namespace MWClass
}
}
void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
ptr.get<ESM::Armor>();
@ -58,9 +58,9 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Armor::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -121,7 +121,7 @@ namespace MWClass
return std::make_pair (slots, false);
}
int Armor::getEquipmentSkill (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
int Armor::getEquipmentSkill (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
ptr.get<ESM::Armor>();
@ -147,19 +147,27 @@ namespace MWClass
if (typeGmst.empty())
return -1;
float iWeight = environment.mWorld->getStore().gameSettings.find (typeGmst)->i;
float iWeight = MWBase::Environment::get().getWorld()->getStore().gameSettings.find (typeGmst)->i;
if (iWeight * environment.mWorld->getStore().gameSettings.find ("fLightMaxMod")->f>=
if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fLightMaxMod")->f>=
ref->base->data.weight)
return ESM::Skill::LightArmor;
if (iWeight * environment.mWorld->getStore().gameSettings.find ("fMedMaxMod")->f>=
if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMedMaxMod")->f>=
ref->base->data.weight)
return ESM::Skill::MediumArmor;
return ESM::Skill::HeavyArmor;
}
int Armor::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
ptr.get<ESM::Armor>();
return ref->base->data.value;
}
void Armor::registerSelf()
{
boost::shared_ptr<Class> instance (new Armor);
@ -167,9 +175,9 @@ namespace MWClass
registerClass (typeid (ESM::Armor).name(), instance);
}
std::string Armor::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Armor::getUpSoundId (const MWWorld::Ptr& ptr) const
{
int es = getEquipmentSkill(ptr, environment);
int es = getEquipmentSkill(ptr);
if (es == ESM::Skill::LightArmor)
return std::string("Item Armor Light Up");
else if (es == ESM::Skill::MediumArmor)
@ -178,9 +186,9 @@ namespace MWClass
return std::string("Item Armor Heavy Up");
}
std::string Armor::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Armor::getDownSoundId (const MWWorld::Ptr& ptr) const
{
int es = getEquipmentSkill(ptr, environment);
int es = getEquipmentSkill(ptr);
if (es == ESM::Skill::LightArmor)
return std::string("Item Armor Light Down");
else if (es == ESM::Skill::MediumArmor)

@ -12,14 +12,14 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const;
@ -35,17 +35,19 @@ namespace MWClass
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped?
virtual int getEquipmentSkill (const MWWorld::Ptr& ptr,
const MWWorld::Environment& environment) const;
virtual int getEquipmentSkill (const MWWorld::Ptr& ptr) const;
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
/// no such skill.
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.hpp"
@ -31,7 +32,7 @@ namespace MWClass
}
}
void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
ptr.get<ESM::Book>();
@ -54,11 +55,11 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
// TODO implement reading
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -72,6 +73,14 @@ namespace MWClass
return ref->base->script;
}
int Book::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
ptr.get<ESM::Book>();
return ref->base->data.value;
}
void Book::registerSelf()
{
boost::shared_ptr<Class> instance (new Book);
@ -79,12 +88,12 @@ namespace MWClass
registerClass (typeid (ESM::Book).name(), instance);
}
std::string Book::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Book::getUpSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Book Up");
}
std::string Book::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Book::getDownSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Book Down");
}

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwrender/objects.hpp"
@ -32,7 +33,7 @@ namespace MWClass
}
}
void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>();
@ -55,9 +56,9 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Clothing::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -89,7 +90,7 @@ namespace MWClass
static const int sMapping[size][2] =
{
{ ESM::Clothing::Shirt, MWWorld::InventoryStore::Slot_Cuirass },
{ ESM::Clothing::Shirt, MWWorld::InventoryStore::Slot_Shirt },
{ ESM::Clothing::Belt, MWWorld::InventoryStore::Slot_Belt },
{ ESM::Clothing::Robe, MWWorld::InventoryStore::Slot_Robe },
{ ESM::Clothing::Pants, MWWorld::InventoryStore::Slot_Pants },
@ -111,8 +112,7 @@ namespace MWClass
return std::make_pair (slots, false);
}
int Clothing::getEquipmentSkill (const MWWorld::Ptr& ptr,
const MWWorld::Environment& environment) const
int Clothing::getEquipmentSkill (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>();
@ -123,6 +123,14 @@ namespace MWClass
return -1;
}
int Clothing::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>();
return ref->base->data.value;
}
void Clothing::registerSelf()
{
boost::shared_ptr<Class> instance (new Clothing);
@ -130,7 +138,7 @@ namespace MWClass
registerClass (typeid (ESM::Clothing).name(), instance);
}
std::string Clothing::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Clothing::getUpSoundId (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>();
@ -142,7 +150,7 @@ namespace MWClass
return std::string("Item Clothes Up");
}
std::string Clothing::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Clothing::getDownSoundId (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>();

@ -12,14 +12,14 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
@ -29,17 +29,19 @@ namespace MWClass
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped?
virtual int getEquipmentSkill (const MWWorld::Ptr& ptr,
const MWWorld::Environment& environment) const;
virtual int getEquipmentSkill (const MWWorld::Ptr& ptr) const;
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
/// no such skill.
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -5,11 +5,12 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/customdata.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.hpp"
@ -61,7 +62,7 @@ namespace MWClass
}
}
void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
ptr.get<ESM::Container>();
@ -76,7 +77,7 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Container::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
const std::string lockedSound = "LockedChest";
const std::string trapActivationSound = "Disarm Trap Fail";
@ -85,7 +86,7 @@ namespace MWClass
{
// TODO check for key
std::cout << "Locked container" << std::endl;
environment.mSoundManager->playSound3D (ptr, lockedSound, 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, lockedSound, 1.0, 1.0);
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
}
else
@ -100,7 +101,7 @@ namespace MWClass
{
// Trap activation goes here
std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl;
environment.mSoundManager->playSound3D (ptr, trapActivationSound, 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, trapActivationSound, 1.0, 1.0);
ptr.getCellRef().trap = "";
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
}

@ -14,14 +14,14 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const;

@ -6,9 +6,10 @@
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/mechanicsmanager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/customdata.hpp"
#include "../mwworld/containerstore.hpp"
@ -74,7 +75,7 @@ namespace MWClass
actors.insertCreature(ptr);
}
void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
ptr.get<ESM::Creature>();
@ -87,14 +88,14 @@ namespace MWClass
}
}
void Creature::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
void Creature::enable (const MWWorld::Ptr& ptr) const
{
environment.mMechanicsManager->addActor (ptr);
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
}
void Creature::disable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
void Creature::disable (const MWWorld::Ptr& ptr) const
{
environment.mMechanicsManager->removeActor (ptr);
MWBase::Environment::get().getMechanicsManager()->removeActor (ptr);
}
std::string Creature::getName (const MWWorld::Ptr& ptr) const
@ -113,7 +114,7 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Creature::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
}

@ -20,12 +20,12 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual void enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const;
virtual void enable (const MWWorld::Ptr& ptr) const;
///< Enable reference; only does the non-rendering part
virtual void disable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const;
virtual void disable (const MWWorld::Ptr& ptr) const;
///< Enable reference; only does the non-rendering part
virtual std::string getName (const MWWorld::Ptr& ptr) const;
@ -36,7 +36,7 @@ namespace MWClass
///< Return creature stats
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual MWWorld::ContainerStore& getContainerStore (

@ -5,11 +5,12 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwworld/actionteleport.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwrender/objects.hpp"
@ -34,7 +35,7 @@ namespace MWClass
}
}
void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
ptr.get<ESM::Door>();
@ -58,7 +59,7 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Door::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
ptr.get<ESM::Door>();
@ -73,7 +74,7 @@ namespace MWClass
// TODO check for key
// TODO report failure to player (message, sound?). Look up behaviour of original MW.
std::cout << "Locked!" << std::endl;
environment.mSoundManager->playSound3D (ptr, lockedSound, 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, lockedSound, 1.0, 1.0);
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
}
@ -81,7 +82,7 @@ namespace MWClass
{
// Trap activation
std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl;
environment.mSoundManager->playSound3D(ptr, trapActivationSound, 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, trapActivationSound, 1.0, 1.0);
ptr.getCellRef().trap = "";
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
}
@ -89,11 +90,11 @@ namespace MWClass
if (ref->ref.teleport)
{
// teleport door
if (environment.mWorld->getPlayer().getPlayer()==actor)
if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor)
{
// the player is using the door
// The reason this is not 3D is that it would get interrupted when you teleport
environment.mSoundManager->playSound(openSound, 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound(openSound, 1.0, 1.0);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTeleportPlayer (ref->ref.destCell, ref->ref.doorDest));
}
@ -110,7 +111,7 @@ namespace MWClass
// TODO return action for rotating the door
// This is a little pointless, but helps with testing
environment.mSoundManager->playSound3D (ptr, openSound, 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, openSound, 1.0, 1.0);
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
}
}

@ -12,14 +12,14 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.hpp"
@ -31,7 +32,7 @@ namespace MWClass
}
}
void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
ptr.get<ESM::Ingredient>();
@ -52,9 +53,9 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Ingredient::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -68,6 +69,14 @@ namespace MWClass
return ref->base->script;
}
int Ingredient::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->data.value;
}
void Ingredient::registerSelf()
{
boost::shared_ptr<Class> instance (new Ingredient);
@ -75,12 +84,12 @@ namespace MWClass
registerClass (typeid (ESM::Ingredient).name(), instance);
}
std::string Ingredient::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Ingredient::getUpSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Ingredient Up");
}
std::string Ingredient::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Ingredient::getDownSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Ingredient Down");
}

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -5,10 +5,11 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwsound/soundmanager.hpp"
@ -39,7 +40,7 @@ namespace MWClass
objects.insertLight (ptr, r, g, b, radius);
}
void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>();
@ -52,14 +53,14 @@ namespace MWClass
}
}
void Light::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
void Light::enable (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>();
if (!ref->base->sound.empty())
{
environment.mSoundManager->playSound3D (ptr, ref->base->sound, 1.0, 1.0, MWSound::Play_Loop);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, ref->base->sound, 1.0, 1.0, MWSound::Play_Loop);
}
}
@ -75,7 +76,7 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Light::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>();
@ -83,7 +84,7 @@ namespace MWClass
if (!(ref->base->data.flags & ESM::Light::Carry))
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -110,6 +111,14 @@ namespace MWClass
return std::make_pair (slots, false);
}
int Light::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>();
return ref->base->data.value;
}
void Light::registerSelf()
{
boost::shared_ptr<Class> instance (new Light);
@ -117,12 +126,12 @@ namespace MWClass
registerClass (typeid (ESM::Light).name(), instance);
}
std::string Light::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Light::getUpSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Misc Up");
}
std::string Light::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Light::getDownSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Misc Down");
}

@ -12,9 +12,9 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual void enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const;
virtual void enable (const MWWorld::Ptr& ptr) const;
///< Enable reference; only does the non-rendering part
/// \attention This is not the same as the script instruction with the same name. References
/// should only be enabled while in an active cell.
@ -24,7 +24,7 @@ namespace MWClass
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
@ -34,12 +34,15 @@ namespace MWClass
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped?
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwrender/objects.hpp"
@ -32,7 +33,7 @@ namespace MWClass
}
}
void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
ptr.get<ESM::Tool>();
@ -56,9 +57,9 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Lockpick::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -81,6 +82,14 @@ namespace MWClass
return std::make_pair (slots, false);
}
int Lockpick::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
ptr.get<ESM::Tool>();
return ref->base->data.value;
}
void Lockpick::registerSelf()
{
boost::shared_ptr<Class> instance (new Lockpick);
@ -88,12 +97,12 @@ namespace MWClass
registerClass (typeid (ESM::Tool).name(), instance);
}
std::string Lockpick::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Lockpick::getUpSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Lockpick Up");
}
std::string Lockpick::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Lockpick::getDownSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Lockpick Down");
}

@ -12,14 +12,14 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
@ -29,12 +29,15 @@ namespace MWClass
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped?
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.hpp"
@ -31,7 +32,7 @@ namespace MWClass
}
}
void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
ptr.get<ESM::Miscellaneous>();
@ -54,9 +55,9 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Miscellaneous::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -70,6 +71,14 @@ namespace MWClass
return ref->base->script;
}
int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->data.value;
}
void Miscellaneous::registerSelf()
{
boost::shared_ptr<Class> instance (new Miscellaneous);
@ -77,7 +86,7 @@ namespace MWClass
registerClass (typeid (ESM::Miscellaneous).name(), instance);
}
std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
ptr.get<ESM::Miscellaneous>();
@ -89,7 +98,7 @@ namespace MWClass
return std::string("Item Misc Up");
}
std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
ptr.get<ESM::Miscellaneous>();

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -14,11 +14,12 @@
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/customdata.hpp"
#include "../mwbase/environment.hpp"
namespace
{
const Ogre::Radian kOgrePi (Ogre::Math::PI);
@ -53,28 +54,40 @@ namespace MWClass
// NPC stats
if (!ref->base->faction.empty())
{
// TODO research how initial rank is stored. The information in loadnpc.hpp are at
// best very unclear.
data->mNpcStats.mFactionRank[ref->base->faction] = 0;
if(ref->base->npdt52.gold != -10)
{
data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt52.rank;
}
else
{
data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt12.rank;
}
}
for (int i=0; i<27; ++i)
data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]);
// creature stats
data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength);
data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence);
data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower);
data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility);
data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed);
data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance);
data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality);
data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck);
data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health);
data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana);
data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue);
data->mCreatureStats.mLevel = ref->base->npdt52.level;
if(ref->base->npdt52.gold != -10)
{
for (int i=0; i<27; ++i)
data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]);
// creature stats
data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength);
data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence);
data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower);
data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility);
data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed);
data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance);
data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality);
data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck);
data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health);
data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana);
data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue);
data->mCreatureStats.mLevel = ref->base->npdt52.level;
}
else
{
//TODO: do something with npdt12 maybe:p
}
// \todo add initial container content
@ -93,10 +106,13 @@ namespace MWClass
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{
renderingInterface.getActors().insertNPC(ptr);
renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr));
}
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
@ -118,14 +134,14 @@ namespace MWClass
}
void Npc::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
void Npc::enable (const MWWorld::Ptr& ptr) const
{
environment.mMechanicsManager->addActor (ptr);
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
}
void Npc::disable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
void Npc::disable (const MWWorld::Ptr& ptr) const
{
environment.mMechanicsManager->removeActor (ptr);
MWBase::Environment::get().getMechanicsManager()->removeActor (ptr);
}
std::string Npc::getName (const MWWorld::Ptr& ptr) const
@ -151,7 +167,7 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Npc::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
}
@ -281,7 +297,6 @@ namespace MWClass
void Npc::registerSelf()
{
boost::shared_ptr<Class> instance (new Npc);
registerClass (typeid (ESM::NPC).name(), instance);
}
}

@ -17,12 +17,12 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual void enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const;
virtual void enable (const MWWorld::Ptr& ptr) const;
///< Enable reference; only does the non-rendering part
virtual void disable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const;
virtual void disable (const MWWorld::Ptr& ptr) const;
///< Enable reference; only does the non-rendering part
virtual std::string getName (const MWWorld::Ptr& ptr) const;
@ -42,7 +42,7 @@ namespace MWClass
///< Return inventory store
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.hpp"
@ -31,7 +32,7 @@ namespace MWClass
}
}
void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
ptr.get<ESM::Potion>();
@ -54,9 +55,9 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Potion::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -70,6 +71,14 @@ namespace MWClass
return ref->base->script;
}
int Potion::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
ptr.get<ESM::Potion>();
return ref->base->data.value;
}
void Potion::registerSelf()
{
boost::shared_ptr<Class> instance (new Potion);
@ -77,12 +86,12 @@ namespace MWClass
registerClass (typeid (ESM::Potion).name(), instance);
}
std::string Potion::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Potion::getUpSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Potion Up");
}
std::string Potion::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Potion::getDownSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Potion Down");
}

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwrender/objects.hpp"
@ -32,7 +33,7 @@ namespace MWClass
}
}
void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
ptr.get<ESM::Probe>();
@ -55,9 +56,9 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Probe::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -80,6 +81,14 @@ namespace MWClass
return std::make_pair (slots, false);
}
int Probe::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
ptr.get<ESM::Probe>();
return ref->base->data.value;
}
void Probe::registerSelf()
{
boost::shared_ptr<Class> instance (new Probe);
@ -87,12 +96,12 @@ namespace MWClass
registerClass (typeid (ESM::Probe).name(), instance);
}
std::string Probe::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Probe::getUpSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Probe Up");
}
std::string Probe::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Probe::getDownSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Probe Down");
}

@ -12,14 +12,14 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
@ -29,12 +29,15 @@ namespace MWClass
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped?
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.hpp"
@ -31,7 +32,7 @@ namespace MWClass
}
}
void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
ptr.get<ESM::Repair>();
@ -54,9 +55,9 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Repair::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -70,6 +71,14 @@ namespace MWClass
return ref->base->script;
}
int Repair::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
ptr.get<ESM::Repair>();
return ref->base->data.value;
}
void Repair::registerSelf()
{
boost::shared_ptr<Class> instance (new Repair);
@ -77,12 +86,12 @@ namespace MWClass
registerClass (typeid (ESM::Repair).name(), instance);
}
std::string Repair::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Repair::getUpSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Repair Up");
}
std::string Repair::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Repair::getDownSoundId (const MWWorld::Ptr& ptr) const
{
return std::string("Item Repair Down");
}

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -25,7 +25,7 @@ namespace MWClass
}
}
void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Static, MWWorld::RefData> *ref =
ptr.get<ESM::Static>();

@ -12,7 +12,7 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwrender/objects.hpp"
@ -32,7 +33,7 @@ namespace MWClass
}
}
void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>();
@ -55,9 +56,9 @@ namespace MWClass
}
boost::shared_ptr<MWWorld::Action> Weapon::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
const MWWorld::Ptr& actor) const
{
environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
@ -108,8 +109,7 @@ namespace MWClass
return std::make_pair (slots, stack);
}
int Weapon::getEquipmentSkill (const MWWorld::Ptr& ptr,
const MWWorld::Environment& environment) const
int Weapon::getEquipmentSkill (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>();
@ -139,6 +139,14 @@ namespace MWClass
return -1;
}
int Weapon::getValue (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>();
return ref->base->data.value;
}
void Weapon::registerSelf()
{
boost::shared_ptr<Class> instance (new Weapon);
@ -146,7 +154,7 @@ namespace MWClass
registerClass (typeid (ESM::Weapon).name(), instance);
}
std::string Weapon::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Weapon::getUpSoundId (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>();
@ -192,7 +200,7 @@ namespace MWClass
return std::string("Item Misc Up");
}
std::string Weapon::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const
std::string Weapon::getDownSoundId (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>();

@ -12,14 +12,14 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
const MWWorld::Ptr& actor) const;
///< Generate action for activation
virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const;
@ -35,17 +35,19 @@ namespace MWClass
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped?
virtual int getEquipmentSkill (const MWWorld::Ptr& ptr,
const MWWorld::Environment& environment) const;
virtual int getEquipmentSkill (const MWWorld::Ptr& ptr) const;
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
/// no such skill.
virtual int getValue (const MWWorld::Ptr& ptr) const;
///< Return trade value of the object. Throws an exception, if the object can't be traded.
static void registerSelf();
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
///< Return the pick up sound Id
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
};
}

@ -9,9 +9,9 @@
#include <components/esm_store/store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/refdata.hpp"
#include "../mwworld/player.hpp"
@ -39,6 +39,9 @@
#include "../mwscript/interpretercontext.hpp"
#include <components/compiler/scriptparser.hpp>
#include "../mwclass/npc.hpp"
#include "../mwmechanics/npcstats.hpp"
namespace
{
std::string toLower (const std::string& name)
@ -109,16 +112,15 @@ namespace
switch (world.getGlobalVariableType (name))
{
case 's':
return selectCompare (comp, value, world.getGlobalVariable (name).mShort);
return selectCompare (comp, world.getGlobalVariable (name).mShort, value);
case 'l':
return selectCompare (comp, value, world.getGlobalVariable (name).mLong);
return selectCompare (comp, world.getGlobalVariable (name).mLong, value);
case 'f':
return selectCompare (comp, value, world.getGlobalVariable (name).mFloat);
return selectCompare (comp, world.getGlobalVariable (name).mFloat, value);
case ' ':
@ -178,7 +180,17 @@ namespace MWDialogue
break;
case 46://Same faction
if(!selectCompare<int,int>(comp,0,select.i)) return false;
{
MWMechanics::NpcStats PCstats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor);
int sameFaction = 0;
if(!NPCstats.mFactionRank.empty())
{
std::string NPCFaction = NPCstats.mFactionRank.begin()->first;
if(PCstats.mFactionRank.find(NPCFaction) != PCstats.mFactionRank.end()) sameFaction = 1;
}
if(!selectCompare<int,int>(comp,sameFaction,select.i)) return false;
}
break;
case 48://Detected
@ -190,7 +202,6 @@ namespace MWDialogue
break;
case 50://choice
if(choice)
{
if(!selectCompare<int,int>(comp,mChoice,select.i)) return false;
@ -270,19 +281,19 @@ namespace MWDialogue
{
case '1': // function
return true; // TODO implement functions
return true; // Done elsewhere.
case '2': // global
if (select.type==ESM::VT_Short || select.type==ESM::VT_Int ||
select.type==ESM::VT_Long)
{
if (!checkGlobal (comp, toLower (name), select.i, *mEnvironment.mWorld))
if (!checkGlobal (comp, toLower (name), select.i, *MWBase::Environment::get().getWorld()))
return false;
}
else if (select.type==ESM::VT_Float)
{
if (!checkGlobal (comp, toLower (name), select.f, *mEnvironment.mWorld))
if (!checkGlobal (comp, toLower (name), select.f, *MWBase::Environment::get().getWorld()))
return false;
}
else
@ -297,13 +308,13 @@ namespace MWDialogue
select.type==ESM::VT_Long)
{
if (!checkLocal (comp, toLower (name), select.i, actor,
mEnvironment.mWorld->getStore()))
MWBase::Environment::get().getWorld()->getStore()))
return false;
}
else if (select.type==ESM::VT_Float)
{
if (!checkLocal (comp, toLower (name), select.f, actor,
mEnvironment.mWorld->getStore()))
MWBase::Environment::get().getWorld()->getStore()))
return false;
}
else
@ -315,7 +326,7 @@ namespace MWDialogue
case '4'://journal
if(select.type==ESM::VT_Int)
{
if(!selectCompare<int,int>(comp,mEnvironment.mJournal->getJournalIndex(toLower(name)),select.i)) return false;
if(!selectCompare<int,int>(comp,MWBase::Environment::get().getJournal()->getJournalIndex(toLower(name)),select.i)) return false;
}
else
throw std::runtime_error (
@ -325,7 +336,7 @@ namespace MWDialogue
case '5'://item
{
MWWorld::Ptr player = mEnvironment.mWorld->getPlayer().getPlayer();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player);
int sum = 0;
@ -413,13 +424,13 @@ namespace MWDialogue
select.type==ESM::VT_Long)
{
if (checkLocal (comp, toLower (name), select.i, actor,
mEnvironment.mWorld->getStore()))
MWBase::Environment::get().getWorld()->getStore()))
return false;
}
else if (select.type==ESM::VT_Float)
{
if (checkLocal (comp, toLower (name), select.f, actor,
mEnvironment.mWorld->getStore()))
MWBase::Environment::get().getWorld()->getStore()))
return false;
}
else
@ -444,9 +455,6 @@ namespace MWDialogue
if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
return false;
//PC Faction
if(!info.pcFaction.empty()) return false;
//NPC race
if (!info.race.empty())
{
@ -474,26 +482,37 @@ namespace MWDialogue
//NPC faction
if (!info.npcFaction.empty())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
if (!cellRef)
return false;
if (toLower (info.npcFaction)!=toLower (cellRef->base->faction))
return false;
//check NPC rank
if(cellRef->base->npdt52.gold != -10)
//MWWorld::Class npcClass = MWWorld::Class::get(actor);
MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.npcFaction);
if(it!=stats.mFactionRank.end())
{
if(cellRef->base->npdt52.rank < info.data.rank) return false;
//check rank
if(it->second < (int)info.data.rank) return false;
}
else
{
if(cellRef->base->npdt12.rank < info.data.rank) return false;
//not in the faction
return false;
}
}
// TODO check player faction
if(!info.pcFaction.empty())
{
MWMechanics::NpcStats stats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.pcFaction);
if(it!=stats.mFactionRank.end())
{
//check rank
if(it->second < (int)info.data.PCrank) return false;
}
else
{
//not in the faction
return false;
}
}
//check gender
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
@ -509,7 +528,7 @@ namespace MWDialogue
// check cell
if (!info.cell.empty())
if (mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell->name != info.cell)
if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell->name != info.cell)
return false;
// TODO check DATAstruct
@ -521,8 +540,8 @@ namespace MWDialogue
return true;
}
DialogueManager::DialogueManager (MWWorld::Environment& environment,const Compiler::Extensions& extensions) :
mEnvironment (environment),mCompilerContext (MWScript::CompilerContext::Type_Dialgoue, environment),
DialogueManager::DialogueManager (const Compiler::Extensions& extensions) :
mCompilerContext (MWScript::CompilerContext::Type_Dialgoue),
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream)
{
mChoice = -1;
@ -530,10 +549,10 @@ namespace MWDialogue
mCompilerContext.setExtensions (&extensions);
mDialogueMap.clear();
actorKnownTopics.clear();
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{
mDialogueMap[it->first] = it->second;
mDialogueMap[toLower(it->first)] = it->second;
}
}
@ -573,8 +592,8 @@ namespace MWDialogue
actorKnownTopics.clear();
//initialise the GUI
mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue);
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Dialogue);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->startDialogue(MWWorld::Class::get (actor).getName (actor));
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
@ -582,9 +601,9 @@ namespace MWDialogue
//greeting
bool greetingFound = false;
//ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
//ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{
ESM::Dialogue ndialogue = it->second;
if(ndialogue.type == ESM::Dialogue::Greeting)
@ -631,7 +650,7 @@ namespace MWDialogue
if (!actorScript.empty())
{
// grab local variables from actor's script, if available.
locals = mEnvironment.mScriptManager->getLocals (actorScript);
locals = MWBase::Environment::get().getScriptManager()->getLocals (actorScript);
}
Compiler::ScriptParser parser(mErrorHandler,mCompilerContext, locals, false);
@ -663,7 +682,7 @@ namespace MWDialogue
{
try
{
MWScript::InterpreterContext interpreterContext(mEnvironment,&mActor.getRefData().getLocals(),mActor);
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
Interpreter::Interpreter interpreter;
MWScript::installOpcodes (interpreter);
interpreter.run (&code[0], code.size(), interpreterContext);
@ -681,9 +700,9 @@ namespace MWDialogue
int choice = mChoice;
mChoice = -1;
actorKnownTopics.clear();
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{
ESM::Dialogue ndialogue = it->second;
if(ndialogue.type == ESM::Dialogue::Topic)
@ -693,7 +712,7 @@ namespace MWDialogue
{
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
{
actorKnownTopics.push_back(it->first);
actorKnownTopics.push_back(toLower(it->first));
//does the player know the topic?
if(knownTopics.find(toLower(it->first)) != knownTopics.end())
{
@ -727,7 +746,7 @@ namespace MWDialogue
parseText(text);
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->addTitle(keyword);
win->addText(iter->response);
@ -747,7 +766,7 @@ namespace MWDialogue
void DialogueManager::goodbyeSelected()
{
mEnvironment.mInputManager->setGuiMode(MWGui::GM_Game);
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game);
}
void DialogueManager::questionAnswered(std::string answere)
@ -770,7 +789,7 @@ namespace MWDialogue
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
std::string text = iter->response;
parseText(text);
win->addText(text);
@ -788,15 +807,30 @@ namespace MWDialogue
void DialogueManager::printError(std::string error)
{
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->addText(error);
}
void DialogueManager::askQuestion(std::string question, int choice)
{
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->askQuestion(question);
mChoiceMap[question] = choice;
mIsInChoice = true;
}
std::string DialogueManager::getFaction()
{
std::string factionID("");
MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
if(stats.mFactionRank.empty())
{
std::cout << "No faction for this actor!";
}
else
{
factionID = stats.mFactionRank.begin()->first;
}
return factionID;
}
}

@ -11,17 +11,10 @@
#include "../mwworld/ptr.hpp"
#include <map>
namespace MWWorld
{
class Environment;
}
namespace MWDialogue
{
class DialogueManager
{
MWWorld::Environment& mEnvironment;
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const;
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const;
@ -39,7 +32,7 @@ namespace MWDialogue
MWScript::CompilerContext mCompilerContext;
std::ostream mErrorStream;
Compiler::StreamErrorHandler mErrorHandler;
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
void executeScript(std::string script);
@ -55,7 +48,7 @@ namespace MWDialogue
public:
DialogueManager (MWWorld::Environment& environment,const Compiler::Extensions& extensions);
DialogueManager (const Compiler::Extensions& extensions);
void startDialogue (const MWWorld::Ptr& actor);
@ -63,6 +56,9 @@ namespace MWDialogue
void askQuestion(std::string question,int choice);
///get the faction of the actor you are talking with
std::string getFaction();
//calbacks for the GUI
void keywordSelected(std::string keyword);
void goodbyeSelected();

@ -1,7 +1,7 @@
#include "journal.hpp"
#include "../mwworld/environment.hpp"
#include "../mwbase/environment.hpp"
#include "../mwgui/window_manager.hpp"
#include "../mwgui/messagebox.hpp"
@ -23,31 +23,30 @@ namespace MWDialogue
return iter->second;
}
Journal::Journal (MWWorld::Environment& environment)
: mEnvironment (environment)
Journal::Journal()
{}
void Journal::addEntry (const std::string& id, int index)
{
StampedJournalEntry entry =
StampedJournalEntry::makeFromQuest (id, index, *mEnvironment.mWorld);
StampedJournalEntry::makeFromQuest (id, index, *MWBase::Environment::get().getWorld());
mJournal.push_back (entry);
Quest& quest = getQuest (id);
quest.addEntry (entry, *mEnvironment.mWorld); // we are doing slicing on purpose here
quest.addEntry (entry, *MWBase::Environment::get().getWorld()); // we are doing slicing on purpose here
std::vector<std::string> empty;
std::string notification = "Your Journal has been updated.";
mEnvironment.mWindowManager->messageBox (notification, empty);
MWBase::Environment::get().getWindowManager()->messageBox (notification, empty);
}
void Journal::setJournalIndex (const std::string& id, int index)
{
Quest& quest = getQuest (id);
quest.setIndex (index, *mEnvironment.mWorld);
quest.setIndex (index, *MWBase::Environment::get().getWorld());
}
void Journal::addTopic (const std::string& topicId, const std::string& infoId)
@ -62,7 +61,7 @@ namespace MWDialogue
iter = result.first;
}
iter->second.addEntry (JournalEntry (topicId, infoId), *mEnvironment.mWorld);
iter->second.addEntry (JournalEntry (topicId, infoId), *MWBase::Environment::get().getWorld());
}
int Journal::getJournalIndex (const std::string& id) const

@ -8,11 +8,6 @@
#include "journalentry.hpp"
#include "quest.hpp"
namespace MWWorld
{
struct Environment;
}
namespace MWDialogue
{
/// \brief The player's journal
@ -29,7 +24,6 @@ namespace MWDialogue
private:
MWWorld::Environment& mEnvironment;
TEntryContainer mJournal;
TQuestContainer mQuests;
TTopicContainer mTopics;
@ -38,7 +32,7 @@ namespace MWDialogue
public:
Journal (MWWorld::Environment& environment);
Journal();
void addEntry (const std::string& id, int index);
///< Add a journal entry.

@ -8,6 +8,8 @@
#include "dialogue.hpp"
#include "mode.hpp"
#include "../mwbase/environment.hpp"
namespace
{
struct Step
@ -93,7 +95,7 @@ namespace
using namespace MWGui;
CharacterCreation::CharacterCreation(WindowManager* _wm, MWWorld::Environment* _environment)
CharacterCreation::CharacterCreation(WindowManager* _wm)
: mNameDialog(0)
, mRaceDialog(0)
, mDialogueWindow(0)
@ -105,7 +107,6 @@ CharacterCreation::CharacterCreation(WindowManager* _wm, MWWorld::Environment* _
, mBirthSignDialog(0)
, mReviewDialog(0)
, mWM(_wm)
, mEnvironment(_environment)
{
mCreationStage = CSE_NotStarted;
}
@ -279,8 +280,8 @@ void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow)
{
const std::string &classId = mPickClassDialog->getClassId();
if (!classId.empty())
mEnvironment->mMechanicsManager->setPlayerClass(classId);
const ESM::Class *klass = mEnvironment->mWorld->getStore().classes.find(classId);
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(classId);
const ESM::Class *klass = MWBase::Environment::get().getWorld()->getStore().classes.find(classId);
if (klass)
{
mPlayerClass = *klass;
@ -307,7 +308,7 @@ void CharacterCreation::onPickClassDialogBack()
{
const std::string classId = mPickClassDialog->getClassId();
if (!classId.empty())
mEnvironment->mMechanicsManager->setPlayerClass(classId);
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(classId);
mWM->removeDialog(mPickClassDialog);
}
@ -345,7 +346,7 @@ void CharacterCreation::onNameDialogDone(WindowBase* parWindow)
{
mPlayerName = mNameDialog->getTextInput();
mWM->setValue("name", mPlayerName);
mEnvironment->mMechanicsManager->setPlayerName(mPlayerName);
MWBase::Environment::get().getMechanicsManager()->setPlayerName(mPlayerName);
mWM->removeDialog(mNameDialog);
}
@ -366,7 +367,7 @@ void CharacterCreation::onRaceDialogBack()
{
mPlayerRaceId = mRaceDialog->getRaceId();
if (!mPlayerRaceId.empty())
mEnvironment->mMechanicsManager->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male);
MWBase::Environment::get().getMechanicsManager()->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male);
mWM->removeDialog(mRaceDialog);
}
@ -380,7 +381,7 @@ void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
mPlayerRaceId = mRaceDialog->getRaceId();
mWM->setValue("race", mPlayerRaceId);
if (!mPlayerRaceId.empty())
mEnvironment->mMechanicsManager->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male);
MWBase::Environment::get().getMechanicsManager()->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male);
mWM->removeDialog(mRaceDialog);
}
@ -402,7 +403,7 @@ void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
mPlayerBirthSignId = mBirthSignDialog->getBirthId();
mWM->setBirthSign(mPlayerBirthSignId);
if (!mPlayerBirthSignId.empty())
mEnvironment->mMechanicsManager->setPlayerBirthsign(mPlayerBirthSignId);
MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mPlayerBirthSignId);
mWM->removeDialog(mBirthSignDialog);
}
@ -419,7 +420,7 @@ void CharacterCreation::onBirthSignDialogBack()
{
if (mBirthSignDialog)
{
mEnvironment->mMechanicsManager->setPlayerBirthsign(mBirthSignDialog->getBirthId());
MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mBirthSignDialog->getBirthId());
mWM->removeDialog(mBirthSignDialog);
}
@ -450,7 +451,7 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
klass.data.skills[i][1] = majorSkills[i];
klass.data.skills[i][0] = minorSkills[i];
}
mEnvironment->mMechanicsManager->setPlayerClass(klass);
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass);
mPlayerClass = klass;
mWM->setPlayerClass(klass);
@ -592,7 +593,7 @@ void CharacterCreation::onGenerateClassBack()
if (mGenerateClassResultDialog)
mWM->removeDialog(mGenerateClassResultDialog);
mEnvironment->mMechanicsManager->setPlayerClass(mGenerateClass);
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass);
mWM->setGuiMode(GM_Class);
}
@ -601,7 +602,7 @@ void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
{
if (mGenerateClassResultDialog)
mWM->removeDialog(mGenerateClassResultDialog);
mEnvironment->mMechanicsManager->setPlayerClass(mGenerateClass);
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass);
if (mCreationStage == CSE_ReviewNext)
mWM->setGuiMode(GM_Review);

@ -30,7 +30,7 @@ namespace MWGui
public:
typedef std::vector<int> SkillList;
CharacterCreation(WindowManager* _wm, MWWorld::Environment* _environment);
CharacterCreation(WindowManager* _wm);
~CharacterCreation();
//Show a dialog
@ -56,7 +56,6 @@ namespace MWGui
ReviewDialog* mReviewDialog;
WindowManager* mWM;
MWWorld::Environment* mEnvironment;
//Player data
std::string mPlayerName;

@ -7,6 +7,8 @@
#include "../mwscript/extensions.hpp"
#include "../mwbase/environment.hpp"
namespace MWGui
{
class ConsoleInterpreterContext : public MWScript::InterpreterContext
@ -15,15 +17,14 @@ namespace MWGui
public:
ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment,
MWWorld::Ptr reference);
ConsoleInterpreterContext (Console& console, MWWorld::Ptr reference);
virtual void report (const std::string& message);
};
ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console,
MWWorld::Environment& environment, MWWorld::Ptr reference)
: MWScript::InterpreterContext (environment,
MWWorld::Ptr reference)
: MWScript::InterpreterContext (
reference.isEmpty() ? 0 : &reference.getRefData().getLocals(), reference),
mConsole (console)
{}
@ -88,7 +89,7 @@ namespace MWGui
scanner.listKeywords (mNames);
// identifier
const ESMS::ESMStore& store = mEnvironment.mWorld->getStore();
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
for (ESMS::RecListList::const_iterator iter (store.recLists.begin());
iter!=store.recLists.end(); ++iter)
@ -101,11 +102,9 @@ namespace MWGui
}
}
Console::Console(int w, int h, MWWorld::Environment& environment,
const Compiler::Extensions& extensions)
Console::Console(int w, int h, const Compiler::Extensions& extensions)
: Layout("openmw_console_layout.xml"),
mCompilerContext (MWScript::CompilerContext::Type_Console, environment),
mEnvironment (environment)
mCompilerContext (MWScript::CompilerContext::Type_Console)
{
setCoord(10,10, w-10, h/2);
@ -139,7 +138,7 @@ namespace MWGui
void Console::disable()
{
setVisible(false);
// Remove keyboard focus from the console input whenever the
// Remove keyboard focus from the console input whenever the
// console is turned off
MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL);
}
@ -241,7 +240,7 @@ namespace MWGui
{
try
{
ConsoleInterpreterContext interpreterContext (*this, mEnvironment, MWWorld::Ptr());
ConsoleInterpreterContext interpreterContext (*this, MWWorld::Ptr());
Interpreter::Interpreter interpreter;
MWScript::installOpcodes (interpreter);
std::vector<Interpreter::Type_Code> code;

@ -23,7 +23,6 @@ namespace MWGui
private:
MWScript::CompilerContext mCompilerContext;
MWWorld::Environment& mEnvironment;
std::vector<std::string> mNames;
bool compile (const std::string& cmd, Compiler::Output& output);
@ -51,7 +50,7 @@ namespace MWGui
StringList::iterator current;
std::string editString;
Console(int w, int h, MWWorld::Environment& environment, const Compiler::Extensions& extensions);
Console(int w, int h, const Compiler::Extensions& extensions);
void enable();

@ -0,0 +1,16 @@
#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);
}

@ -0,0 +1,16 @@
#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

@ -3,7 +3,7 @@
#include "window_manager.hpp"
#include "widgets.hpp"
#include "components/esm_store/store.hpp"
#include "../mwworld/environment.hpp"
#include "../mwbase/environment.hpp"
#include "../mwdialogue/dialoguemanager.hpp"
#include <assert.h>
@ -36,9 +36,8 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su
}
DialogueWindow::DialogueWindow(WindowManager& parWindowManager,MWWorld::Environment& environment)
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager),
mEnvironment(environment)
DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager)
{
// Centre dialog
center();
@ -54,7 +53,7 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager,MWWorld::Environm
/// \todo scrolling the dialogue history with the mouse wheel doesn't work using this solution
getWidget(eventbox, "EventBox");
eventbox->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked);
//Topics list
getWidget(topicsList, "TopicsList");
topicsList->setScrollVisible(true);
@ -83,9 +82,9 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
if(color != "#B29154")
{
UString key = history->getColorTextAt(cursorPosition);
if(color == "#686EBA") mEnvironment.mDialogueManager->keywordSelected(lower_string(key));
if(color == "#686EBA") MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(key));
if(color == "#572D21") mEnvironment.mDialogueManager->questionAnswered(key);
if(color == "#572D21") MWBase::Environment::get().getDialogueManager()->questionAnswered(key);
}
}
@ -100,7 +99,7 @@ void DialogueWindow::open()
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
{
mEnvironment.mDialogueManager->goodbyeSelected();
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
}
void DialogueWindow::onSelectTopic(MyGUI::ListBox* _sender, size_t _index)
@ -108,7 +107,7 @@ void DialogueWindow::onSelectTopic(MyGUI::ListBox* _sender, size_t _index)
if (_index == MyGUI::ITEM_NONE)
return;
std::string topic = _sender->getItemNameAt(_index);
mEnvironment.mDialogueManager->keywordSelected(lower_string(topic));
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
}
void DialogueWindow::startDialogue(std::string npcName)
@ -183,6 +182,16 @@ void DialogueWindow::addText(std::string text)
void DialogueWindow::addTitle(std::string text)
{
// This is called from the dialogue manager, so text is
// case-smashed - thus we have to retrieve the correct case
// of the text through the topic list.
for (size_t i=0; i<topicsList->getItemCount(); ++i)
{
std::string item = topicsList->getItemNameAt(i);
if (lower_string(item) == text)
text = item;
}
history->addDialogHeading(text);
}

@ -9,11 +9,6 @@ namespace MWGui
class WindowManager;
}
namespace MWWorld
{
class Environment;
}
/*
This file contains the dialouge window
Layout is defined by resources/mygui/openmw_dialogue_window_layout.xml.
@ -23,17 +18,15 @@ namespace MWGui
{
class DialogueHistory;
using namespace MyGUI;
class DialogueWindow: public WindowBase
{
public:
DialogueWindow(WindowManager& parWindowManager,MWWorld::Environment& environment);
DialogueWindow(WindowManager& parWindowManager);
void open();
// Events
typedef delegates::CMultiDelegate0 EventHandle_Void;
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
/** Event : Dialog finished, OK button clicked.\n
signature : void method()\n
@ -65,8 +58,6 @@ namespace MWGui
MyGUI::ProgressPtr pDispositionBar;
MyGUI::EditPtr pDispositionText;
std::map<std::string,std::string> pTopicsText;// this map links keyword and "real" text.
MWWorld::Environment& mEnvironment;
};
}
#endif

@ -1,7 +1,7 @@
#include "journalwindow.hpp"
#include "window_manager.hpp"
#include "../mwdialogue/journal.hpp"
#include "../mwworld/environment.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwsound/soundmanager.hpp"
@ -118,20 +118,20 @@ void MWGui::JournalWindow::open()
{
mPageNumber = 0;
std::string journalOpenSound = "book open";
mWindowManager.getEnvironment().mSoundManager->playSound (journalOpenSound, 1.0, 1.0);
if(mWindowManager.getEnvironment().mJournal->begin()!=mWindowManager.getEnvironment().mJournal->end())
MWBase::Environment::get().getSoundManager()->playSound (journalOpenSound, 1.0, 1.0);
if(MWBase::Environment::get().getJournal()->begin()!=MWBase::Environment::get().getJournal()->end())
{
book journal;
journal.endLine = 0;
for(std::deque<MWDialogue::StampedJournalEntry>::const_iterator it = mWindowManager.getEnvironment().mJournal->begin();it!=mWindowManager.getEnvironment().mJournal->end();it++)
for(std::deque<MWDialogue::StampedJournalEntry>::const_iterator it = MWBase::Environment::get().getJournal()->begin();it!=MWBase::Environment::get().getJournal()->end();it++)
{
std::string a = it->getText(mWindowManager.getEnvironment().mWorld->getStore());
std::string a = it->getText(MWBase::Environment::get().getWorld()->getStore());
journal = formatText(a,journal,10,17);
journal.endLine = journal.endLine +1;
journal.pages.back() = journal.pages.back() + std::string("\n");
}
//std::string a = mWindowManager.getEnvironment().mJournal->begin()->getText(mWindowManager.getEnvironment().mWorld->getStore());
//std::string a = MWBase::Environment::get().getJournal()->begin()->getText(MWBase::Environment::get().getWorld()->getStore());
//std::list<std::string> journal = formatText(a,10,20,1);
bool left = true;
for(std::list<std::string>::iterator it = journal.pages.begin(); it != journal.pages.end();it++)
@ -155,7 +155,7 @@ void MWGui::JournalWindow::open()
}
else
{
//std::cout << mWindowManager.getEnvironment().mJournal->begin()->getText(mWindowManager.getEnvironment().mWorld->getStore());
//std::cout << MWBase::Environment::get().getJournal()->begin()->getText(MWBase::Environment::get().getWorld()->getStore());
}
}
@ -181,7 +181,7 @@ void MWGui::JournalWindow::notifyNextPage(MyGUI::WidgetPtr _sender)
if(mPageNumber < int(leftPages.size())-1)
{
std::string nextSound = "book page2";
mWindowManager.getEnvironment().mSoundManager->playSound (nextSound, 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound (nextSound, 1.0, 1.0);
mPageNumber = mPageNumber + 1;
displayLeftText(leftPages[mPageNumber]);
displayRightText(rightPages[mPageNumber]);
@ -193,7 +193,7 @@ void MWGui::JournalWindow::notifyPrevPage(MyGUI::WidgetPtr _sender)
if(mPageNumber > 0)
{
std::string prevSound = "book page";
mWindowManager.getEnvironment().mSoundManager->playSound (prevSound, 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound (prevSound, 1.0, 1.0);
mPageNumber = mPageNumber - 1;
displayLeftText(leftPages[mPageNumber]);
displayRightText(rightPages[mPageNumber]);

@ -31,6 +31,11 @@ HUD::HUD(int width, int height, int fpsLevel)
, fpscounter(NULL)
, trianglecounter(NULL)
, batchcounter(NULL)
, hmsBaseLeft(0)
, weapBoxBaseLeft(0)
, spellBoxBaseLeft(0)
, effectBoxBaseRight(0)
, minimapBoxBaseRight(0)
{
setCoord(0,0, width, height);
@ -38,32 +43,32 @@ HUD::HUD(int width, int height, int fpsLevel)
getWidget(health, "Health");
getWidget(magicka, "Magicka");
getWidget(stamina, "Stamina");
hmsBaseLeft = health->getLeft();
// Item and spell images and status bars
getWidget(weapBox, "WeapBox");
getWidget(weapImage, "WeapImage");
getWidget(weapStatus, "WeapStatus");
weapBoxBaseLeft = weapBox->getLeft();
getWidget(spellBox, "SpellBox");
getWidget(spellImage, "SpellImage");
getWidget(spellStatus, "SpellStatus");
spellBoxBaseLeft = spellBox->getLeft();
getWidget(effectBox, "EffectBox");
getWidget(effect1, "Effect1");
effectBoxBaseRight = effectBox->getRight();
getWidget(minimapBox, "MiniMapBox");
minimapBoxBaseRight = minimapBox->getRight();
getWidget(minimap, "MiniMap");
getWidget(compass, "Compass");
getWidget(crosshair, "Crosshair");
if ( fpsLevel == 2 ){
getWidget(fpsbox, "FPSBoxAdv");
fpsbox->setVisible(true);
getWidget(fpscounter, "FPSCounterAdv");
}else if ( fpsLevel == 1 ){
getWidget(fpsbox, "FPSBox");
fpsbox->setVisible(true);
getWidget(fpscounter, "FPSCounter");
}else{
getWidget(fpscounter, "FPSCounter");
}
setFpsLevel(fpsLevel);
getWidget(trianglecounter, "TriangleCounter");
getWidget(batchcounter, "BatchCounter");
@ -81,6 +86,28 @@ HUD::HUD(int width, int height, int fpsLevel)
LocalMapBase::init(minimap, this);
}
void HUD::setFpsLevel(int level)
{
MyGUI::Widget* fps;
getWidget(fps, "FPSBoxAdv");
fps->setVisible(false);
getWidget(fps, "FPSBox");
fps->setVisible(false);
if (level == 2)
{
getWidget(fpsbox, "FPSBoxAdv");
fpsbox->setVisible(true);
getWidget(fpscounter, "FPSCounterAdv");
}
else if (level == 1)
{
getWidget(fpsbox, "FPSBox");
fpsbox->setVisible(true);
getWidget(fpscounter, "FPSCounter");
}
}
void HUD::setFPS(float fps)
{
fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps));
@ -163,15 +190,21 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& v
void HUD::setPlayerDir(const float x, const float y)
{
if (!minimapBox->getVisible() || (x == mLastPositionX && y == mLastPositionY)) return;
MyGUI::ISubWidget* main = compass->getSubWidgetMain();
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
float angle = std::atan2(x,y);
rotatingSubskin->setAngle(angle);
mLastPositionX = x;
mLastPositionY = y;
}
void HUD::setPlayerPos(const float x, const float y)
{
if (!minimapBox->getVisible() || (x == mLastDirectionX && y == mLastDirectionY)) return;
MyGUI::IntSize size = minimap->getCanvasSize();
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
MyGUI::IntCoord viewsize = minimap->getCoord();
@ -179,99 +212,39 @@ void HUD::setPlayerPos(const float x, const float y)
minimap->setViewOffset(pos);
compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
}
MapWindow::MapWindow()
: Layout("openmw_map_window_layout.xml")
, mGlobal(false)
, mVisible(false)
{
setCoord(500,0,320,300);
setText("WorldButton", "World");
setImage("Compass", "textures\\compass.dds");
// Obviously you should override this later on
setCellName("No Cell Loaded");
getWidget(mLocalMap, "LocalMap");
getWidget(mGlobalMap, "GlobalMap");
getWidget(mPlayerArrow, "Compass");
getWidget(mButton, "WorldButton");
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
MyGUI::Button* eventbox;
getWidget(eventbox, "EventBox");
eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
LocalMapBase::init(mLocalMap, this);
}
void MapWindow::setVisible(bool b)
{
mMainWidget->setVisible(b);
if (b)
mVisible = true;
else
mVisible = false;
}
void MapWindow::setCellName(const std::string& cellName)
{
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName);
adjustWindowCaption();
}
void MapWindow::setPlayerPos(const float x, const float y)
{
if (mGlobal || mVisible) return;
MyGUI::IntSize size = mLocalMap->getCanvasSize();
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
mLocalMap->setViewOffset(pos);
mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
mLastDirectionX = x;
mLastDirectionY = y;
}
void MapWindow::setPlayerDir(const float x, const float y)
void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible)
{
if (!mVisible) return;
MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain();
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
float angle = std::atan2(x,y);
rotatingSubskin->setAngle(angle);
int weapDx = 0, spellDx = 0;
if (!hmsVisible)
spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft;
if (!weapVisible)
spellDx -= spellBoxBaseLeft - weapBoxBaseLeft;
health->setVisible(hmsVisible);
stamina->setVisible(hmsVisible);
magicka->setVisible(hmsVisible);
weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop());
weapBox->setVisible(weapVisible);
spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop());
spellBox->setVisible(spellVisible);
}
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible)
{
if (_id!=MyGUI::MouseButton::Left) return;
if (!mGlobal)
mLastDragPos = MyGUI::IntPoint(_left, _top);
}
void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
if (_id!=MyGUI::MouseButton::Left) return;
if (!mGlobal)
{
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff );
mLastDragPos = MyGUI::IntPoint(_left, _top);
}
}
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
{
mGlobal = !mGlobal;
mGlobalMap->setVisible(mGlobal);
mLocalMap->setVisible(!mGlobal);
mButton->setCaption( mGlobal ? "Local" : "World" );
// effect box can have variable width -> variable left coordinate
int effectsDx = 0;
if (!minimapBoxVisible)
effectsDx = minimapBoxBaseRight - effectBoxBaseRight;
minimapBox->setVisible(minimapBoxVisible);
effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop());
effectBox->setVisible(effectBoxVisible);
}
LocalMapBase::LocalMapBase()
@ -283,6 +256,10 @@ LocalMapBase::LocalMapBase()
, mPrefix()
, mChanged(true)
, mLayout(NULL)
, mLastPositionX(0.0f)
, mLastPositionY(0.0f)
, mLastDirectionX(0.0f)
, mLastDirectionY(0.0f)
{
}

@ -53,6 +53,11 @@ namespace MWGui
void applyFogOfWar();
OEngine::GUI::Layout* mLayout;
float mLastPositionX;
float mLastPositionY;
float mLastDirectionX;
float mLastDirectionY;
};
class HUD : public OEngine::GUI::Layout, public LocalMapBase
@ -71,11 +76,15 @@ namespace MWGui
void setBatchCount(size_t count);
void setPlayerDir(const float x, const float y);
void setPlayerPos(const float x, const float y);
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
void setFpsLevel(const int level);
MyGUI::ProgressPtr health, magicka, stamina;
MyGUI::Widget *weapBox, *spellBox;
MyGUI::ImageBox *weapImage, *spellImage;
MyGUI::ProgressPtr weapStatus, spellStatus;
MyGUI::WidgetPtr effectBox;
MyGUI::Widget *effectBox, *minimapBox;
MyGUI::ImageBox* effect1;
MyGUI::ScrollView* minimap;
MyGUI::ImageBox* compass;
@ -85,30 +94,12 @@ namespace MWGui
MyGUI::TextBox* fpscounter;
MyGUI::TextBox* trianglecounter;
MyGUI::TextBox* batchcounter;
};
class MapWindow : public OEngine::GUI::Layout, public LocalMapBase
{
public:
MapWindow();
virtual ~MapWindow(){}
void setVisible(bool b);
void setPlayerPos(const float x, const float y);
void setPlayerDir(const float x, const float y);
void setCellName(const std::string& cellName);
private:
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onWorldButtonClicked(MyGUI::Widget* _sender);
MyGUI::ScrollView* mGlobalMap;
MyGUI::ImageBox* mPlayerArrow;
MyGUI::Button* mButton;
MyGUI::IntPoint mLastDragPos;
bool mVisible;
bool mGlobal;
// bottom left elements
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
// bottom right elements
int minimapBoxBaseRight, effectBoxBaseRight;
};
class MainMenu : public OEngine::GUI::Layout

@ -0,0 +1,106 @@
#include "map_window.hpp"
#include "window_manager.hpp"
/*
#include "../mwmechanics/mechanicsmanager.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#undef min
#undef max
*/
using namespace MWGui;
MapWindow::MapWindow(WindowManager& parWindowManager) :
MWGui::WindowPinnableBase("openmw_map_window_layout.xml", parWindowManager),
mGlobal(false)
{
setCoord(500,0,320,300);
setText("WorldButton", "World");
setImage("Compass", "textures\\compass.dds");
// Obviously you should override this later on
setCellName("No Cell Loaded");
getWidget(mLocalMap, "LocalMap");
getWidget(mGlobalMap, "GlobalMap");
getWidget(mPlayerArrow, "Compass");
getWidget(mButton, "WorldButton");
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
MyGUI::Button* eventbox;
getWidget(eventbox, "EventBox");
eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
LocalMapBase::init(mLocalMap, this);
}
void MapWindow::setCellName(const std::string& cellName)
{
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName);
adjustWindowCaption();
}
void MapWindow::setPlayerPos(const float x, const float y)
{
if (mGlobal || !mVisible || (x == mLastPositionX && y == mLastPositionY)) return;
MyGUI::IntSize size = mLocalMap->getCanvasSize();
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
mLocalMap->setViewOffset(pos);
mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
mLastPositionX = x;
mLastPositionY = y;
}
void MapWindow::setPlayerDir(const float x, const float y)
{
if (!mVisible || (x == mLastDirectionX && y == mLastDirectionY)) return;
MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain();
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
float angle = std::atan2(x,y);
rotatingSubskin->setAngle(angle);
mLastDirectionX = x;
mLastDirectionY = y;
}
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
if (_id!=MyGUI::MouseButton::Left) return;
if (!mGlobal)
mLastDragPos = MyGUI::IntPoint(_left, _top);
}
void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
if (_id!=MyGUI::MouseButton::Left) return;
if (!mGlobal)
{
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff );
mLastDragPos = MyGUI::IntPoint(_left, _top);
}
}
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
{
mGlobal = !mGlobal;
mGlobalMap->setVisible(mGlobal);
mLocalMap->setVisible(!mGlobal);
mButton->setCaption( mGlobal ? "Local" : "World" );
}
void MapWindow::onPinToggled()
{
mWindowManager.setMinimapVisibility(!mPinned);
}

@ -0,0 +1,34 @@
#ifndef MWGUI_MAPWINDOW_H
#define MWGUI_MAPWINDOW_H
#include "layouts.hpp"
#include "window_pinnable_base.hpp"
namespace MWGui
{
class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase
{
public:
MapWindow(WindowManager& parWindowManager);
virtual ~MapWindow(){}
void setPlayerPos(const float x, const float y);
void setPlayerDir(const float x, const float y);
void setCellName(const std::string& cellName);
private:
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onWorldButtonClicked(MyGUI::Widget* _sender);
MyGUI::ScrollView* mGlobalMap;
MyGUI::ImageBox* mPlayerArrow;
MyGUI::Button* mButton;
MyGUI::IntPoint mLastDragPos;
bool mGlobal;
protected:
virtual void onPinToggled();
};
}
#endif

@ -12,7 +12,7 @@ using namespace MWGui;
const int StatsWindow::lineHeight = 18;
StatsWindow::StatsWindow (WindowManager& parWindowManager)
: WindowBase("openmw_stats_window_layout.xml", parWindowManager)
: WindowPinnableBase("openmw_stats_window_layout.xml", parWindowManager)
, skillAreaWidget(NULL)
, skillClientWidget(NULL)
, skillScrollerWidget(NULL)
@ -381,3 +381,8 @@ void StatsWindow::updateScroller()
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
}
void StatsWindow::onPinToggled()
{
mWindowManager.setHMSVisibility(!mPinned);
}

@ -9,13 +9,13 @@
#include <utility>
#include "../mwmechanics/stat.hpp"
#include "window_base.hpp"
#include "window_pinnable_base.hpp"
namespace MWGui
{
class WindowManager;
class StatsWindow : public WindowBase
class StatsWindow : public WindowPinnableBase
{
public:
typedef std::pair<std::string, int> Faction;
@ -74,6 +74,9 @@ namespace MWGui
std::string birthSignId;
int reputation, bounty;
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information
protected:
virtual void onPinToggled();
};
}
#endif

@ -4,26 +4,30 @@
#include "review.hpp"
#include "dialogue.hpp"
#include "dialogue_history.hpp"
#include "map_window.hpp"
#include "stats_window.hpp"
#include "messagebox.hpp"
#include "../mwmechanics/mechanicsmanager.hpp"
#include "../mwinput/inputmanager.hpp"
#include "../mwbase/environment.hpp"
#include "console.hpp"
#include "journalwindow.hpp"
#include "charactercreation.hpp"
#include <components/settings/settings.hpp>
#include <assert.h>
#include <iostream>
#include <iterator>
using namespace MWGui;
WindowManager::WindowManager(MWWorld::Environment& environment,
WindowManager::WindowManager(
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath)
: mGuiManager(NULL)
, environment(environment)
, hud(NULL)
, map(NULL)
, menu(NULL)
@ -71,17 +75,17 @@ WindowManager::WindowManager(MWWorld::Environment& environment,
hud = new HUD(w,h, showFPSLevel);
menu = new MainMenu(w,h);
map = new MapWindow();
map = new MapWindow(*this);
stats = new StatsWindow(*this);
console = new Console(w,h, environment, extensions);
console = new Console(w,h, extensions);
mJournal = new JournalWindow(*this);
mMessageBoxManager = new MessageBoxManager(this);
dialogueWindow = new DialogueWindow(*this,environment);
dialogueWindow = new DialogueWindow(*this);
// The HUD is always on
hud->setVisible(true);
mCharGen = new CharacterCreation(this, &environment);
mCharGen = new CharacterCreation(this);
// Setup player stats
for (int i = 0; i < ESM::Attribute::Length; ++i)
@ -140,7 +144,7 @@ void WindowManager::update()
if (needModeChange)
{
needModeChange = false;
environment.mInputManager->setGuiMode(nextMode);
MWBase::Environment::get().getInputManager()->setGuiMode(nextMode);
nextMode = GM_Game;
}
if (showFPSLevel > 0)
@ -151,11 +155,6 @@ void WindowManager::update()
}
}
MWWorld::Environment& WindowManager::getEnvironment()
{
return environment;
}
void WindowManager::setNextMode(GuiMode newMode)
{
nextMode = newMode;
@ -164,7 +163,7 @@ void WindowManager::setNextMode(GuiMode newMode)
void WindowManager::setGuiMode(GuiMode newMode)
{
environment.mInputManager->setGuiMode(newMode);
MWBase::Environment::get().getInputManager()->setGuiMode(newMode);
}
void WindowManager::updateVisible()
@ -385,7 +384,7 @@ int WindowManager::readPressedButton ()
const std::string &WindowManager::getGameSettingString(const std::string &id, const std::string &default_)
{
const ESM::GameSetting *setting = environment.mWorld->getStore().gameSettings.search(id);
const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.search(id);
if (setting && setting->type == ESM::VT_String)
return setting->str;
return default_;
@ -409,7 +408,7 @@ void WindowManager::onFrame (float frameDuration)
const ESMS::ESMStore& WindowManager::getStore() const
{
return environment.mWorld->getStore();
return MWBase::Environment::get().getWorld()->getStore();
}
void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
@ -456,8 +455,26 @@ void WindowManager::setPlayerDir(const float x, const float y)
hud->setPlayerDir(x,y);
}
void WindowManager::setHMSVisibility(bool visible)
{
hud->setBottomLeftVisibility(visible, hud->weapBox->getVisible(), hud->spellBox->getVisible());
}
void WindowManager::setMinimapVisibility(bool visible)
{
hud->setBottomRightVisibility(hud->effectBox->getVisible(), visible);
}
void WindowManager::toggleFogOfWar()
{
map->toggleFogOfWar();
hud->toggleFogOfWar();
}
int WindowManager::toggleFps()
{
showFPSLevel = (showFPSLevel+1)%3;
hud->setFpsLevel(showFPSLevel);
Settings::Manager::setInt("fps", "HUD", showFPSLevel);
return showFPSLevel;
}

@ -34,7 +34,6 @@ namespace Compiler
namespace MWWorld
{
class Environment;
class World;
}
@ -83,7 +82,7 @@ namespace MWGui
typedef std::vector<Faction> FactionList;
typedef std::vector<int> SkillList;
WindowManager(MWWorld::Environment& environment, const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath);
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath);
virtual ~WindowManager();
void setGuiMode(GuiMode newMode);
@ -95,8 +94,6 @@ namespace MWGui
*/
void update();
MWWorld::Environment& getEnvironment();
void setMode(GuiMode newMode)
{
if (newMode==GM_Inventory && allowed==GW_None)
@ -158,10 +155,18 @@ namespace MWGui
void setPlayerDir(const float x, const float y); ///< set player view direction in map space
void toggleFogOfWar();
int toggleFps();
///< toggle fps display @return resulting fps level
void setInteriorMapTexture(const int x, const int y);
///< set the index of the map texture that should be used (for interiors)
// sets the visibility of the hud health/magicka/stamina bars
void setHMSVisibility(bool visible);
// sets the visibility of the hud minimap
void setMinimapVisibility(bool visible);
template<typename T>
void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr.
void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
@ -184,7 +189,6 @@ namespace MWGui
private:
OEngine::GUI::MyGUIManager *mGuiManager;
MWWorld::Environment& environment;
HUD *hud;
MapWindow *map;
MainMenu *menu;

@ -0,0 +1,33 @@
#include "window_pinnable_base.hpp"
#include "window_manager.hpp"
using namespace MWGui;
WindowPinnableBase::WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager)
: WindowBase(parLayout, parWindowManager), mPinned(false), mVisible(false)
{
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget);
t->eventWindowButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onWindowButtonPressed);
}
void WindowPinnableBase::setVisible(bool b)
{
// Pinned windows can not be hidden
if (mPinned && !b)
return;
WindowBase::setVisible(b);
mVisible = b;
}
void WindowPinnableBase::onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName)
{
if ("PinToggle" == eventName)
{
mPinned = !mPinned;
onPinToggled();
}
eventDone(this);
}

@ -0,0 +1,28 @@
#ifndef MWGUI_WINDOW_PINNABLE_BASE_H
#define MWGUI_WINDOW_PINNABLE_BASE_H
#include "window_base.hpp"
namespace MWGui
{
class WindowManager;
class WindowPinnableBase: public WindowBase
{
public:
WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager);
void setVisible(bool b);
private:
void onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName);
protected:
virtual void onPinToggled() = 0;
bool mPinned;
bool mVisible;
};
}
#endif

@ -65,6 +65,10 @@ namespace MWInput
A_QuickLoad,
A_QuickMenu,
A_GameMenu,
A_ToggleWeapon,
A_ToggleSpell,
A_ToggleFps, // Toggle FPS display (this is temporary)
A_LAST // Marker for the last item
};
@ -86,6 +90,45 @@ namespace MWInput
/* InputImpl Methods */
void toggleFps()
{
windows.toggleFps();
}
void toggleSpell()
{
if (windows.isGuiMode()) return;
DrawState state = player.getDrawState();
if (state == DrawState_Weapon || state == DrawState_Nothing)
{
player.setDrawState(DrawState_Spell);
std::cout << "Player has now readied his hands for spellcasting!\n";
}
else
{
player.setDrawState(DrawState_Nothing);
std::cout << "Player does not have any kind of attack ready now.\n";
}
}
void toggleWeapon()
{
if (windows.isGuiMode()) return;
DrawState state = player.getDrawState();
if (state == DrawState_Spell || state == DrawState_Nothing)
{
player.setDrawState(DrawState_Weapon);
std::cout << "Player is now drawing his weapon.\n";
}
else
{
player.setDrawState(DrawState_Nothing);
std::cout << "Player does not have any kind of attack ready now.\n";
}
}
void screenshot()
{
mEngine.screenshot();
@ -143,11 +186,13 @@ namespace MWInput
void toggleAutoMove()
{
if (windows.isGuiMode()) return;
player.setAutoMove (!player.getAutoMove());
}
void toggleWalking()
{
if (windows.isGuiMode()) return;
player.toggleRunning();
}
@ -197,7 +242,12 @@ namespace MWInput
"Auto Move");
disp->funcs.bind(A_ToggleWalk, boost::bind(&InputImpl::toggleWalking, this),
"Toggle Walk/Run");
disp->funcs.bind(A_ToggleWeapon,boost::bind(&InputImpl::toggleWeapon,this),
"Draw Weapon");
disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this),
"Ready hands");
disp->funcs.bind(A_ToggleFps, boost::bind(&InputImpl::toggleFps, this),
"Toggle FPS display");
// Add the exit listener
ogre.getRoot()->addFrameListener(&exit);
@ -242,6 +292,9 @@ namespace MWInput
disp->bind(A_AutoMove, KC_Z);
disp->bind(A_ToggleSneak, KC_X);
disp->bind(A_ToggleWalk, KC_C);
disp->bind(A_ToggleWeapon,KC_F);
disp->bind(A_ToggleSpell,KC_R);
disp->bind(A_ToggleFps, KC_F10);
// Key bindings for polled keys
// NOTE: These keys are constantly being polled. Only add keys that must be checked each frame.

@ -0,0 +1,77 @@
#include "actors.hpp"
#include <typeinfo>
#include <components/esm/loadnpc.hpp>
#include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp"
namespace MWMechanics
{
void Actors::updateActor (const MWWorld::Ptr& ptr, float duration)
{
}
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
{
if (!paused && ptr.getRefData().getHandle()!="player")
MWWorld::Class::get (ptr).getInventoryStore (ptr).autoEquip (
MWWorld::Class::get (ptr).getNpcStats (ptr));
}
Actors::Actors() : mDuration (0) {}
void Actors::addActor (const MWWorld::Ptr& ptr)
{
mActors.insert (ptr);
}
void Actors::removeActor (const MWWorld::Ptr& ptr)
{
mActors.erase (ptr);
}
void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore)
{
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
while (iter!=mActors.end())
if (iter->getCell()==cellStore)
{
mActors.erase (iter++);
}
else
++iter;
}
void Actors::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement, float duration,
bool paused)
{
mDuration += duration;
if (mDuration>=0.25)
{
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter)
{
updateActor (*iter, mDuration);
if (iter->getTypeName()==typeid (ESM::NPC).name())
updateNpc (*iter, mDuration, paused);
}
mDuration = 0;
}
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
++iter)
{
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
if (vector!=Ogre::Vector3::ZERO)
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
}
}
}

@ -0,0 +1,45 @@
#ifndef GAME_MWMECHANICS_ACTORS_H
#define GAME_MWMECHANICS_ACTORS_H
#include <set>
#include <vector>
#include <string>
#include "../mwworld/ptr.hpp"
namespace Ogre
{
class Vector3;
}
namespace MWMechanics
{
class Actors
{
std::set<MWWorld::Ptr> mActors;
float mDuration;
void updateActor (const MWWorld::Ptr& ptr, float duration);
void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused);
public:
Actors();
void addActor (const MWWorld::Ptr& ptr);
///< Register an actor for stats management
void removeActor (const MWWorld::Ptr& ptr);
///< Deregister an actor for stats management
void dropActors (const MWWorld::Ptr::CellStore *cellStore);
///< Deregister all actors in the given cell.
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
float duration, bool paused);
///< Update actor stats and store desired velocity vectors in \a movement
};
}
#endif

@ -6,6 +6,7 @@
#include "stat.hpp"
#include "magiceffects.hpp"
#include "spells.hpp"
namespace MWMechanics
{
@ -14,7 +15,7 @@ namespace MWMechanics
Stat<int> mAttributes[8];
DynamicStat<int> mDynamic[3]; // health, magicka, fatigue
int mLevel;
std::set<std::string> mAbilities;
Spells mSpells;
MagicEffects mMagicEffects;
};
}

@ -0,0 +1,13 @@
#ifndef GAME_MWMECHANICS_DRAWSTATE_H
#define GAME_MWMECHANICS_DRAWSTATE_H
#undef DrawState
enum DrawState
{
DrawState_Weapon = 0,
DrawState_Spell = 1,
DrawState_Nothing = 2,
};
#endif

@ -5,8 +5,9 @@
#include "../mwgui/window_manager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/player.hpp"
@ -14,7 +15,7 @@ namespace MWMechanics
{
void MechanicsManager::buildPlayer()
{
MWWorld::Ptr ptr = mEnvironment.mWorld->getPlayer().getPlayer();
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr);
@ -23,7 +24,7 @@ namespace MWMechanics
// reset
creatureStats.mLevel = player->npdt52.level;
creatureStats.mAbilities.clear();
creatureStats.mSpells.clear();
creatureStats.mMagicEffects = MagicEffects();
for (int i=0; i<27; ++i)
@ -33,10 +34,10 @@ namespace MWMechanics
if (mRaceSelected)
{
const ESM::Race *race =
mEnvironment.mWorld->getStore().races.find (
mEnvironment.mWorld->getPlayer().getRace());
MWBase::Environment::get().getWorld()->getStore().races.find (
MWBase::Environment::get().getWorld()->getPlayer().getRace());
bool male = mEnvironment.mWorld->getPlayer().isMale();
bool male = MWBase::Environment::get().getWorld()->getPlayer().isMale();
for (int i=0; i<8; ++i)
{
@ -71,28 +72,28 @@ namespace MWMechanics
for (std::vector<std::string>::const_iterator iter (race->powers.list.begin());
iter!=race->powers.list.end(); ++iter)
{
insertSpell (*iter, ptr);
creatureStats.mSpells.add (*iter);
}
}
// birthsign
if (!mEnvironment.mWorld->getPlayer().getBirthsign().empty())
if (!MWBase::Environment::get().getWorld()->getPlayer().getBirthsign().empty())
{
const ESM::BirthSign *sign =
mEnvironment.mWorld->getStore().birthSigns.find (
mEnvironment.mWorld->getPlayer().getBirthsign());
MWBase::Environment::get().getWorld()->getStore().birthSigns.find (
MWBase::Environment::get().getWorld()->getPlayer().getBirthsign());
for (std::vector<std::string>::const_iterator iter (sign->powers.list.begin());
iter!=sign->powers.list.end(); ++iter)
{
insertSpell (*iter, ptr);
creatureStats.mSpells.add (*iter);
}
}
// class
if (mClassSelected)
{
const ESM::Class& class_ = mEnvironment.mWorld->getPlayer().getClass();
const ESM::Class& class_ = MWBase::Environment::get().getWorld()->getPlayer().getClass();
for (int i=0; i<2; ++i)
{
@ -121,7 +122,7 @@ namespace MWMechanics
}
typedef ESMS::IndexListT<ESM::Skill>::MapType ContainerType;
const ContainerType& skills = mEnvironment.mWorld->getStore().skills.list;
const ContainerType& skills = MWBase::Environment::get().getWorld()->getStore().skills.list;
for (ContainerType::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter)
{
@ -159,59 +160,14 @@ namespace MWMechanics
creatureStats.mDynamic[i].setCurrent (creatureStats.mDynamic[i].getModified());
}
void MechanicsManager::insertSpell (const std::string& id, MWWorld::Ptr& creature)
{
MWMechanics::CreatureStats& creatureStats =
MWWorld::Class::get (creature).getCreatureStats (creature);
const ESM::Spell *spell = mEnvironment.mWorld->getStore().spells.find (id);
switch (spell->data.type)
{
case ESM::Spell::ST_Ability:
if (creatureStats.mAbilities.find (id)==creatureStats.mAbilities.end())
{
creatureStats.mAbilities.insert (id);
}
break;
// TODO ST_SPELL, ST_Blight, ST_Disease, ST_Curse, ST_Power
default:
std::cout
<< "adding unsupported spell type (" << spell->data.type
<< ") to creature: " << id << std::endl;
}
}
void MechanicsManager::adjustMagicEffects (MWWorld::Ptr& creature)
{
MWMechanics::CreatureStats& creatureStats =
MWWorld::Class::get (creature).getCreatureStats (creature);
MagicEffects now;
for (std::set<std::string>::const_iterator iter (creatureStats.mAbilities.begin());
iter!=creatureStats.mAbilities.end(); ++iter)
{
const ESM::Spell *spell = mEnvironment.mWorld->getStore().spells.find (*iter);
MagicEffects now = creatureStats.mSpells.getMagicEffects();
for (std::vector<ESM::ENAMstruct>::const_iterator iter = spell->effects.list.begin();
iter!=spell->effects.list.end(); ++iter)
{
if (iter->range==0) // self
{
EffectParam param;
param.mMagnitude = iter->magnMax; // TODO calculate magnitude
now.add (EffectKey (*iter), param);
}
}
}
// TODO add effects from other spell types, active spells and equipment
/// \todo add effects from active spells and equipment
MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now);
@ -220,8 +176,8 @@ namespace MWMechanics
// TODO apply diff to other stats
}
MechanicsManager::MechanicsManager (MWWorld::Environment& environment)
: mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false),
MechanicsManager::MechanicsManager()
: mUpdatePlayer (true), mClassSelected (false),
mRaceSelected (false)
{
buildPlayer();
@ -229,7 +185,7 @@ namespace MWMechanics
void MechanicsManager::addActor (const MWWorld::Ptr& ptr)
{
mActors.insert (ptr);
mActors.addActor (ptr);
}
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
@ -237,7 +193,7 @@ namespace MWMechanics
if (ptr==mWatched)
mWatched = MWWorld::Ptr();
mActors.erase (ptr);
mActors.removeActor (ptr);
}
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
@ -245,16 +201,7 @@ namespace MWMechanics
if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
mWatched = MWWorld::Ptr();
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
while (iter!=mActors.end())
if (iter->getCell()==cellStore)
{
//std::cout << "Erasing an actor";
mActors.erase (iter++);
}
else
++iter;
mActors.dropActors (cellStore);
}
void MechanicsManager::watchActor (const MWWorld::Ptr& ptr)
@ -262,7 +209,8 @@ namespace MWMechanics
mWatched = ptr;
}
void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement)
void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
float duration, bool paused)
{
if (!mWatched.isEmpty())
{
@ -289,7 +237,7 @@ namespace MWMechanics
{
mWatchedCreature.mAttributes[i] = stats.mAttributes[i];
mEnvironment.mWindowManager->setValue (attributeNames[i], stats.mAttributes[i]);
MWBase::Environment::get().getWindowManager()->setValue (attributeNames[i], stats.mAttributes[i]);
}
}
@ -299,7 +247,7 @@ namespace MWMechanics
{
mWatchedCreature.mDynamic[i] = stats.mDynamic[i];
mEnvironment.mWindowManager->setValue (dynamicNames[i], stats.mDynamic[i]);
MWBase::Environment::get().getWindowManager()->setValue (dynamicNames[i], stats.mDynamic[i]);
}
}
@ -312,25 +260,25 @@ namespace MWMechanics
{
update = true;
mWatchedNpc.mSkill[i] = npcStats.mSkill[i];
mEnvironment.mWindowManager->setValue((ESM::Skill::SkillEnum)i, npcStats.mSkill[i]);
MWBase::Environment::get().getWindowManager()->setValue((ESM::Skill::SkillEnum)i, npcStats.mSkill[i]);
}
}
if (update)
mEnvironment.mWindowManager->updateSkillArea();
MWBase::Environment::get().getWindowManager()->updateSkillArea();
mEnvironment.mWindowManager->setValue ("level", stats.mLevel);
MWBase::Environment::get().getWindowManager()->setValue ("level", stats.mLevel);
}
if (mUpdatePlayer)
{
// basic player profile; should not change anymore after the creation phase is finished.
mEnvironment.mWindowManager->setValue ("name", mEnvironment.mWorld->getPlayer().getName());
mEnvironment.mWindowManager->setValue ("race",
mEnvironment.mWorld->getStore().races.find (mEnvironment.mWorld->getPlayer().
MWBase::Environment::get().getWindowManager()->setValue ("name", MWBase::Environment::get().getWorld()->getPlayer().getName());
MWBase::Environment::get().getWindowManager()->setValue ("race",
MWBase::Environment::get().getWorld()->getStore().races.find (MWBase::Environment::get().getWorld()->getPlayer().
getRace())->name);
mEnvironment.mWindowManager->setValue ("class",
mEnvironment.mWorld->getPlayer().getClass().name);
MWBase::Environment::get().getWindowManager()->setValue ("class",
MWBase::Environment::get().getWorld()->getPlayer().getClass().name);
mUpdatePlayer = false;
MWGui::WindowManager::SkillList majorSkills (5);
@ -338,33 +286,26 @@ namespace MWMechanics
for (int i=0; i<5; ++i)
{
minorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][0];
majorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][1];
minorSkills[i] = MWBase::Environment::get().getWorld()->getPlayer().getClass().data.skills[i][0];
majorSkills[i] = MWBase::Environment::get().getWorld()->getPlayer().getClass().data.skills[i][1];
}
mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills);
MWBase::Environment::get().getWindowManager()->configureSkills (majorSkills, minorSkills);
}
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
++iter)
{
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
if (vector!=Ogre::Vector3::ZERO)
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
}
mActors.update (movement, duration, paused);
}
void MechanicsManager::setPlayerName (const std::string& name)
{
mEnvironment.mWorld->getPlayer().setName (name);
MWBase::Environment::get().getWorld()->getPlayer().setName (name);
mUpdatePlayer = true;
}
void MechanicsManager::setPlayerRace (const std::string& race, bool male)
{
mEnvironment.mWorld->getPlayer().setGender (male);
mEnvironment.mWorld->getPlayer().setRace (race);
MWBase::Environment::get().getWorld()->getPlayer().setGender (male);
MWBase::Environment::get().getWorld()->getPlayer().setRace (race);
mRaceSelected = true;
buildPlayer();
mUpdatePlayer = true;
@ -372,14 +313,14 @@ namespace MWMechanics
void MechanicsManager::setPlayerBirthsign (const std::string& id)
{
mEnvironment.mWorld->getPlayer().setBirthsign (id);
MWBase::Environment::get().getWorld()->getPlayer().setBirthsign (id);
buildPlayer();
mUpdatePlayer = true;
}
void MechanicsManager::setPlayerClass (const std::string& id)
{
mEnvironment.mWorld->getPlayer().setClass (*mEnvironment.mWorld->getStore().classes.find (id));
MWBase::Environment::get().getWorld()->getPlayer().setClass (*MWBase::Environment::get().getWorld()->getStore().classes.find (id));
mClassSelected = true;
buildPlayer();
mUpdatePlayer = true;
@ -387,7 +328,7 @@ namespace MWMechanics
void MechanicsManager::setPlayerClass (const ESM::Class& class_)
{
mEnvironment.mWorld->getPlayer().setClass (class_);
MWBase::Environment::get().getWorld()->getPlayer().setClass (class_);
mClassSelected = true;
buildPlayer();
mUpdatePlayer = true;

@ -1,7 +1,6 @@
#ifndef GAME_MWMECHANICS_MECHANICSMANAGER_H
#define GAME_MWMECHANICS_MECHANICSMANAGER_H
#include <set>
#include <vector>
#include <string>
@ -9,41 +8,34 @@
#include "creaturestats.hpp"
#include "npcstats.hpp"
#include "actors.hpp"
namespace Ogre
{
class Vector3;
}
namespace MWWorld
{
class Environment;
}
namespace MWMechanics
{
class MechanicsManager
{
MWWorld::Environment& mEnvironment;
std::set<MWWorld::Ptr> mActors;
MWWorld::Ptr mWatched;
CreatureStats mWatchedCreature;
NpcStats mWatchedNpc;
bool mUpdatePlayer;
bool mClassSelected;
bool mRaceSelected;
Actors mActors;
void buildPlayer();
///< build player according to stored class/race/birthsign information. Will
/// default to the values of the ESM::NPC object, if no explicit information is given.
void insertSpell (const std::string& id, MWWorld::Ptr& creature);
void adjustMagicEffects (MWWorld::Ptr& creature);
public:
MechanicsManager (MWWorld::Environment& environment);
MechanicsManager ();
void configureGUI();
@ -60,8 +52,12 @@ namespace MWMechanics
///< On each update look for changes in a previously registered actor and update the
/// GUI accordingly.
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement);
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement, float duration,
bool paused);
///< 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
/// component is up).
void setPlayerName (const std::string& name);
///< Set player name.

@ -2,14 +2,19 @@
#define GAME_MWMECHANICS_NPCSTATS_H
#include <map>
#include <set>
#include "stat.hpp"
#include "drawstate.hpp"
namespace MWMechanics
{
/// \brief Additional stats for NPCs
///
/// For non-NPC-specific stats, see the CreatureStats struct.
///
/// \note For technical reasons the spell list and the currently selected spell is also handled by
/// CreatureStats, even though they are actually NPC stats.
struct NpcStats
{
@ -24,9 +29,10 @@ namespace MWMechanics
bool mRun;
bool mSneak;
bool mCombat;
DrawState mDrawState;
NpcStats() : mForceRun (false), mForceSneak (false), mRun (false), mSneak (false),
mCombat (false) {}
mCombat (false) , mDrawState(DrawState_Nothing) {}
};
}

@ -0,0 +1,82 @@
#include "spells.hpp"
#include <components/esm/loadspel.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
#include "magiceffects.hpp"
namespace MWMechanics
{
void Spells::addSpell (const ESM::Spell *spell, MagicEffects& effects) const
{
for (std::vector<ESM::ENAMstruct>::const_iterator iter = spell->effects.list.begin();
iter!=spell->effects.list.end(); ++iter)
{
EffectParam param;
param.mMagnitude = iter->magnMax; /// \todo calculate magnitude
effects.add (EffectKey (*iter), param);
}
}
Spells::TIterator Spells::begin() const
{
return mSpells.begin();
}
Spells::TIterator Spells::end() const
{
return mSpells.end();
}
void Spells::add (const std::string& spellId)
{
if (std::find (mSpells.begin(), mSpells.end(), spellId)!=mSpells.end())
mSpells.push_back (spellId);
}
void Spells::remove (const std::string& spellId)
{
TContainer::iterator iter = std::find (mSpells.begin(), mSpells.end(), spellId);
if (iter!=mSpells.end())
mSpells.erase (iter);
if (spellId==mSelectedSpell)
mSelectedSpell.clear();
}
MagicEffects Spells::getMagicEffects() const
{
MagicEffects effects;
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
{
const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().spells.find (*iter);
if (spell->data.type==ESM::Spell::ST_Ability || spell->data.type==ESM::Spell::ST_Blight ||
spell->data.type==ESM::Spell::ST_Disease || spell->data.type==ESM::Spell::ST_Curse)
addSpell (spell, effects);
}
return effects;
}
void Spells::clear()
{
mSpells.clear();
}
void Spells::setSelectedSpell (const std::string& spellId)
{
mSelectedSpell = spellId;
}
const std::string Spells::getSelectedSpell() const
{
return mSelectedSpell;
}
}

@ -0,0 +1,61 @@
#ifndef GAME_MWMECHANICS_SPELLS_H
#define GAME_MWMECHANICS_SPELLS_H
#include <vector>
#include <string>
namespace ESM
{
struct Spell;
}
namespace MWMechanics
{
class MagicEffects;
/// \brief Spell list
///
/// This class manages known spells as well as abilities, powers and permanent negative effects like
/// diseaes.
class Spells
{
public:
typedef std::vector<std::string> TContainer;
typedef TContainer::const_iterator TIterator;
private:
std::vector<std::string> mSpells;
std::string mSelectedSpell;
void addSpell (const ESM::Spell *, MagicEffects& effects) const;
public:
TIterator begin() const;
TIterator end() const;
void add (const std::string& spell);
///< Adding a spell that is already listed in *this is a no-op.
void remove (const std::string& spell);
///< If the spell to be removed is the selected spell, the selected spell will be changed to
/// no spell (empty string).
MagicEffects getMagicEffects() const;
///< Return sum of magic effects resulting from abilities, blights, deseases and curses.
void clear();
///< Remove all spells of al types.
void setSelectedSpell (const std::string& spellId);
///< This function does not verify, if the spell is available.
const std::string getSelectedSpell() const;
///< May return an empty string.
};
}
#endif

@ -20,12 +20,12 @@ Actors::~Actors(){
void Actors::setMwRoot(Ogre::SceneNode* root){
mMwRoot = root;
}
void Actors::insertNPC(const MWWorld::Ptr& ptr){
void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv){
insertBegin(ptr, true, true);
NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mEnvironment, mRend);
insertBegin(ptr, true, true);
NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mRend, inv);
mAllActors[ptr] = anim;
mAllActors[ptr] = anim;
}
void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){
Ogre::SceneNode* cellnode;
@ -68,7 +68,7 @@ void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){
void Actors::insertCreature (const MWWorld::Ptr& ptr){
insertBegin(ptr, true, true);
CreatureAnimation* anim = new MWRender::CreatureAnimation(ptr, mEnvironment, mRend);
CreatureAnimation* anim = new MWRender::CreatureAnimation(ptr, mRend);
//mAllActors.insert(std::pair<MWWorld::Ptr, Animation*>(ptr,anim));
delete mAllActors[ptr];
mAllActors[ptr] = anim;

@ -13,7 +13,6 @@
#include "../mwworld/refdata.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp"
#include "../mwworld/environment.hpp"
#include "npcanimation.hpp"
#include "creatureanimation.hpp"
#include <openengine/bullet/physic.hpp>
@ -23,18 +22,17 @@ namespace MWRender{
OEngine::Render::OgreRenderer &mRend;
std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes;
Ogre::SceneNode* mMwRoot;
MWWorld::Environment& mEnvironment;
std::map<MWWorld::Ptr, Animation*> mAllActors;
public:
Actors(OEngine::Render::OgreRenderer& _rend, MWWorld::Environment& _env): mRend(_rend), mEnvironment(_env){}
Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {}
~Actors();
void setMwRoot(Ogre::SceneNode* root);
void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
void insertCreature (const MWWorld::Ptr& ptr);
void insertNPC(const MWWorld::Ptr& ptr);
void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv);
bool deleteObject (const MWWorld::Ptr& ptr);
///< \return found?

@ -4,12 +4,10 @@
namespace MWRender{
std::map<std::string, int> Animation::mUniqueIDs;
Animation::Animation(MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend)
Animation::Animation(OEngine::Render::OgreRenderer& _rend)
: insert(NULL)
, mRend(_rend)
, mEnvironment(_env)
, vecRotPos()
, shapeparts()
, time(0.0f)
, startTime(0.0f)
, stopTime(0.0f)
@ -19,7 +17,6 @@ namespace MWRender{
, shapeNumber(0)
, shapeIndexI()
, shapes(NULL)
, entityparts()
, transformations(NULL)
, textmappings(NULL)
, base(NULL)
@ -305,8 +302,8 @@ namespace MWRender{
for(; boneSequenceIter != boneSequence.end(); boneSequenceIter++)
{
if(creaturemodel->getSkeleton()->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(*boneSequenceIter);
if(skel->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
// Computes C = B + AxC*scale
transmult = transmult + rotmult * bonePtr->getPosition();
rotmult = rotmult * bonePtr->getOrientation();
@ -430,14 +427,7 @@ namespace MWRender{
//base->_updateAnimation();
//base->_notifyMoved();
for(unsigned int i = 0; i < entityparts.size(); i++){
//Ogre::SkeletonInstance* skel = entityparts[i]->getSkeleton();
//Ogre::Bone* b = skel->getRootBone();
//b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3));//This is a trick
//entityparts[i]->getAllAnimationStates()->_notifyDirty();
}
std::vector<Nif::NiKeyframeData>::iterator iter;

@ -5,7 +5,6 @@
#include "../mwworld/refdata.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp"
#include "../mwworld/environment.hpp"
#include <components/nif/node.hpp>
#include <map>
#include <openengine/bullet/physic.hpp>
@ -21,17 +20,16 @@ struct PosAndRot{
};
class Animation{
protected:
Ogre::SceneNode* insert;
OEngine::Render::OgreRenderer &mRend;
MWWorld::Environment& mEnvironment;
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot> vecRotPos;
static std::map<std::string, int> mUniqueIDs;
std::vector<std::vector<Nif::NiTriShapeCopy>* > shapeparts; //All the NiTriShape data that we need for animating an npc
float time;
float startTime;
@ -41,14 +39,14 @@ class Animation{
std::vector<int>rindexI;
//Represents a translation index for each bone
std::vector<int>tindexI;
//Only shapes with morphing data will use a shape number
int shapeNumber;
std::vector<std::vector<int> > shapeIndexI;
//Ogre::SkeletonInstance* skel;
std::vector<Nif::NiTriShapeCopy>* shapes; //All the NiTriShapeData for a creature
std::vector<Ogre::Entity*> entityparts;
std::vector<Nif::NiKeyframeData>* transformations;
@ -58,16 +56,16 @@ class Animation{
void handleAnimationTransforms();
bool timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x );
std::string getUniqueID(std::string mesh);
public:
Animation(MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend);
Animation(OEngine::Render::OgreRenderer& _rend);
virtual void runAnimation(float timepassed) = 0;
void startScript(std::string groupname, int mode, int loops);
void stopScript();
virtual ~Animation();
};
}
#endif

@ -1,4 +1,5 @@
#include "creatureanimation.hpp"
#include "renderconst.hpp"
#include "../mwworld/world.hpp"
@ -9,7 +10,7 @@ namespace MWRender{
CreatureAnimation::~CreatureAnimation(){
}
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend): Animation(_env,_rend){
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend): Animation(_rend){
insert = ptr.getRefData().getBaseNode();
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
ptr.get<ESM::Creature>();
@ -20,6 +21,28 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme
std::string meshNumbered = mesh + getUniqueID(mesh) + ">|";
NifOgre::NIFLoader::load(meshNumbered);
base = mRend.getScene()->createEntity(meshNumbered);
base->setVisibilityFlags(RV_Actors);
bool transparent = false;
for (unsigned int i=0; i<base->getNumSubEntities(); ++i)
{
Ogre::MaterialPtr mat = base->getSubEntity(i)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
}
}
}
base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
std::string meshZero = mesh + "0000>|";
if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){

@ -7,20 +7,19 @@
#include "../mwworld/refdata.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/environment.hpp"
#include "components/nifogre/ogre_nif_loader.hpp"
namespace MWRender{
class CreatureAnimation: public Animation{
public:
virtual ~CreatureAnimation();
CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend);
CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend);
virtual void runAnimation(float timepassed);
};
}
#endif
#endif

@ -8,7 +8,7 @@
#include <OgreMaterialManager.h>
#include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
#include "../mwworld/environment.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp"
#include <components/esm/loadstat.hpp>
#include <components/esm/loadpgrd.hpp>
@ -138,8 +138,8 @@ ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid)
return result;
}
Debugging::Debugging(SceneNode *mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine) :
mMwRoot(mwRoot), mEnvironment(env), mEngine(engine),
Debugging::Debugging(SceneNode *mwRoot, OEngine::Physic::PhysicEngine *engine) :
mMwRoot(mwRoot), mEngine(engine),
mSceneMgr(mwRoot->getCreator()),
mPathgridEnabled(false),
mInteriorPathgridNode(NULL), mPathGridRoot(NULL),
@ -218,7 +218,7 @@ void Debugging::togglePathgrid()
void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store)
{
ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().pathgrids.search(*store->cell);
ESM::Pathgrid *pathgrid = MWBase::Environment::get().getWorld()->getStore().pathgrids.search(*store->cell);
if (!pathgrid) return;
Vector3 cellPathGridPos(0, 0, 0);

@ -23,7 +23,6 @@ namespace Ogre
namespace MWWorld
{
class World;
class Environment;
}
namespace MWRender
@ -34,7 +33,6 @@ namespace MWRender
{
OEngine::Physic::PhysicEngine* mEngine;
Ogre::SceneManager *mSceneMgr;
MWWorld::Environment& mEnvironment;
// Path grid stuff
bool mPathgridEnabled;
@ -68,7 +66,7 @@ namespace MWRender
Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid);
Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid);
public:
Debugging(Ogre::SceneNode* mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine);
Debugging(Ogre::SceneNode* mwRoot, OEngine::Physic::PhysicEngine *engine);
~Debugging();
bool toggleRenderMode (int mode);

@ -1,9 +1,10 @@
#include "localmap.hpp"
#include "renderingmanager.hpp"
#include "../mwworld/environment.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwgui/window_manager.hpp"
#include "renderconst.hpp"
#include <OgreOverlayManager.h>
#include <OgreMaterialManager.h>
@ -11,12 +12,11 @@
using namespace MWRender;
using namespace Ogre;
LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering, MWWorld::Environment* env) :
LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering) :
mInterior(false), mCellX(0), mCellY(0)
{
mRendering = rend;
mRenderingManager = rendering;
mEnvironment = env;
mCameraPosNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
mCameraRotNode = mCameraPosNode->createChildSceneNode();
@ -53,12 +53,12 @@ void LocalMap::saveTexture(const std::string& texname, const std::string& filena
if (tex.isNull()) return;
HardwarePixelBufferSharedPtr readbuffer = tex->getBuffer();
readbuffer->lock(HardwareBuffer::HBL_NORMAL );
const PixelBox &readrefpb = readbuffer->getCurrentLock();
uchar *readrefdata = static_cast<uchar*>(readrefpb.data);
const PixelBox &readrefpb = readbuffer->getCurrentLock();
uchar *readrefdata = static_cast<uchar*>(readrefpb.data);
Image img;
img = img.loadDynamicImage (readrefdata, tex->getWidth(),
tex->getHeight(), tex->getFormat());
tex->getHeight(), tex->getFormat());
img.save("./" + filename);
readbuffer->unlock();
@ -81,7 +81,7 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell)
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
Vector2 length = max-min;
// divide into segments
const int segsX = std::ceil( length.x / sSize );
const int segsY = std::ceil( length.y / sSize );
@ -122,7 +122,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y);
const Vector2& north = mEnvironment->mWorld->getNorthVector(cell);
const Vector2& north = MWBase::Environment::get().getWorld()->getNorthVector(cell);
Radian angle(std::atan2(-north.x, -north.y));
mAngle = angle.valueRadians();
mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0));
@ -212,7 +212,7 @@ void LocalMap::render(const float x, const float y,
texture,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
xw*sMapResolution/sSize, yw*sMapResolution/sSize,
xw*sMapResolution/sSize, yw*sMapResolution/sSize,
0,
PF_R8G8B8,
TU_RENDERTARGET);
@ -223,7 +223,10 @@ void LocalMap::render(const float x, const float y,
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setBackgroundColour(ColourValue(0, 0, 0));
//vp->setVisibilityMask( ... );
vp->setVisibilityMask(RV_Map);
// use fallback techniques without shadows and without mrt
vp->setMaterialScheme("Fallback");
rtt->update();
@ -232,7 +235,7 @@ void LocalMap::render(const float x, const float y,
texture + "_fog",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
xw*sFogOfWarResolution/sSize, yw*sFogOfWarResolution/sSize,
xw*sFogOfWarResolution/sSize, yw*sFogOfWarResolution/sSize,
0,
PF_A8R8G8B8,
TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
@ -272,7 +275,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
return;
}
// retrieve the x,y grid coordinates the player is in
// retrieve the x,y grid coordinates the player is in
int x,y;
Vector3 _pos(position.x, 0, position.z);
Vector2 pos(_pos.x, _pos.z);
@ -299,7 +302,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
x = std::ceil((pos.x - min.x)/sSize)-1;
y = std::ceil((pos.y - min.y)/sSize)-1;
mEnvironment->mWindowManager->setInteriorMapTexture(x,y);
MWBase::Environment::get().getWindowManager()->setInteriorMapTexture(x,y);
}
// convert from world coordinates to texture UV coordinates
@ -319,8 +322,8 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
texName = mInteriorName + "_" + coordStr(x,y);
}
mEnvironment->mWindowManager->setPlayerPos(u, v);
mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z);
MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v);
MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, -playerdirection.z);
// explore radius (squared)
const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution;

@ -5,11 +5,6 @@
#include <openengine/ogre/renderer.hpp>
namespace MWWorld
{
class Environment;
}
namespace MWRender
{
class RenderingManager;
@ -20,7 +15,7 @@ namespace MWRender
class LocalMap
{
public:
LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering, MWWorld::Environment* env);
LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering);
~LocalMap();
/**
@ -61,7 +56,6 @@ namespace MWRender
private:
OEngine::Render::OgreRenderer* mRendering;
MWRender::RenderingManager* mRenderingManager;
MWWorld::Environment* mEnvironment;
// 1024*1024 pixels for a cell
static const int sMapResolution = 1024;

@ -1,6 +1,8 @@
#include "npcanimation.hpp"
#include "../mwworld/world.hpp"
#include "renderconst.hpp"
#include "../mwbase/environment.hpp"
using namespace Ogre;
using namespace NifOgre;
@ -10,9 +12,49 @@ NpcAnimation::~NpcAnimation(){
}
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend): Animation(_env,_rend){
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_rend), mStateID(-1), inv(_inv), timeToChange(0),
robe(inv.end()), helmet(inv.end()), shirt(inv.end()),
cuirass(inv.end()), greaves(inv.end()),
leftpauldron(inv.end()), rightpauldron(inv.end()),
boots(inv.end()),
leftglove(inv.end()), rightglove(inv.end()), skirtiter(inv.end()),
pants(inv.end()),
lclavicle(0),
rclavicle(0),
rupperArm(0),
lupperArm(0),
rUpperLeg(0),
lUpperLeg(0),
lForearm(0),
rForearm(0),
lWrist(0),
rWrist(0),
rKnee(0),
lKnee(0),
neck(0),
rAnkle(0),
lAnkle(0),
groin(0),
lfoot(0),
rfoot(0)
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
ptr.get<ESM::NPC>();
Ogre::Entity* blank = 0;
std::vector<Nif::NiTriShapeCopy>* blankshape = 0;
zero = std::make_pair(blank, blankshape);
chest = std::make_pair(blank, blankshape);
tail = std::make_pair(blank, blankshape);
lFreeFoot = std::make_pair(blank, blankshape);
rFreeFoot = std::make_pair(blank, blankshape);
rhand = std::make_pair(blank, blankshape);
lhand = std::make_pair(blank, blankshape);
skirt = std::make_pair(blank, blankshape);
for (int init = 0; init < 27; init++){
partslots[init] = -1; //each slot is empty
partpriorities[init] = 0;
}
//Part selection on last character of the file string
// " Tri Chest
@ -34,16 +76,22 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
std::string hairID = ref->base->hair;
std::string headID = ref->base->head;
std::string npcName = ref->base->name;
headModel = "meshes\\" +
MWBase::Environment::get().getWorld()->getStore().bodyParts.find(headID)->model;
hairModel = "meshes\\" +
MWBase::Environment::get().getWorld()->getStore().bodyParts.find(hairID)->model;
npcName = ref->base->name;
//ESMStore::Races r =
const ESM::Race* race = mEnvironment.mWorld->getStore().races.find(ref->base->race);
const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().races.find(ref->base->race);
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2);
bool female = tolower(secondtolast) == 'f';
isFemale = tolower(secondtolast) == 'f';
std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower);
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
isBeast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
/*std::cout << "Race: " << ref->base->race ;
if(female){
@ -56,7 +104,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
std::string smodel = "meshes\\base_anim.nif";
if(beast)
if(isBeast)
smodel = "meshes\\base_animkna.nif";
insert = ptr.getRefData().getBaseNode();
@ -65,6 +113,29 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
NifOgre::NIFLoader::load(smodel);
base = mRend.getScene()->createEntity(smodel);
base->setVisibilityFlags(RV_Actors);
bool transparent = false;
for (unsigned int i=0; i<base->getNumSubEntities(); ++i)
{
Ogre::MaterialPtr mat = base->getSubEntity(i)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
}
}
}
base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones
//stay in the same place when we skipanim, or open a gui window
@ -83,168 +154,412 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
textmappings = NIFLoader::getSingletonPtr()->getTextIndices(smodel);
insert->attachObject(base);
if(female)
if(isFemale)
insert->scale(race->data.height.female, race->data.height.female, race->data.height.female);
else
insert->scale(race->data.height.male, race->data.height.male, race->data.height.male);
std::string headModel = "meshes\\" +
mEnvironment.mWorld->getStore().bodyParts.find(headID)->model;
std::string hairModel = "meshes\\" +
mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model;
const ESM::BodyPart *chest = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest");
const ESM::BodyPart *upperleg = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg");
const ESM::BodyPart *groin = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "groin");
const ESM::BodyPart *arml = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); //We need two
const ESM::BodyPart *neck = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "neck");
const ESM::BodyPart *knee = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee");
const ESM::BodyPart *ankle = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle");
const ESM::BodyPart *foot = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot");
const ESM::BodyPart *feet = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet");
const ESM::BodyPart *tail = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail");
const ESM::BodyPart *wristl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); //We need two
const ESM::BodyPart *forearml = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); //We need two
const ESM::BodyPart *handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); //We need two
const ESM::BodyPart *hair = mEnvironment.mWorld->getStore().bodyParts.search(hairID);
const ESM::BodyPart *head = mEnvironment.mWorld->getStore().bodyParts.search(headID);
if(bodyRaceID == "b_n_argonian_f_")
forearml = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); //We need two
if(!handl)
handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands");
//const ESM::BodyPart* claviclel = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "clavicle");
//const ESM::BodyPart* clavicler = claviclel;
const ESM::BodyPart* handr = handl;
const ESM::BodyPart* forearmr = forearml;
const ESM::BodyPart* wristr = wristl;
const ESM::BodyPart* armr = arml;
if(upperleg){
insertBoundedPart("meshes\\" + upperleg->model + "*|", "Left Upper Leg");
insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg");
updateParts();
}
if(foot){
if(bodyRaceID.compare("b_n_khajiit_m_") == 0)
{
feet = foot;
}
else
{
insertBoundedPart("meshes\\" + foot->model, "Right Foot");
insertBoundedPart("meshes\\" + foot->model + "*|", "Left Foot");
}
}
if(groin){
insertBoundedPart("meshes\\" + groin->model, "Groin");
}
if(knee)
{
insertBoundedPart("meshes\\" + knee->model + "*|", "Left Knee"); //e
insertBoundedPart("meshes\\" + knee->model, "Right Knee"); //e
}
}
if(ankle){
void NpcAnimation::updateParts(){
insertBoundedPart("meshes\\" + ankle->model + "*|", "Left Ankle"); //Ogre::Quaternion(Ogre::Radian(3.14 / 4), Ogre::Vector3(1, 0, 0)),blank); //1,0,0, blank);
insertBoundedPart("meshes\\" + ankle->model, "Right Ankle");
}
if (armr){
insertBoundedPart("meshes\\" + armr->model, "Right Upper Arm");
bool apparelChanged = false;
//inv.getSlot(MWWorld::InventoryStore::Slot_Robe);
if(robe != inv.getSlot(MWWorld::InventoryStore::Slot_Robe)){
//A robe was added or removed
removePartGroup(MWWorld::InventoryStore::Slot_Robe);
robe = inv.getSlot(MWWorld::InventoryStore::Slot_Robe);
apparelChanged = true;
}
if(arml){
insertBoundedPart("meshes\\" + arml->model + "*|", "Left Upper Arm");
if(skirtiter != inv.getSlot(MWWorld::InventoryStore::Slot_Skirt)){
//A robe was added or removed
removePartGroup(MWWorld::InventoryStore::Slot_Skirt);
skirtiter = inv.getSlot(MWWorld::InventoryStore::Slot_Skirt);
apparelChanged = true;
}
if(helmet != inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)){
apparelChanged = true;
helmet = inv.getSlot(MWWorld::InventoryStore::Slot_Helmet);
removePartGroup(MWWorld::InventoryStore::Slot_Helmet);
if (forearmr)
{
insertBoundedPart("meshes\\" + forearmr->model, "Right Forearm");
}
if(forearml)
insertBoundedPart("meshes\\" + forearml->model + "*|", "Left Forearm");
}
if(cuirass != inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)){
cuirass = inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass);
removePartGroup(MWWorld::InventoryStore::Slot_Cuirass);
apparelChanged = true;
if (wristr)
{
insertBoundedPart("meshes\\" + wristr->model, "Right Wrist");
}
}
if(greaves != inv.getSlot(MWWorld::InventoryStore::Slot_Greaves)){
greaves = inv.getSlot(MWWorld::InventoryStore::Slot_Greaves);
removePartGroup(MWWorld::InventoryStore::Slot_Greaves);
apparelChanged = true;
}
if(leftpauldron != inv.getSlot(MWWorld::InventoryStore::Slot_LeftPauldron)){
leftpauldron = inv.getSlot(MWWorld::InventoryStore::Slot_LeftPauldron);
removePartGroup(MWWorld::InventoryStore::Slot_LeftPauldron);
apparelChanged = true;
}
if(rightpauldron != inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron)){
rightpauldron = inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron);
removePartGroup(MWWorld::InventoryStore::Slot_RightPauldron);
apparelChanged = true;
}
if(!isBeast && boots != inv.getSlot(MWWorld::InventoryStore::Slot_Boots)){
boots = inv.getSlot(MWWorld::InventoryStore::Slot_Boots);
removePartGroup(MWWorld::InventoryStore::Slot_Boots);
apparelChanged = true;
if(wristl)
insertBoundedPart("meshes\\" + wristl->model + "*|", "Left Wrist");
}
if(leftglove != inv.getSlot(MWWorld::InventoryStore::Slot_LeftGauntlet)){
leftglove = inv.getSlot(MWWorld::InventoryStore::Slot_LeftGauntlet);
removePartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet);
apparelChanged = true;
}
if(rightglove != inv.getSlot(MWWorld::InventoryStore::Slot_RightGauntlet)){
rightglove = inv.getSlot(MWWorld::InventoryStore::Slot_RightGauntlet);
removePartGroup(MWWorld::InventoryStore::Slot_RightGauntlet);
apparelChanged = true;
}
if(shirt != inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)){
shirt = inv.getSlot(MWWorld::InventoryStore::Slot_Shirt);
removePartGroup(MWWorld::InventoryStore::Slot_Shirt);
apparelChanged = true;
}
if(pants != inv.getSlot(MWWorld::InventoryStore::Slot_Pants)){
pants = inv.getSlot(MWWorld::InventoryStore::Slot_Pants);
removePartGroup(MWWorld::InventoryStore::Slot_Pants);
apparelChanged = true;
}
if(apparelChanged){
if(robe != inv.end())
{
MWWorld::Ptr ptr = *robe;
const ESM::Clothing *clothes = (ptr.get<ESM::Clothing>())->base;
std::vector<ESM::PartReference> parts = clothes->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_Robe, 5, parts);
reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_Skirt, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_RLeg, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_LLeg, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_RUpperarm, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_LUpperarm, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_RKnee, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_LKnee, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_RForearm, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_LForearm, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_RPauldron, MWWorld::InventoryStore::Slot_Robe, 5);
reserveIndividualPart(ESM::PRT_LPauldron, MWWorld::InventoryStore::Slot_Robe, 5);
}
if(skirtiter != inv.end())
{
MWWorld::Ptr ptr = *skirtiter;
const ESM::Clothing *clothes = (ptr.get<ESM::Clothing>())->base;
std::vector<ESM::PartReference> parts = clothes->parts.parts;
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(helmet != inv.end()){
removeIndividualPart(ESM::PRT_Hair);
const ESM::Armor *armor = (helmet->get<ESM::Armor>())->base;
std::vector<ESM::PartReference> parts = armor->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_Helmet, 3, parts);
}
if(cuirass != inv.end()){
const ESM::Armor *armor = (cuirass->get<ESM::Armor>())->base;
std::vector<ESM::PartReference> parts = armor->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_Cuirass, 3, parts);
}
if(greaves != inv.end()){
const ESM::Armor *armor = (greaves->get<ESM::Armor>())->base;
std::vector<ESM::PartReference> parts = armor->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_Greaves, 3, parts);
}
if(leftpauldron != inv.end()){
const ESM::Armor *armor = (leftpauldron->get<ESM::Armor>())->base;
std::vector<ESM::PartReference> parts = armor->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_LeftPauldron, 3, parts);
}
if(rightpauldron != inv.end()){
const ESM::Armor *armor = (rightpauldron->get<ESM::Armor>())->base;
std::vector<ESM::PartReference> parts = armor->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_RightPauldron, 3, parts);
}
if(!isBeast && boots != inv.end()){
if(boots->getTypeName() == typeid(ESM::Clothing).name()){
const ESM::Clothing *clothes = (boots->get<ESM::Clothing>())->base;
std::vector<ESM::PartReference> parts = clothes->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_Boots, 2, parts);
}
else if(boots->getTypeName() == typeid(ESM::Armor).name())
{
const ESM::Armor *armor = (boots->get<ESM::Armor>())->base;
std::vector<ESM::PartReference> parts = armor->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_Boots, 3, parts);
}
}
if(leftglove != inv.end()){
if(leftglove->getTypeName() == typeid(ESM::Clothing).name()){
const ESM::Clothing *clothes = (leftglove->get<ESM::Clothing>())->base;
std::vector<ESM::PartReference> parts = clothes->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 2, parts);
}
else
{
const ESM::Armor *armor = (leftglove->get<ESM::Armor>())->base;
std::vector<ESM::PartReference> parts = armor->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 3, parts);
}
}
if(rightglove != inv.end()){
if(rightglove->getTypeName() == typeid(ESM::Clothing).name()){
const ESM::Clothing *clothes = (rightglove->get<ESM::Clothing>())->base;
std::vector<ESM::PartReference> parts = clothes->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 2, parts);
}
else
{
const ESM::Armor *armor = (rightglove->get<ESM::Armor>())->base;
std::vector<ESM::PartReference> parts = armor->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 3, parts);
}
}
if(shirt != inv.end()){
const ESM::Clothing *clothes = (shirt->get<ESM::Clothing>())->base;
std::vector<ESM::PartReference> parts = clothes->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_Shirt, 2, parts);
}
if(pants != inv.end()){
const ESM::Clothing *clothes = (pants->get<ESM::Clothing>())->base;
std::vector<ESM::PartReference> parts = clothes->parts.parts;
addPartGroup(MWWorld::InventoryStore::Slot_Pants, 2, parts);
}
}
if(partpriorities[ESM::PRT_Head] < 1){
addOrReplaceIndividualPart(ESM::PRT_Head, -1,1,headModel);
}
if(partpriorities[ESM::PRT_Hair] < 1 && partpriorities[ESM::PRT_Head] <= 1){
addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1,hairModel);
}
if(partpriorities[ESM::PRT_Neck] < 1){
const ESM::BodyPart *neckPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "neck");
if(neckPart)
addOrReplaceIndividualPart(ESM::PRT_Neck, -1,1,"meshes\\" + neckPart->model);
}
if(partpriorities[ESM::PRT_Cuirass] < 1){
const ESM::BodyPart *chestPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "chest");
if(chestPart)
addOrReplaceIndividualPart(ESM::PRT_Cuirass, -1,1,"meshes\\" + chestPart->model);
}
if(partpriorities[ESM::PRT_Groin] < 1){
const ESM::BodyPart *groinPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "groin");
if(groinPart)
addOrReplaceIndividualPart(ESM::PRT_Groin, -1,1,"meshes\\" + groinPart->model);
}
if(partpriorities[ESM::PRT_RHand] < 1){
const ESM::BodyPart *handPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "hand");
if(!handPart)
handPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "hands");
if(handPart)
addOrReplaceIndividualPart(ESM::PRT_RHand, -1,1,"meshes\\" + handPart->model);
}
if(partpriorities[ESM::PRT_LHand] < 1){
const ESM::BodyPart *handPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "hand");
if(!handPart)
handPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "hands");
if(handPart)
addOrReplaceIndividualPart(ESM::PRT_LHand, -1,1,"meshes\\" + handPart->model);
}
if(partpriorities[ESM::PRT_RWrist] < 1){
const ESM::BodyPart *wristPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "wrist");
if(wristPart)
addOrReplaceIndividualPart(ESM::PRT_RWrist, -1,1,"meshes\\" + wristPart->model);
}
if(partpriorities[ESM::PRT_LWrist] < 1){
const ESM::BodyPart *wristPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "wrist");
if(wristPart)
addOrReplaceIndividualPart(ESM::PRT_LWrist, -1,1,"meshes\\" + wristPart->model);
}
if(partpriorities[ESM::PRT_RForearm] < 1){
const ESM::BodyPart *forearmPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "forearm");
if(bodyRaceID == "b_n_argonian_f_")
forearmPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search ("b_n_argonian_m_forearm");
if(forearmPart)
addOrReplaceIndividualPart(ESM::PRT_RForearm, -1,1,"meshes\\" + forearmPart->model);
}
if(partpriorities[ESM::PRT_LForearm] < 1){
const ESM::BodyPart *forearmPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "forearm");
if(bodyRaceID == "b_n_argonian_f_")
forearmPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search ("b_n_argonian_m_forearm");
if(forearmPart)
addOrReplaceIndividualPart(ESM::PRT_LForearm, -1,1,"meshes\\" + forearmPart->model);
}
if(partpriorities[ESM::PRT_RUpperarm] < 1){
const ESM::BodyPart *armPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "upper arm");
if(armPart)
addOrReplaceIndividualPart(ESM::PRT_RUpperarm, -1,1,"meshes\\" + armPart->model);
}
if(partpriorities[ESM::PRT_LUpperarm] < 1){
const ESM::BodyPart *armPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "upper arm");
if(armPart)
addOrReplaceIndividualPart(ESM::PRT_LUpperarm, -1,1,"meshes\\" + armPart->model);
}
if(partpriorities[ESM::PRT_RFoot] < 1){
const ESM::BodyPart *footPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "foot");
if(isBeast && !footPart)
footPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "feet");
if(footPart)
addOrReplaceIndividualPart(ESM::PRT_RFoot, -1,1,"meshes\\" + footPart->model);
}
if(partpriorities[ESM::PRT_LFoot] < 1){
const ESM::BodyPart *footPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "foot");
if(isBeast && !footPart)
footPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "feet");
if(footPart)
addOrReplaceIndividualPart(ESM::PRT_LFoot, -1,1,"meshes\\" + footPart->model);
}
if(partpriorities[ESM::PRT_RAnkle] < 1){
const ESM::BodyPart *anklePart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "ankle");
if(anklePart)
addOrReplaceIndividualPart(ESM::PRT_RAnkle, -1,1,"meshes\\" + anklePart->model);
}
if(partpriorities[ESM::PRT_LAnkle] < 1){
const ESM::BodyPart *anklePart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "ankle");
if(anklePart)
addOrReplaceIndividualPart(ESM::PRT_LAnkle, -1,1,"meshes\\" + anklePart->model);
}
if(partpriorities[ESM::PRT_RKnee] < 1){
const ESM::BodyPart *kneePart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "knee");
if(kneePart)
addOrReplaceIndividualPart(ESM::PRT_RKnee, -1,1,"meshes\\" + kneePart->model);
}
if(partpriorities[ESM::PRT_LKnee] < 1){
const ESM::BodyPart *kneePart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "knee");
if(kneePart)
addOrReplaceIndividualPart(ESM::PRT_LKnee, -1,1,"meshes\\" + kneePart->model);
}
if(partpriorities[ESM::PRT_RLeg] < 1){
const ESM::BodyPart *legPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "upper leg");
if(legPart)
addOrReplaceIndividualPart(ESM::PRT_RLeg, -1,1,"meshes\\" + legPart->model);
}
if(partpriorities[ESM::PRT_LLeg] < 1){
const ESM::BodyPart *legPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "upper leg");
if(legPart)
addOrReplaceIndividualPart(ESM::PRT_LLeg, -1,1,"meshes\\" + legPart->model);
}
if(partpriorities[ESM::PRT_Tail] < 1){
const ESM::BodyPart *tailPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "tail");
if(tailPart)
addOrReplaceIndividualPart(ESM::PRT_Tail, -1,1,"meshes\\" + tailPart->model);
}
/*if(claviclel)
insertBoundedPart("meshes\\" + claviclel->model + "*|", "Left Clavicle", base);
if(clavicler)
insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/
if(neck)
{
insertBoundedPart("meshes\\" + neck->model, "Neck");
}
if(head)
insertBoundedPart("meshes\\" + head->model, "Head");
if(hair)
insertBoundedPart("meshes\\" + hair->model, "Head");
if (chest){
insertFreePart("meshes\\" + chest->model, ">\"", insert);
}
if (handr){
insertFreePart("meshes\\" + handr->model , ">?", insert);
}
if (handl){
insertFreePart("meshes\\" + handl->model, ">>", insert);
}
if(tail){
insertFreePart("meshes\\" + tail->model, ">*", insert);
}
if(feet){
std::string num = getUniqueID(feet->model);
insertFreePart("meshes\\" + feet->model,"><", insert);
insertFreePart("meshes\\" + feet->model,">:", insert);
}
//originalpos = insert->_getWorldAABB().getCenter();
//originalscenenode = insert->getPosition();
}
Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){
NIFLoader::load(mesh);
Entity* ent = mRend.getScene()->createEntity(mesh);
Ogre::Entity* part = mRend.getScene()->createEntity(mesh);
part->setVisibilityFlags(RV_Actors);
base->attachObjectToBone(bonename, part);
return part;
}
void NpcAnimation::insertFootPart(int type, const std::string &mesh){
std::string meshAndSuffix = mesh;
if(type == ESM::PRT_LFoot)
meshAndSuffix += "*|";
NIFLoader::load(meshAndSuffix);
Ogre::Entity* part = mRend.getScene()->createEntity(meshAndSuffix);
std::vector<Nif::NiTriShapeCopy>* shape = ((NIFLoader::getSingletonPtr())->getShapes(meshAndSuffix));
if(shape == 0){
if(type == ESM::PRT_LFoot){
base->attachObjectToBone("Left Foot", part);
lfoot = part;
}
else if (type == ESM::PRT_RFoot){
base->attachObjectToBone("Right Foot", part);
rfoot = part;
}
}
else{
if(type == ESM::PRT_LFoot)
lFreeFoot = insertFreePart(mesh, "::");
else if (type == ESM::PRT_RFoot)
rFreeFoot = insertFreePart(mesh, ":<");
}
base->attachObjectToBone(bonename, ent);
return ent;
}
void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix, Ogre::SceneNode* insert){
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix){
std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix;
NIFLoader::load(meshNumbered);
Ogre::Entity* ent = mRend.getScene()->createEntity(meshNumbered);
Ogre::Entity* part = mRend.getScene()->createEntity(meshNumbered);
part->setVisibilityFlags(RV_Actors);
insert->attachObject(part);
insert->attachObject(ent);
entityparts.push_back(ent);
shapes = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix));
if(shapes){
shapeparts.push_back(shapes);
handleShapes(shapes, ent, base->getSkeleton());
std::vector<Nif::NiTriShapeCopy>* shape = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix));
if(shape){
handleShapes(shape, part, base->getSkeleton());
}
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> pair = std::make_pair(part, shape);
return pair;
}
}
void NpcAnimation::runAnimation(float timepassed){
if(timeToChange > .2){
timeToChange = 0;
updateParts();
}
timeToChange += timepassed;
//1. Add the amount of time passed to time
//2. Handle the animation transforms dependent on time
@ -262,23 +577,285 @@ void NpcAnimation::runAnimation(float timepassed){
time = startTime + (time - stopTime);
}
handleAnimationTransforms();
handleAnimationTransforms();
std::vector<std::vector<Nif::NiTriShapeCopy>*>::iterator shapepartsiter = shapeparts.begin();
std::vector<Ogre::Entity*>::iterator entitypartsiter = entityparts.begin();
while(shapepartsiter != shapeparts.end())
{
vecRotPos.clear();
std::vector<Nif::NiTriShapeCopy>* shapes = *shapepartsiter;
Ogre::Entity* theentity = *entitypartsiter;
handleShapes(shapes, theentity, base->getSkeleton());
shapepartsiter++;
entitypartsiter++;
if(lFreeFoot.first)
handleShapes(lFreeFoot.second, lFreeFoot.first, base->getSkeleton());
if(rFreeFoot.first)
handleShapes(rFreeFoot.second, rFreeFoot.first, base->getSkeleton());
if(chest.first)
handleShapes(chest.second, chest.first, base->getSkeleton());
if(tail.first)
handleShapes(tail.second, tail.first, base->getSkeleton());
if(skirt.first){
handleShapes(skirt.second, skirt.first, base->getSkeleton());
}
if(lhand.first)
handleShapes(lhand.second, lhand.first, base->getSkeleton());
if(rhand.first)
handleShapes(rhand.second, rhand.first, base->getSkeleton());
}
}
void NpcAnimation::removeIndividualPart(int type){
partpriorities[type] = 0;
partslots[type] = -1;
if(type == ESM::PRT_Head && head){ //0
base->detachObjectFromBone(head);
head = 0;
}
else if(type == ESM::PRT_Hair && hair){//1
base->detachObjectFromBone(hair);
hair = 0;
}
else if(type == ESM::PRT_Neck && neck){//2
base->detachObjectFromBone(neck);
neck = 0;
}
else if(type == ESM::PRT_Cuirass && chest.first){//3
insert->detachObject(chest.first);
chest = zero;
}
else if(type == ESM::PRT_Groin && groin){//4
base->detachObjectFromBone(groin);
groin = 0;
}
else if(type == ESM::PRT_Skirt && skirt.first){//5
insert->detachObject(skirt.first);
skirt = zero;
}
else if(type == ESM::PRT_RHand && rhand.first){//6
insert->detachObject(rhand.first);
rhand = zero;
}
else if(type == ESM::PRT_LHand && lhand.first){//7
insert->detachObject(lhand.first);
lhand = zero;
}
else if(type == ESM::PRT_RWrist && rWrist){//8
base->detachObjectFromBone(rWrist);
rWrist = 0;
}
else if(type == ESM::PRT_LWrist && lWrist){//9
base->detachObjectFromBone(lWrist);
lWrist = 0;
}
else if(type == ESM::PRT_Shield){//10
}
else if(type == ESM::PRT_RForearm && rForearm){//11
base->detachObjectFromBone(rForearm);
rForearm = 0;
}
else if(type == ESM::PRT_LForearm && lForearm){//12
base->detachObjectFromBone(lForearm);
lForearm = 0;
}
else if(type == ESM::PRT_RUpperarm && rupperArm){//13
base->detachObjectFromBone(rupperArm);
rupperArm = 0;
}
else if(type == ESM::PRT_LUpperarm && lupperArm){//14
base->detachObjectFromBone(lupperArm);
lupperArm = 0;
}
else if(type == ESM::PRT_RFoot){ //15
if(rfoot){
base->detachObjectFromBone(rfoot);
rfoot = 0;
}
else if(rFreeFoot.first){
insert->detachObject(rFreeFoot.first);
rFreeFoot = zero;
}
}
else if(type == ESM::PRT_LFoot){ //16
if(lfoot){
base->detachObjectFromBone(lfoot);
lfoot = 0;
}
else if(lFreeFoot.first){
insert->detachObject(lFreeFoot.first);
lFreeFoot = zero;
}
}
else if(type == ESM::PRT_RAnkle && rAnkle){ //17
base->detachObjectFromBone(rAnkle);
rAnkle = 0;
}
else if(type == ESM::PRT_LAnkle && lAnkle){ //18
base->detachObjectFromBone(lAnkle);
lAnkle = 0;
}
else if(type == ESM::PRT_RKnee && rKnee){ //19
base->detachObjectFromBone(rKnee);
rKnee = 0;
}
else if(type == ESM::PRT_LKnee && lKnee){ //20
base->detachObjectFromBone(lKnee);
lKnee = 0;
}
else if(type == ESM::PRT_RLeg && rUpperLeg){ //21
base->detachObjectFromBone(rUpperLeg);
rUpperLeg = 0;
}
else if(type == ESM::PRT_LLeg && lUpperLeg){ //22
base->detachObjectFromBone(lUpperLeg);
lUpperLeg = 0;
}
else if(type == ESM::PRT_RPauldron && rclavicle){ //23
base->detachObjectFromBone(rclavicle);
rclavicle = 0;
}
else if(type == ESM::PRT_LPauldron && lclavicle){ //24
base->detachObjectFromBone(lclavicle);
lclavicle = 0;
}
else if(type == ESM::PRT_Weapon){ //25
}
else if(type == ESM::PRT_Tail && tail.first){ //26
insert->detachObject(tail.first);
tail = zero;
}
}
}
void NpcAnimation::reserveIndividualPart(int type, int group, int priority){
if(priority > partpriorities[type]){
removeIndividualPart(type);
partpriorities[type] = priority;
partslots[type] = group;
}
}
void NpcAnimation::removePartGroup(int group){
for(int i = 0; i < 27; i++){
if(partslots[i] == group){
removeIndividualPart(i);
}
}
}
bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh){
if(priority > partpriorities[type]){
removeIndividualPart(type);
partslots[type] = group;
partpriorities[type] = priority;
switch(type){
case ESM::PRT_Head: //0
head = insertBoundedPart(mesh, "Head");
break;
case ESM::PRT_Hair: //1
hair = insertBoundedPart(mesh, "Head");
break;
case ESM::PRT_Neck: //2
neck = insertBoundedPart(mesh, "Neck");
break;
case ESM::PRT_Cuirass: //3
chest = insertFreePart(mesh, ":\"");
break;
case ESM::PRT_Groin: //4
groin = insertBoundedPart(mesh, "Groin");
break;
case ESM::PRT_Skirt: //5
skirt = insertFreePart(mesh, ":|");
break;
case ESM::PRT_RHand: //6
rhand = insertFreePart(mesh, ":?");
break;
case ESM::PRT_LHand: //7
lhand = insertFreePart(mesh, ":>");
break;
case ESM::PRT_RWrist: //8
rWrist = insertBoundedPart(mesh, "Right Wrist");
break;
case ESM::PRT_LWrist: //9
lWrist = insertBoundedPart(mesh + "*|", "Left Wrist");
break;
case ESM::PRT_Shield: //10
break;
case ESM::PRT_RForearm: //11
rForearm = insertBoundedPart(mesh, "Right Forearm");
break;
case ESM::PRT_LForearm: //12
lForearm = insertBoundedPart(mesh + "*|", "Left Forearm");
break;
case ESM::PRT_RUpperarm: //13
rupperArm = insertBoundedPart(mesh, "Right Upper Arm");
break;
case ESM::PRT_LUpperarm: //14
lupperArm = insertBoundedPart(mesh + "*|", "Left Upper Arm");
break;
case ESM::PRT_RFoot: //15
insertFootPart(type, mesh);
break;
case ESM::PRT_LFoot: //16
insertFootPart(type, mesh);
break;
case ESM::PRT_RAnkle: //17
rAnkle = insertBoundedPart(mesh , "Right Ankle");
break;
case ESM::PRT_LAnkle: //18
lAnkle = insertBoundedPart(mesh + "*|", "Left Ankle");
break;
case ESM::PRT_RKnee: //19
rKnee = insertBoundedPart(mesh , "Right Knee");
break;
case ESM::PRT_LKnee: //20
lKnee = insertBoundedPart(mesh + "*|", "Left Knee");
break;
case ESM::PRT_RLeg: //21
rUpperLeg = insertBoundedPart(mesh, "Right Upper Leg");
break;
case ESM::PRT_LLeg: //22
lUpperLeg = insertBoundedPart(mesh + "*|", "Left Upper Leg");
break;
case ESM::PRT_RPauldron: //23
rclavicle = insertBoundedPart(mesh , "Right Clavicle");
break;
case ESM::PRT_LPauldron: //24
lclavicle = insertBoundedPart(mesh + "*|", "Left Clavicle");
break;
case ESM::PRT_Weapon: //25
break;
case ESM::PRT_Tail: //26
tail = insertFreePart(mesh, ":*");
break;
}
return true;
}
return false;
}
void NpcAnimation::addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts){
for(std::size_t i = 0; i < parts.size(); i++)
{
ESM::PartReference part = parts[i];
const ESM::BodyPart *bodypart = 0;
if(isFemale)
bodypart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (part.female);
if(!bodypart)
bodypart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (part.male);
if(bodypart){
addOrReplaceIndividualPart(part.part, group,priority,"meshes\\" + bodypart->model);
}
else
reserveIndividualPart(part.part, group, priority);
}
}
}

@ -6,25 +6,96 @@
#include <components/nif/property.hpp>
#include <components/nif/controller.hpp>
#include <components/nif/extra.hpp>
#include <utility>
#include "../mwworld/refdata.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/environment.hpp"
#include "components/nifogre/ogre_nif_loader.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwclass/npc.hpp"
#include "../mwworld/containerstore.hpp"
#include "components/esm/loadarmo.hpp"
namespace MWRender{
class NpcAnimation: public Animation{
private:
MWWorld::InventoryStore& inv;
int mStateID;
//Free Parts
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> chest;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> skirt;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> lhand;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> rhand;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> tail;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> lFreeFoot;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> rFreeFoot;
int partslots[27]; //Each part slot is taken by clothing, armor, or is empty
int partpriorities[27];
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> zero;
//Bounded Parts
Ogre::Entity* lclavicle;
Ogre::Entity* rclavicle;
Ogre::Entity* rupperArm;
Ogre::Entity* lupperArm;
Ogre::Entity* rUpperLeg;
Ogre::Entity* lUpperLeg;
Ogre::Entity* lForearm;
Ogre::Entity* rForearm;
Ogre::Entity* lWrist;
Ogre::Entity* rWrist;
Ogre::Entity* rKnee;
Ogre::Entity* lKnee;
Ogre::Entity* neck;
Ogre::Entity* rAnkle;
Ogre::Entity* lAnkle;
Ogre::Entity* groin;
Ogre::Entity* lfoot;
Ogre::Entity* rfoot;
Ogre::Entity* hair;
Ogre::Entity* head;
Ogre::SceneNode* insert;
bool isBeast;
bool isFemale;
std::string headModel;
std::string hairModel;
std::string npcName;
std::string bodyRaceID;
float timeToChange;
MWWorld::ContainerStoreIterator robe;
MWWorld::ContainerStoreIterator helmet;
MWWorld::ContainerStoreIterator shirt;
MWWorld::ContainerStoreIterator cuirass;
MWWorld::ContainerStoreIterator greaves;
MWWorld::ContainerStoreIterator leftpauldron;
MWWorld::ContainerStoreIterator rightpauldron;
MWWorld::ContainerStoreIterator boots;
MWWorld::ContainerStoreIterator pants;
MWWorld::ContainerStoreIterator leftglove;
MWWorld::ContainerStoreIterator rightglove;
MWWorld::ContainerStoreIterator skirtiter;
public:
NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend);
NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv);
virtual ~NpcAnimation();
Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename);
void insertFreePart(const std::string &mesh, const std::string suffix, Ogre::SceneNode* insert);
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> insertFreePart(const std::string &mesh, const std::string suffix);
void insertFootPart(int type, const std::string &mesh);
virtual void runAnimation(float timepassed);
void updateParts();
void removeIndividualPart(int type);
void reserveIndividualPart(int type, int group, int priority);
bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh);
void removePartGroup(int group);
void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts);
};
}
#endif
#endif

@ -4,23 +4,19 @@
#include <components/nifogre/ogre_nif_loader.hpp>
#include <components/settings/settings.hpp>
#include "renderconst.hpp"
using namespace MWRender;
bool Objects::lightConst = false;
float Objects::lightConstValue = 0.0f;
bool Objects::lightLinear = true;
int Objects::lightLinearMethod = 1;
// These are the Morrowind.ini defaults
float Objects::lightLinearValue = 3;
float Objects::lightLinearRadiusMult = 1;
bool Objects::lightQuadratic = false;
int Objects::lightQuadraticMethod = 2;
float Objects::lightQuadraticValue = 16;
float Objects::lightQuadraticRadiusMult = 1;
bool Objects::lightOutQuadInLin = false;
bool Objects::lightOutQuadInLin = true;
bool Objects::lightQuadratic = false;
int Objects::uniqueID = 0;
@ -112,11 +108,32 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
bounds.scale(insert->getScale());
mBounds[ptr.getCell()].merge(bounds);
if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects"))
bool transparent = false;
for (unsigned int i=0; i<ent->getNumSubEntities(); ++i)
{
Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
}
}
}
if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent)
{
insert->attachObject(ent);
ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); /// \todo config value
ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
else
{
@ -130,7 +147,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
mStaticGeometrySmall[ptr.getCell()] = sg;
sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); /// \todo config value
sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance"));
}
else
sg = mStaticGeometrySmall[ptr.getCell()];
@ -158,6 +175,12 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics);
sg->setCastShadows(true);
sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
mRenderer.getScene()->destroyEntity(ent);
}
}
@ -168,35 +191,61 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f
assert(insert);
Ogre::Light *light = mRenderer.getScene()->createLight();
light->setDiffuseColour (r, g, b);
mLights.push_back(light->getName());
float cval=0.0f, lval=0.0f, qval=0.0f;
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>();
LightInfo info;
info.name = light->getName();
info.radius = radius;
info.colour = Ogre::ColourValue(r, g, b);
if(lightConst)
cval = lightConstValue;
if (ref->base->data.flags & ESM::Light::Negative)
info.colour *= -1;
info.interior = (ptr.getCell()->cell->data.flags & ESM::Cell::Interior);
if (ref->base->data.flags & ESM::Light::Flicker)
info.type = LT_Flicker;
else if (ref->base->data.flags & ESM::Light::FlickerSlow)
info.type = LT_FlickerSlow;
else if (ref->base->data.flags & ESM::Light::Pulse)
info.type = LT_Pulse;
else if (ref->base->data.flags & ESM::Light::PulseSlow)
info.type = LT_PulseSlow;
else
info.type = LT_Normal;
// random starting phase for the animation
info.time = Ogre::Math::RangeRandom(0, 2 * M_PI);
// adjust the lights depending if we're in an interior or exterior cell
// quadratic means the light intensity falls off quite fast, resulting in a
// dark, atmospheric environment (perfect for exteriors)
// for interiors, we want more "warm" lights, so use linear attenuation.
bool quadratic = false;
if (!lightOutQuadInLin)
quadratic = lightQuadratic;
else
{
quadratic = !info.interior;
}
if(!lightOutQuadInLin)
if (!quadratic)
{
if(lightLinear)
radius *= lightLinearRadiusMult;
if(lightQuadratic)
radius *= lightQuadraticRadiusMult;
if(lightLinear)
lval = lightLinearValue / pow(radius, lightLinearMethod);
if(lightQuadratic)
qval = lightQuadraticValue / pow(radius, lightQuadraticMethod);
float r = radius * lightLinearRadiusMult;
float attenuation = lightLinearValue / r;
light->setAttenuation(r*10, 0, attenuation, 0);
}
else
{
// FIXME:
// Do quadratic or linear, depending if we're in an exterior or interior
// cell, respectively. Ignore lightLinear and lightQuadratic.
float r = radius * lightQuadraticRadiusMult;
float attenuation = lightQuadraticValue / pow(r, 2);
light->setAttenuation(r*10, 0, 0, attenuation);
}
light->setAttenuation(10*radius, cval, lval, qval);
insert->attachObject(light);
mLights.push_back(info);
}
bool Objects::deleteObject (const MWWorld::Ptr& ptr)
@ -277,12 +326,12 @@ Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell)
void Objects::enableLights()
{
std::vector<std::string>::iterator it = mLights.begin();
std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end())
{
if (mMwRoot->getCreator()->hasLight(*it))
if (mMwRoot->getCreator()->hasLight(it->name))
{
mMwRoot->getCreator()->getLight(*it)->setVisible(true);
mMwRoot->getCreator()->getLight(it->name)->setVisible(true);
++it;
}
else
@ -292,12 +341,12 @@ void Objects::enableLights()
void Objects::disableLights()
{
std::vector<std::string>::iterator it = mLights.begin();
std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end())
{
if (mMwRoot->getCreator()->hasLight(*it))
if (mMwRoot->getCreator()->hasLight(it->name))
{
mMwRoot->getCreator()->getLight(*it)->setVisible(false);
mMwRoot->getCreator()->getLight(it->name)->setVisible(false);
++it;
}
else
@ -305,3 +354,90 @@ void Objects::disableLights()
}
}
void Objects::update(const float dt)
{
std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end())
{
if (mMwRoot->getCreator()->hasLight(it->name))
{
Ogre::Light* light = mMwRoot->getCreator()->getLight(it->name);
// Light animation (pulse & flicker)
it->time += dt;
const float phase = std::fmod(static_cast<double> (it->time), (32 * 2 * M_PI)) * 20;
float pulseConstant;
// These formulas are just guesswork, but they work pretty well
if (it->type == LT_Normal)
{
// Less than 1/255 light modifier for a constant light:
pulseConstant = (const float)(1.0 + sin(phase) / 255.0 );
}
else if (it->type == LT_Flicker)
{
// Let's do a 50% -> 100% sine wave pulse over 1 second:
// This is 75% +/- 25%
pulseConstant = (const float)(0.75 + sin(phase) * 0.25);
// Then add a 25% flicker variation:
it->resetTime -= dt;
if (it->resetTime < 0)
{
it->flickerVariation = (rand() % 1000) / 1000 * 0.25;
it->resetTime = 0.5;
}
if (it->resetTime > 0.25)
{
pulseConstant = (pulseConstant+it->flickerVariation) * (1-it->resetTime * 2.0f) + pulseConstant * it->resetTime * 2.0f;
}
else
{
pulseConstant = (pulseConstant+it->flickerVariation) * (it->resetTime * 2.0f) + pulseConstant * (1-it->resetTime * 2.0f);
}
}
else if (it->type == LT_FlickerSlow)
{
// Let's do a 50% -> 100% sine wave pulse over 1 second:
// This is 75% +/- 25%
pulseConstant = (const float)(0.75 + sin(phase / 4.0) * 0.25);
// Then add a 25% flicker variation:
it->resetTime -= dt;
if (it->resetTime < 0)
{
it->flickerVariation = (rand() % 1000) / 1000 * 0.25;
it->resetTime = 0.5;
}
if (it->resetTime > 0.5)
{
pulseConstant = (pulseConstant+it->flickerVariation) * (1-it->resetTime) + pulseConstant * it->resetTime;
}
else
{
pulseConstant = (pulseConstant+it->flickerVariation) * (it->resetTime) + pulseConstant * (1-it->resetTime);
}
}
else if (it->type == LT_Pulse)
{
// Let's do a 75% -> 125% sine wave pulse over 1 second:
// This is 100% +/- 25%
pulseConstant = (const float)(1.0 + sin(phase) * 0.25);
}
else if (it->type == LT_PulseSlow)
{
// Let's do a 75% -> 125% sine wave pulse over 1 second:
// This is 100% +/- 25%
pulseConstant = (const float)(1.0 + sin(phase / 4.0) * 0.25);
}
else
assert(0 && "Invalid light type");
light->setDiffuseColour( it->colour * pulseConstant );
++it;
}
else
it = mLights.erase(it);
}
}

@ -10,26 +10,55 @@
namespace MWRender{
/// information about light needed for rendering
enum LightType
{
// These are all mutually exclusive
LT_Normal=0,
LT_Flicker=1,
LT_FlickerSlow=2,
LT_Pulse=3,
LT_PulseSlow=4
};
struct LightInfo
{
// Constants
std::string name; // ogre handle
Ogre::ColourValue colour;
float radius;
bool interior; // Does this light belong to an interior or exterior cell
LightType type;
// Runtime variables
float flickerVariation; // 25% flicker variation, reset once every 0.5 seconds
float flickerSlowVariation; // 25% flicker variation, reset once every 1.0 seconds
float resetTime;
long double time;
LightInfo() :
flickerVariation(0), resetTime(0.5),
flickerSlowVariation(0), time(0), interior(true)
{
}
};
class Objects{
OEngine::Render::OgreRenderer &mRenderer;
std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes;
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry;
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall;
std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds;
std::vector<std::string> mLights;
std::vector<LightInfo> mLights;
Ogre::SceneNode* mMwRoot;
bool mIsStatic;
static int uniqueID;
static bool lightConst;
static float lightConstValue;
static bool lightLinear;
static int lightLinearMethod;
static float lightLinearValue;
static float lightLinearRadiusMult;
static bool lightQuadratic;
static int lightQuadraticMethod;
static float lightQuadraticValue;
static float lightQuadraticRadiusMult;
@ -39,7 +68,7 @@ class Objects{
///< Remove all movable objects from \a node.
public:
Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer){}
Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer) {}
~Objects(){}
void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);
@ -48,6 +77,9 @@ public:
void enableLights();
void disableLights();
void update (const float dt);
///< per-frame update
Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*);
///< get a bounding box that encloses all objects in the specified cell

@ -1,4 +1,5 @@
#include "occlusionquery.hpp"
#include "renderconst.hpp"
#include <OgreRenderSystem.h>
#include <OgreRoot.h>
@ -40,9 +41,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
return;
}
// This means that everything up to RENDER_QUEUE_MAIN can occlude the objects that are tested
const int queue = RENDER_QUEUE_MAIN+1;
MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");
MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels");
matQueryArea->setDepthWriteEnabled(false);
@ -62,25 +60,31 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
mBBQueryTotal = mRendering->getScene()->createBillboardSet(1);
mBBQueryTotal->setCastShadows(false);
mBBQueryTotal->setDefaultDimensions(150, 150);
mBBQueryTotal->createBillboard(Vector3::ZERO);
mBBQueryTotal->setMaterialName("QueryTotalPixels");
mBBQueryTotal->setRenderQueueGroup(queue+1);
mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery);
mBBNodeReal->attachObject(mBBQueryTotal);
mBBQueryVisible = mRendering->getScene()->createBillboardSet(1);
mBBQueryVisible->setCastShadows(false);
mBBQueryVisible->setDefaultDimensions(150, 150);
mBBQueryVisible->createBillboard(Vector3::ZERO);
mBBQueryVisible->setMaterialName("QueryVisiblePixels");
mBBQueryVisible->setRenderQueueGroup(queue+1);
mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery);
mBBNodeReal->attachObject(mBBQueryVisible);
mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1);
/// \todo ideally this should occupy exactly 1 pixel on the screen
mBBQuerySingleObject->setCastShadows(false);
mBBQuerySingleObject->setDefaultDimensions(0.003, 0.003);
mBBQuerySingleObject->createBillboard(Vector3::ZERO);
mBBQuerySingleObject->setMaterialName("QueryVisiblePixels");
mBBQuerySingleObject->setRenderQueueGroup(queue);
mBBQuerySingleObject->setRenderQueueGroup(RQG_OcclusionQuery);
mBBQuerySingleObject->setVisibilityFlags(RV_OcclusionQuery);
mObjectNode->attachObject(mBBQuerySingleObject);
mRendering->getScene()->addRenderObjectListener(this);
@ -153,7 +157,7 @@ void OcclusionQuery::renderQueueEnded(uint8 queueGroupId, const String& invocati
* this can happen for example if the object that is tested is outside of the view frustum
* to prevent this, check if the queries have been performed after everything has been rendered and if not, start them manually
*/
if (queueGroupId == RENDER_QUEUE_SKIES_LATE)
if (queueGroupId == RQG_SkiesLate)
{
if (mWasVisible == false && mDoQuery)
{

@ -0,0 +1,64 @@
#ifndef GAME_RENDER_CONST_H
#define GAME_RENDER_CONST_H
#include <OgreRenderQueue.h>
namespace MWRender
{
// Render queue groups
enum RenderQueueGroups
{
// Sky early (atmosphere, clouds, moons)
RQG_SkiesEarly = Ogre::RENDER_QUEUE_SKIES_EARLY,
RQG_Main = Ogre::RENDER_QUEUE_MAIN,
RQG_Water = Ogre::RENDER_QUEUE_7+1,
RQG_Alpha = Ogre::RENDER_QUEUE_MAIN,
RQG_UnderWater = Ogre::RENDER_QUEUE_7+1,
RQG_OcclusionQuery = Ogre::RENDER_QUEUE_8,
// Sky late (sun & sun flare)
RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE
};
// Visibility flags
enum VisibilityFlags
{
// Terrain
RV_Terrain = 1,
// Statics (e.g. trees, houses)
RV_Statics = 2,
// Small statics
RV_StaticsSmall = 4,
// Water
RV_Water = 8,
// Actors (player, npcs, creatures)
RV_Actors = 16,
// Misc objects (containers, dynamic objects)
RV_Misc = 32,
RV_Sky = 64,
// Sun glare (not visible in reflection)
RV_Glare = 128,
RV_OcclusionQuery = 256,
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water,
/// \todo markers (normally hidden)
};
}
#endif

@ -14,18 +14,22 @@
#include <components/esm/loadstat.hpp>
#include <components/settings/settings.hpp>
#include "shadows.hpp"
#include "shaderhelper.hpp"
#include "localmap.hpp"
#include "water.hpp"
using namespace MWRender;
using namespace Ogre;
namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment)
:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0)
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine)
:mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0)
{
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
mTerrainManager = new TerrainManager(mRendering.getScene(),
environment);
mWater = 0;
//The fog type must be set before any terrain objects are created as if the
//fog type is set to FOG_NONE then the initially created terrain won't have any fog
@ -39,14 +43,41 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
std::string filter = Settings::Manager::getString("texture filtering", "General");
if (filter == "anisotropic") tfo = TFO_ANISOTROPIC;
else if (filter == "trilinear") tfo = TFO_TRILINEAR;
else /* if (filter == "bilinear") */ tfo = TFO_BILINEAR;
else if (filter == "bilinear") tfo = TFO_BILINEAR;
else if (filter == "none") tfo = TFO_NONE;
MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
MaterialManager::getSingleton().setDefaultAnisotropy(Settings::Manager::getInt("anisotropy", "General"));
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
// Load resources
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
// Due to the huge world size of MW, we'll want camera-relative rendering.
// This prevents precision artifacts when moving very far from the origin.
mRendering.getScene()->setCameraRelativeRendering(true);
// disable unsupported effects
const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects"))
Settings::Manager::setBool("shader", "Water", false);
if ( !(caps->isShaderProfileSupported("fp40") || caps->isShaderProfileSupported("ps_4_0"))
|| !Settings::Manager::getBool("shaders", "Objects"))
Settings::Manager::setBool("enabled", "Shadows", false);
// note that the order is important here
if (useMRT())
{
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbuffer");
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true);
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "Underwater");
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbufferFinalizer");
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true);
}
else
{
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "UnderwaterNoMRT");
}
// 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
@ -64,23 +95,25 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode();
cameraPitchNode->attachObject(mRendering.getCamera());
mShadows = new Shadows(&mRendering);
mShaderHelper = new ShaderHelper(this);
mTerrainManager = new TerrainManager(mRendering.getScene(), this);
//mSkyManager = 0;
mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera(), &environment);
mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera());
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
mWater = 0;
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mSun = 0;
mDebugging = new Debugging(mMwRoot, environment, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this, &environment);
mDebugging = new Debugging(mMwRoot, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this);
}
RenderingManager::~RenderingManager ()
{
//TODO: destroy mSun?
delete mPlayer;
delete mSkyManager;
delete mDebugging;
@ -122,8 +155,7 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store)
void RenderingManager::removeWater ()
{
if(mWater){
delete mWater;
mWater = 0;
mWater->setActive(false);
}
}
@ -139,6 +171,7 @@ void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
mDebugging->cellAdded(store);
if (store->cell->isExterior())
mTerrainManager->cellAdded(store);
waterAdded(store);
}
void RenderingManager::addObject (const MWWorld::Ptr& ptr){
@ -179,6 +212,7 @@ void RenderingManager::moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Ve
void RenderingManager::update (float duration){
mActors.update (duration);
mObjects.update (duration);
mOcclusionQuery->update(duration);
@ -191,15 +225,16 @@ void RenderingManager::update (float duration){
mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() );
checkUnderwater();
mWater->update();
}
void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){
if(store->cell->data.flags & store->cell->HasWater){
if(mWater == 0)
mWater = new MWRender::Water(mRendering.getCamera(), store->cell);
mWater = new MWRender::Water(mRendering.getCamera(), mSkyManager, store->cell);
else
mWater->changeCell(store->cell);
//else
mWater->setActive(true);
}
else
removeWater();
@ -263,11 +298,25 @@ bool RenderingManager::toggleRenderMode(int mode)
{
if (mRendering.getCamera()->getPolygonMode() == PM_SOLID)
{
// disable compositors
if (useMRT())
{
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", false);
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", false);
}
mRendering.getCamera()->setPolygonMode(PM_WIREFRAME);
return true;
}
else
{
// re-enable compositors
if (useMRT())
{
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true);
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true);
}
mRendering.getCamera()->setPolygonMode(PM_SOLID);
return false;
}
@ -276,23 +325,29 @@ bool RenderingManager::toggleRenderMode(int mode)
void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
{
Ogre::ColourValue color;
color.setAsABGR (mCell.cell->ambi.fog);
Ogre::ColourValue color;
color.setAsABGR (mCell.cell->ambi.fog);
configureFog(mCell.cell->ambi.fogDensity, color);
configureFog(mCell.cell->ambi.fogDensity, color);
}
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
{
float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
mRendering.getCamera()->setFarClipDistance ( max / density );
mRendering.getViewport()->setBackgroundColour (colour);
mRendering.getCamera()->setFarClipDistance ( max / density );
mRendering.getViewport()->setBackgroundColour (colour);
CompositorInstance* inst = CompositorManager::getSingleton().getCompositorChain(mRendering.getViewport())->getCompositor("gbuffer");
if (inst != 0)
inst->getCompositor()->getTechnique(0)->getTargetPass(0)->getPass(0)->setClearColour(colour);
if (mWater)
mWater->setViewportBackground(colour);
}
@ -319,41 +374,43 @@ void RenderingManager::setAmbientMode()
void RenderingManager::configureAmbient(ESMS::CellStore<MWWorld::RefData> &mCell)
{
mAmbientColor.setAsABGR (mCell.cell->ambi.ambient);
setAmbientMode();
mAmbientColor.setAsABGR (mCell.cell->ambi.ambient);
setAmbientMode();
// Create a "sun" that shines light downwards. It doesn't look
// completely right, but leave it for now.
if(!mSun)
{
mSun = mRendering.getScene()->createLight();
}
Ogre::ColourValue colour;
colour.setAsABGR (mCell.cell->ambi.sunlight);
mSun->setDiffuseColour (colour);
mSun->setType(Ogre::Light::LT_DIRECTIONAL);
mSun->setDirection(0,-1,0);
// Create a "sun" that shines light downwards. It doesn't look
// completely right, but leave it for now.
if(!mSun)
{
mSun = mRendering.getScene()->createLight();
}
Ogre::ColourValue colour;
colour.setAsABGR (mCell.cell->ambi.sunlight);
mSun->setDiffuseColour (colour);
mSun->setType(Ogre::Light::LT_DIRECTIONAL);
mSun->setDirection(0,-1,0);
}
// Switch through lighting modes.
void RenderingManager::toggleLight()
{
if (mAmbientMode==2)
mAmbientMode = 0;
else
++mAmbientMode;
if (mAmbientMode==2)
mAmbientMode = 0;
else
++mAmbientMode;
switch (mAmbientMode)
{
case 0: std::cout << "Setting lights to normal\n"; break;
case 1: std::cout << "Turning the lights up\n"; break;
case 2: std::cout << "Turning the lights to full\n"; break;
}
switch (mAmbientMode)
{
case 0: std::cout << "Setting lights to normal\n"; break;
case 1: std::cout << "Turning the lights up\n"; break;
case 2: std::cout << "Turning the lights to full\n"; break;
}
setAmbientMode();
setAmbientMode();
}
void RenderingManager::checkUnderwater(){
if(mWater){
void RenderingManager::checkUnderwater()
{
if(mWater)
{
mWater->checkUnderwater( mRendering.getCamera()->getRealPosition().y );
}
}
@ -371,7 +428,9 @@ void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr)
void RenderingManager::setSunColour(const Ogre::ColourValue& colour)
{
if (!mSunEnabled) return;
mSun->setDiffuseColour(colour);
mSun->setSpecularColour(colour);
mTerrainManager->setDiffuse(colour);
}
@ -383,12 +442,21 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour)
void RenderingManager::sunEnable()
{
if (mSun) mSun->setVisible(true);
// Don't disable the light, as the shaders assume the first light to be directional.
//if (mSun) mSun->setVisible(true);
mSunEnabled = true;
}
void RenderingManager::sunDisable()
{
if (mSun) mSun->setVisible(false);
// Don't disable the light, as the shaders assume the first light to be directional.
//if (mSun) mSun->setVisible(false);
mSunEnabled = false;
if (mSun)
{
mSun->setDiffuseColour(ColourValue(0,0,0));
mSun->setSpecularColour(ColourValue(0,0,0));
}
}
void RenderingManager::setSunDirection(const Ogre::Vector3& direction)
@ -421,11 +489,33 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell)
void RenderingManager::disableLights()
{
mObjects.disableLights();
sunDisable();
}
void RenderingManager::enableLights()
{
mObjects.enableLights();
sunEnable();
}
const bool RenderingManager::useMRT()
{
return Settings::Manager::getBool("shader", "Water");
}
Shadows* RenderingManager::getShadows()
{
return mShadows;
}
void RenderingManager::switchToInterior()
{
mRendering.getScene()->setCameraRelativeRendering(false);
}
void RenderingManager::switchToExterior()
{
mRendering.getScene()->setCameraRelativeRendering(true);
}
} // namespace

@ -25,17 +25,12 @@
#include "objects.hpp"
#include "actors.hpp"
#include "player.hpp"
#include "water.hpp"
#include "localmap.hpp"
#include "occlusionquery.hpp"
namespace Ogre
{
class Camera;
class Viewport;
class SceneManager;
class SceneNode;
class RaySceneQuery;
class Quaternion;
class Vector3;
}
@ -48,7 +43,10 @@ namespace MWWorld
namespace MWRender
{
class Shadows;
class ShaderHelper;
class LocalMap;
class Water;
class RenderingManager: private RenderingInterface {
@ -59,7 +57,7 @@ class RenderingManager: private RenderingInterface {
virtual MWRender::Actors& getActors();
public:
RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment);
RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine);
virtual ~RenderingManager();
@ -84,6 +82,8 @@ class RenderingManager: private RenderingInterface {
void removeWater();
static const bool useMRT();
void preCellChange (MWWorld::Ptr::CellStore* store);
///< this event is fired immediately before changing cell
@ -115,6 +115,11 @@ class RenderingManager: private RenderingInterface {
bool occlusionQuerySupported() { return mOcclusionQuery->supported(); };
OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; };
Shadows* getShadows();
void switchToInterior();
void switchToExterior();
void setGlare(bool glare);
void skyEnable ();
void skyDisable ();
@ -150,6 +155,8 @@ class RenderingManager: private RenderingInterface {
void setAmbientMode();
bool mSunEnabled;
SkyManager* mSkyManager;
OcclusionQuery* mOcclusionQuery;
@ -181,6 +188,10 @@ class RenderingManager: private RenderingInterface {
MWRender::Debugging *mDebugging;
MWRender::LocalMap* mLocalMap;
MWRender::Shadows* mShadows;
MWRender::ShaderHelper* mShaderHelper;
};
}

@ -0,0 +1,308 @@
#include "shaderhelper.hpp"
#include "renderingmanager.hpp"
#include "shadows.hpp"
#include <OgreHighLevelGpuProgramManager.h>
#include <OgreHighLevelGpuProgram.h>
#include <OgreGpuProgramParams.h>
#include <components/settings/settings.hpp>
using namespace Ogre;
using namespace MWRender;
ShaderHelper::ShaderHelper(RenderingManager* rend)
{
mRendering = rend;
applyShaders();
}
void ShaderHelper::applyShaders()
{
if (!Settings::Manager::getBool("shaders", "Objects")) return;
bool mrt = RenderingManager::useMRT();
bool shadows = Settings::Manager::getBool("enabled", "Shadows");
bool split = Settings::Manager::getBool("split", "Shadows");
// shader for normal rendering
createShader(mrt, shadows, split, "main");
// fallback shader without mrt and without shadows
// (useful for reflection and for minimap)
createShader(false, false, false, "main_fallback");
}
void ShaderHelper::createShader(const bool mrt, const bool shadows, const bool split, const std::string& name)
{
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
const int numsplits = 3;
// the number of lights to support.
// when rendering an object, OGRE automatically picks the lights that are
// closest to the object being rendered. unfortunately this mechanism does
// not work perfectly for objects batched together (they will all use the same
// lights). to work around this, we are simply pushing the maximum number
// of lights here in order to minimize disappearing lights.
int num_lights = Settings::Manager::getInt("num lights", "Objects");
{
// vertex
HighLevelGpuProgramPtr vertex;
if (!mgr.getByName(name+"_vp").isNull())
mgr.remove(name+"_vp");
vertex = mgr.createProgram(name+"_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_VERTEX_PROGRAM);
vertex->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1");
vertex->setParameter("entry_point", "main_vp");
StringUtil::StrStreamType outStream;
outStream <<
"void main_vp( \n"
" float4 position : POSITION, \n"
" float4 normal : NORMAL, \n"
" float4 colour : COLOR, \n"
" in float2 uv : TEXCOORD0, \n"
" out float2 oUV : TEXCOORD0, \n"
" out float4 oPosition : POSITION, \n"
" out float4 oPositionObjSpace : TEXCOORD1, \n"
" out float4 oNormal : TEXCOORD2, \n"
" out float oDepth : TEXCOORD3, \n"
" out float4 oVertexColour : TEXCOORD4, \n";
if (shadows && !split) outStream <<
" out float4 oLightSpacePos0 : TEXCOORD5, \n"
" uniform float4x4 worldMatrix, \n"
" uniform float4x4 texViewProjMatrix0, \n";
else
{
for (int i=0; i<numsplits; ++i)
{
outStream <<
" out float4 oLightSpacePos"<<i<<" : TEXCOORD"<<i+5<<", \n"
" uniform float4x4 texViewProjMatrix"<<i<<", \n";
}
outStream <<
" uniform float4x4 worldMatrix, \n";
}
outStream <<
" uniform float4x4 worldViewProj \n"
") \n"
"{ \n"
" oVertexColour = colour; \n"
" oUV = uv; \n"
" oNormal = normal; \n"
" oPosition = mul( worldViewProj, position ); \n"
" oDepth = oPosition.z; \n"
" oPositionObjSpace = position; \n";
if (shadows && !split) outStream <<
" oLightSpacePos0 = mul(texViewProjMatrix0, mul(worldMatrix, position)); \n";
else
{
outStream <<
" float4 wPos = mul(worldMatrix, position); \n";
for (int i=0; i<numsplits; ++i)
{
outStream <<
" oLightSpacePos"<<i<<" = mul(texViewProjMatrix"<<i<<", wPos); \n";
}
}
outStream <<
"}";
vertex->setSource(outStream.str());
vertex->load();
vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
if (shadows)
{
vertex->getDefaultParameters()->setNamedAutoConstant("worldMatrix", GpuProgramParameters::ACT_WORLD_MATRIX);
if (!split)
vertex->getDefaultParameters()->setNamedAutoConstant("texViewProjMatrix0", GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, 0);
else
{
for (int i=0; i<numsplits; ++i)
{
vertex->getDefaultParameters()->setNamedAutoConstant("texViewProjMatrix"+StringConverter::toString(i), GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i);
}
}
}
}
{
// fragment
HighLevelGpuProgramPtr fragment;
if (!mgr.getByName(name+"_fp").isNull())
mgr.remove(name+"_fp");
fragment = mgr.createProgram(name+"_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_FRAGMENT_PROGRAM);
fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1");
fragment->setParameter("entry_point", "main_fp");
StringUtil::StrStreamType outStream;
if (shadows) outStream <<
"float depthShadow(sampler2D shadowMap, float4 shadowMapPos, float2 offset) \n"
"{ \n"
" shadowMapPos /= shadowMapPos.w; \n"
" float3 o = float3(offset.xy, -offset.x) * 0.3f; \n"
" float c = (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy - o.xy).r) ? 1 : 0; // top left \n"
" c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy + o.xy).r) ? 1 : 0; // bottom right \n"
" c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy + o.zy).r) ? 1 : 0; // bottom left \n"
" c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy - o.zy).r) ? 1 : 0; // top right \n"
" return c / 4; \n"
"} \n";
outStream <<
"void main_fp( \n"
" in float2 uv : TEXCOORD0, \n"
" out float4 oColor : COLOR, \n"
" uniform sampler2D texture : register(s0), \n"
" float4 positionObjSpace : TEXCOORD1, \n"
" float4 normal : TEXCOORD2, \n"
" float iDepth : TEXCOORD3, \n"
" float4 vertexColour : TEXCOORD4, \n"
" uniform float4 fogColour, \n"
" uniform float4 fogParams, \n";
if (shadows) outStream <<
" uniform float4 shadowFar_fadeStart, \n";
if (shadows && !split) outStream <<
" uniform sampler2D shadowMap : register(s1), \n"
" float4 lightSpacePos0 : TEXCOORD5, \n"
" uniform float4 invShadowmapSize0, \n";
else
{
outStream <<
" uniform float4 pssmSplitPoints, \n";
for (int i=0; i<numsplits; ++i)
{
outStream <<
" uniform sampler2D shadowMap"<<i<<" : register(s"<<i+1<<"), \n"
" float4 lightSpacePos"<<i<<" : TEXCOORD"<<i+5<<", \n"
" uniform float4 invShadowmapSize"<<i<<", \n";
}
}
if (mrt) outStream <<
" out float4 oColor1 : COLOR1, \n"
" uniform float far, \n";
for (int i=0; i<num_lights; ++i)
{
outStream <<
" uniform float4 lightDiffuse"<<i<<", \n"
" uniform float4 lightPositionObjSpace"<<i<<", \n"
" uniform float4 lightAttenuation"<<i<<", \n";
}
outStream <<
" uniform float4 lightAmbient, \n"
" uniform float4 ambient, \n"
" uniform float4 diffuse, \n"
" uniform float4 emissive \n"
") \n"
"{ \n"
" float4 tex = tex2D(texture, uv); \n"
" float d; \n"
" float attn; \n"
" float3 lightDir; \n"
" float3 lightColour = float3(0, 0, 0); \n";
for (int i=0; i<num_lights; ++i)
{
outStream <<
" lightDir = lightPositionObjSpace"<<i<<".xyz - (positionObjSpace.xyz * lightPositionObjSpace"<<i<<".w); \n"
// pre-multiply light color with attenuation factor
" d = length( lightDir ); \n"
" attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
" lightDiffuse"<<i<<" *= attn; \n";
if (i == 0 && shadows)
{
outStream <<
" float shadow; \n";
if (!split) outStream <<
" shadow = depthShadow(shadowMap, lightSpacePos0, invShadowmapSize0.xy); \n";
else
{
for (int j=0; j<numsplits; ++j)
{
std::string channel;
if (j==0) channel = "x";
else if (j==1) channel = "y";
else if (j==2) channel = "z";
if (j==0)
outStream << " if (iDepth <= pssmSplitPoints." << channel << ") \n";
else if (j < numsplits - 1)
outStream << " else if (iDepth <= pssmSplitPoints." << channel << ") \n";
else
outStream << " else \n";
outStream <<
" { \n"
" shadow = depthShadow(shadowMap" << j << ", lightSpacePos" << j << ", invShadowmapSize" << j << ".xy); \n"
" } \n";
}
}
outStream <<
" float fadeRange = shadowFar_fadeStart.x - shadowFar_fadeStart.y; \n"
" float fade = 1-((iDepth - shadowFar_fadeStart.y) / fadeRange); \n"
" shadow = (iDepth > shadowFar_fadeStart.x) ? 1 : ((iDepth > shadowFar_fadeStart.y) ? 1-((1-shadow)*fade) : shadow); \n"
" lightColour.xyz += shadow * lit(dot(normalize(lightDir), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
}
else outStream <<
" lightColour.xyz += lit(dot(normalize(lightDir), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
}
outStream <<
" float3 lightingFinal = lightColour.xyz * diffuse.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
" float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n"
" oColor.xyz = lerp(lightingFinal * tex.xyz * vertexColour.xyz, fogColour.xyz, fogValue); \n"
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n";
if (mrt) outStream <<
" oColor1 = float4(iDepth / far, 0, 0, (oColor.a == 1)); \n"; // only write to MRT if alpha is 1
outStream <<
"}";
fragment->setSource(outStream.str());
fragment->load();
for (int i=0; i<num_lights; ++i)
{
fragment->getDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
}
fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
fragment->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
if (shadows)
{
fragment->getDefaultParameters()->setNamedConstant("shadowFar_fadeStart", Vector4(mRendering->getShadows()->getShadowFar(), mRendering->getShadows()->getFadeStart()*mRendering->getShadows()->getShadowFar(), 0, 0));
for (int i=0; i < (split ? numsplits : 1); ++i)
{
fragment->getDefaultParameters()->setNamedAutoConstant("invShadowmapSize" + StringConverter::toString(i), GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i+1);
}
if (split)
{
Vector4 splitPoints;
const PSSMShadowCameraSetup::SplitPointList& splitPointList = mRendering->getShadows()->getPSSMSetup()->getSplitPoints();
// Populate from split point 1, not 0, since split 0 isn't useful (usually 0)
for (int i = 1; i < numsplits; ++i)
{
splitPoints[i-1] = splitPointList[i];
}
fragment->getDefaultParameters()->setNamedConstant("pssmSplitPoints", splitPoints);
}
}
if (mrt)
fragment->getDefaultParameters()->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE);
}
}

@ -0,0 +1,29 @@
#ifndef GAME_SHADERHELPER_H
#define GAME_SHADERHELPER_H
#include <string>
namespace MWRender
{
class RenderingManager;
///
/// \brief manages the main shader
///
class ShaderHelper
{
public:
ShaderHelper(RenderingManager* rend);
void applyShaders();
///< apply new settings
private:
RenderingManager* mRendering;
void createShader(const bool mrt, const bool shadows, const bool split, const std::string& name);
};
}
#endif

@ -0,0 +1,173 @@
#include "shadows.hpp"
#include <components/settings/settings.hpp>
#include <openengine/ogre/renderer.hpp>
#include <OgreSceneManager.h>
#include <OgreColourValue.h>
#include <OgreShadowCameraSetupLiSPSM.h>
#include <OgreShadowCameraSetupPSSM.h>
#include <OgreHardwarePixelBuffer.h>
#include <OgreOverlayContainer.h>
#include <OgreOverlayManager.h>
#include "renderconst.hpp"
using namespace Ogre;
using namespace MWRender;
Shadows::Shadows(OEngine::Render::OgreRenderer* rend) :
mShadowFar(1000), mFadeStart(0.9)
{
mRendering = rend;
mSceneMgr = mRendering->getScene();
recreate();
}
void Shadows::recreate()
{
bool enabled = Settings::Manager::getBool("enabled", "Shadows");
// Split shadow maps are currently disabled because the terrain cannot cope with them
// (Too many texture units) Solution would be a multi-pass terrain material
bool split = Settings::Manager::getBool("split", "Shadows");
//const bool split = false;
if (!enabled)
{
mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
return;
}
int texsize = Settings::Manager::getInt("texture size", "Shadows");
mSceneMgr->setShadowTextureSize(texsize);
mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED);
// no point light shadows, i'm afraid. might revisit this with Deferred Shading
mSceneMgr->setShadowTextureCountPerLightType(Light::LT_POINT, 0);
mSceneMgr->setShadowTextureCountPerLightType(Light::LT_DIRECTIONAL, split ? 3 : 1);
mSceneMgr->setShadowTextureCount(split ? 3 : 1);
mSceneMgr->setShadowTextureSelfShadow(true);
mSceneMgr->setShadowCasterRenderBackFaces(true);
mSceneMgr->setShadowTextureCasterMaterial("depth_shadow_caster");
mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R);
mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000000);
mShadowFar = split ? Settings::Manager::getInt("split shadow distance", "Shadows") : Settings::Manager::getInt("shadow distance", "Shadows");
mSceneMgr->setShadowFarDistance(mShadowFar);
mFadeStart = Settings::Manager::getFloat("fade start", "Shadows");
ShadowCameraSetupPtr shadowCameraSetup;
if (split)
{
mPSSMSetup = new PSSMShadowCameraSetup();
mPSSMSetup->setSplitPadding(5);
mPSSMSetup->calculateSplitPoints(3, mRendering->getCamera()->getNearClipDistance(), mShadowFar);
const Real adjustFactors[3] = {64, 64, 64};
for (int i=0; i < 3; ++i)
{
mPSSMSetup->setOptimalAdjustFactor(i, adjustFactors[i]);
/*if (i==0)
mSceneMgr->setShadowTextureConfig(i, texsize, texsize, Ogre::PF_FLOAT32_R);
else if (i ==1)
mSceneMgr->setShadowTextureConfig(i, texsize/2, texsize/2, Ogre::PF_FLOAT32_R);
else if (i ==2)
mSceneMgr->setShadowTextureConfig(i, texsize/4, texsize/4, Ogre::PF_FLOAT32_R);*/
}
shadowCameraSetup = ShadowCameraSetupPtr(mPSSMSetup);
}
else
{
LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup();
lispsmSetup->setOptimalAdjustFactor(2);
//lispsmSetup->setCameraLightDirectionThreshold(Degree(0));
//lispsmSetup->setUseAggressiveFocusRegion(false);
shadowCameraSetup = ShadowCameraSetupPtr(lispsmSetup);
}
mSceneMgr->setShadowCameraSetup(shadowCameraSetup);
// Set visibility mask for the shadow render textures
int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows")
+ (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows")
+ RV_Misc * Settings::Manager::getBool("misc shadows", "Shadows");
for (int i = 0; i < (split ? 3 : 1); ++i)
{
TexturePtr shadowTexture = mSceneMgr->getShadowTexture(i);
Viewport* vp = shadowTexture->getBuffer()->getRenderTarget()->getViewport(0);
vp->setVisibilityMask(visibilityMask);
}
// --------------------------------------------------------------------------------------------------------------------
// --------------------------- Debug overlays to display the content of shadow maps -----------------------------------
// --------------------------------------------------------------------------------------------------------------------
/*
OverlayManager& mgr = OverlayManager::getSingleton();
Overlay* overlay;
// destroy if already exists
if (overlay = mgr.getByName("DebugOverlay"))
mgr.destroy(overlay);
overlay = mgr.create("DebugOverlay");
for (size_t i = 0; i < (split ? 3 : 1); ++i) {
TexturePtr tex = mRendering->getScene()->getShadowTexture(i);
// Set up a debug panel to display the shadow
if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + StringConverter::toString(i)))
MaterialManager::getSingleton().remove("Ogre/DebugTexture" + StringConverter::toString(i));
MaterialPtr debugMat = MaterialManager::getSingleton().create(
"Ogre/DebugTexture" + StringConverter::toString(i),
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
OverlayContainer* debugPanel;
// destroy container if exists
try
{
if (debugPanel =
static_cast<OverlayContainer*>(
mgr.getOverlayElement("Ogre/DebugTexPanel" + StringConverter::toString(i)
)))
mgr.destroyOverlayElement(debugPanel);
}
catch (Ogre::Exception&) {}
debugPanel = (OverlayContainer*)
(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
debugPanel->_setPosition(0.8, i*0.25);
debugPanel->_setDimensions(0.2, 0.24);
debugPanel->setMaterialName(debugMat->getName());
debugPanel->show();
overlay->add2D(debugPanel);
overlay->show();
}
*/
}
PSSMShadowCameraSetup* Shadows::getPSSMSetup()
{
return mPSSMSetup;
}
float Shadows::getShadowFar() const
{
return mShadowFar;
}
float Shadows::getFadeStart() const
{
return mFadeStart;
}

@ -0,0 +1,39 @@
#ifndef GAME_SHADOWS_H
#define GAME_SHADOWS_H
// forward declares
namespace Ogre
{
class SceneManager;
class PSSMShadowCameraSetup;
}
namespace OEngine{
namespace Render{
class OgreRenderer;
}
}
namespace MWRender
{
class Shadows
{
public:
Shadows(OEngine::Render::OgreRenderer* rend);
void recreate();
Ogre::PSSMShadowCameraSetup* getPSSMSetup();
float getShadowFar() const;
float getFadeStart() const;
protected:
OEngine::Render::OgreRenderer* mRendering;
Ogre::SceneManager* mSceneMgr;
Ogre::PSSMShadowCameraSetup* mPSSMSetup;
float mShadowFar;
float mFadeStart;
};
}
#endif

@ -10,9 +10,10 @@
#include <components/nifogre/ogre_nif_loader.hpp>
#include "../mwworld/environment.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
#include "occlusionquery.hpp"
#include "renderconst.hpp"
#include "renderingmanager.hpp"
using namespace MWRender;
using namespace Ogre;
@ -60,6 +61,11 @@ Vector3 BillboardObject::getPosition() const
return Vector3(p.x, -p.z, p.y);
}
void BillboardObject::setVisibilityFlags(int flags)
{
mBBSet->setVisibilityFlags(flags);
}
void BillboardObject::setColour(const ColourValue& pColour)
{
mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(pColour);
@ -89,13 +95,14 @@ void BillboardObject::init(const String& textureName,
/// \todo These billboards are not 100% correct, might want to revisit them later
mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1);
mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
mBBSet->setRenderQueueGroup(RENDER_QUEUE_MAIN+2);
mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON);
mBBSet->setCommonDirection( -position.normalisedCopy() );
mBBSet->setVisibilityFlags(RV_Sky);
mNode = rootNode->createChildSceneNode();
mNode->setPosition(finalPosition);
mNode->attachObject(mBBSet);
mBBSet->createBillboard(0,0,0);
mBBSet->setCastShadows(false);
mMaterial = MaterialManager::getSingleton().create("BillboardMaterial"+StringConverter::toString(bodyCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
mMaterial->removeAllTechniques();
@ -109,6 +116,65 @@ void BillboardObject::init(const String& textureName,
p->createTextureUnitState(textureName);
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
HighLevelGpuProgramPtr vshader;
if (mgr.resourceExists("BBO_VP"))
vshader = mgr.getByName("BBO_VP");
else
vshader = mgr.createProgram("BBO_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM);
vshader->setParameter("profiles", "vs_2_x arbvp1");
vshader->setParameter("entry_point", "main_vp");
StringUtil::StrStreamType outStream;
outStream <<
"void main_vp( \n"
" float4 position : POSITION, \n"
" in float2 uv : TEXCOORD0, \n"
" out float2 oUV : TEXCOORD0, \n"
" out float4 oPosition : POSITION, \n"
" uniform float4x4 worldViewProj \n"
") \n"
"{ \n"
" oUV = uv; \n"
" oPosition = mul( worldViewProj, position ); \n"
"}";
vshader->setSource(outStream.str());
vshader->load();
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
mMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
HighLevelGpuProgramPtr fshader;
if (mgr.resourceExists("BBO_FP"))
fshader = mgr.getByName("BBO_FP");
else
fshader = mgr.createProgram("BBO_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_FRAGMENT_PROGRAM);
fshader->setParameter("profiles", "ps_2_x arbfp1");
fshader->setParameter("entry_point", "main_fp");
StringUtil::StrStreamType outStream2;
outStream2 <<
"void main_fp( \n"
" in float2 uv : TEXCOORD0, \n"
" out float4 oColor : COLOR, \n";
if (RenderingManager::useMRT()) outStream2 <<
" out float4 oColor1 : COLOR1, \n";
outStream2 <<
" uniform sampler2D texture : TEXUNIT0, \n"
" uniform float4 diffuse, \n"
" uniform float4 emissive \n"
") \n"
"{ \n"
" float4 tex = tex2D(texture, uv); \n"
" oColor = float4(emissive.xyz,1) * tex * float4(1,1,1,diffuse.a); \n";
if (RenderingManager::useMRT()) outStream2 <<
" oColor1 = float4(1, 0, 0, 1); \n";
outStream2 <<
"}";
fshader->setSource(outStream2.str());
fshader->load();
fshader->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
mMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());
bodyCount++;
}
@ -157,7 +223,10 @@ Moon::Moon( const String& textureName,
outStream2 <<
"void main_fp( \n"
" in float2 uv : TEXCOORD0, \n"
" out float4 oColor : COLOR, \n"
" out float4 oColor : COLOR, \n";
if (RenderingManager::useMRT()) outStream2 <<
" out float4 oColor1 : COLOR1, \n";
outStream2 <<
" uniform sampler2D texture : TEXUNIT0, \n"
" uniform float4 skyColour, \n"
" uniform float4 diffuse, \n"
@ -165,7 +234,10 @@ Moon::Moon( const String& textureName,
") \n"
"{ \n"
" float4 tex = tex2D(texture, uv); \n"
" oColor = float4(emissive.xyz,1) * tex; \n"
" oColor = float4(emissive.xyz,1) * tex; \n";
if (RenderingManager::useMRT()) outStream2 <<
" oColor1 = float4(1, 0, 0, 1); \n";
outStream2 <<
// use a circle for the alpha (compute UV distance to center)
// looks a bit bad because its not filtered on the edges,
// but it's cheaper than a seperate alpha texture.
@ -199,10 +271,10 @@ void Moon::setPhase(const Moon::Phase& phase)
{
// Colour texture
Ogre::String textureName = "textures\\tx_";
if (mType == Moon::Type_Secunda) textureName += "secunda_";
else textureName += "masser_";
if (phase == Moon::Phase_New) textureName += "new";
else if (phase == Moon::Phase_WaxingCrescent) textureName += "one_wax";
else if (phase == Moon::Phase_WaxingHalf) textureName += "half_wax";
@ -211,9 +283,9 @@ void Moon::setPhase(const Moon::Phase& phase)
else if (phase == Moon::Phase_WaningHalf) textureName += "half_wan";
else if (phase == Moon::Phase_WaningGibbous) textureName += "three_wan";
else if (phase == Moon::Phase_Full) textureName += "full";
textureName += ".dds";
mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(textureName);
mPhase = phase;
@ -293,9 +365,8 @@ void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock();
}
SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera, MWWorld::Environment* env)
: mEnvironment(env)
, mHour(0.0f)
SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
: mHour(0.0f)
, mDay(0)
, mMonth(0)
, mSun(NULL)
@ -358,15 +429,17 @@ void SkyManager::create()
mSecunda = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode);
mSecunda->setType(Moon::Type_Secunda);
mSecunda->setRenderQueue(RENDER_QUEUE_SKIES_EARLY+4);
mSecunda->setRenderQueue(RQG_SkiesEarly+4);
mMasser = new Moon("textures\\tx_masser_full.dds", 0.75, Vector3(-0.4, 0.4, 0.5), mRootNode);
mMasser->setRenderQueue(RENDER_QUEUE_SKIES_EARLY+3);
mMasser->setRenderQueue(RQG_SkiesEarly+3);
mMasser->setType(Moon::Type_Masser);
mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode);
mSun->setRenderQueue(RQG_SkiesEarly+4);
mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode);
mSunGlare->setRenderQueue(RENDER_QUEUE_SKIES_LATE);
mSunGlare->setRenderQueue(RQG_SkiesLate);
mSunGlare->setVisibilityFlags(RV_Glare);
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
@ -375,7 +448,9 @@ void SkyManager::create()
/// \todo sky_night_02.nif (available in Bloodmoon)
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
night1_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+1);
night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
night1_ent->setVisibilityFlags(RV_Sky);
night1_ent->setCastShadows(false);
mAtmosphereNight = mRootNode->createChildSceneNode();
mAtmosphereNight->attachObject(night1_ent);
@ -413,7 +488,10 @@ void SkyManager::create()
outStream5 <<
"void main_fp( \n"
" in float2 uv : TEXCOORD0, \n"
" out float4 oColor : COLOR, \n"
" out float4 oColor : COLOR, \n";
if (RenderingManager::useMRT()) outStream5 <<
" out float4 oColor1 : COLOR1, \n";
outStream5 <<
" in float fade : TEXCOORD1, \n"
" uniform sampler2D texture : TEXUNIT0, \n"
" uniform float opacity, \n"
@ -421,7 +499,10 @@ void SkyManager::create()
" uniform float4 emissive \n"
") \n"
"{ \n"
" oColor = tex2D(texture, uv) * float4(emissive.xyz, 1) * float4(1,1,1,fade*diffuse.a); \n"
" oColor = tex2D(texture, uv) * float4(emissive.xyz, 1) * float4(1,1,1,fade*diffuse.a); \n";
if (RenderingManager::useMRT()) outStream5 <<
" oColor1 = float4(1, 0, 0, 1); \n";
outStream5 <<
"}";
stars_fp->setSource(outStream5.str());
stars_fp->load();
@ -445,10 +526,12 @@ void SkyManager::create()
// Atmosphere (day)
mesh = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif");
Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif");
atmosphere_ent->setCastShadows(false);
ModVertexAlpha(atmosphere_ent, 0);
atmosphere_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY);
atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
atmosphere_ent->setVisibilityFlags(RV_Sky);
mAtmosphereDay = mRootNode->createChildSceneNode();
mAtmosphereDay->attachObject(atmosphere_ent);
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
@ -466,29 +549,56 @@ void SkyManager::create()
" float4 position : POSITION, \n"
" in float4 color : COLOR, \n"
" out float4 oPosition : POSITION, \n"
" out float4 oColor : COLOR, \n"
" uniform float4 emissive, \n"
" out float4 oVertexColor : TEXCOORD0, \n"
" uniform float4x4 worldViewProj \n"
") \n"
"{ \n"
" oPosition = mul( worldViewProj, position ); \n"
" oColor = color * emissive; \n"
" oVertexColor = color; \n"
"}";
vshader->setSource(outStream.str());
vshader->load();
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
vshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram("");
HighLevelGpuProgramPtr fshader = mgr.createProgram("Atmosphere_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_FRAGMENT_PROGRAM);
fshader->setParameter("profiles", "ps_2_x arbfp1");
fshader->setParameter("entry_point", "main_fp");
StringUtil::StrStreamType _outStream;
_outStream <<
"void main_fp( \n"
" in float4 iVertexColor : TEXCOORD0, \n"
" out float4 oColor : COLOR, \n";
if (RenderingManager::useMRT()) _outStream <<
" out float4 oColor1 : COLOR1, \n";
_outStream <<
" uniform float4 emissive \n"
") \n"
"{ \n"
" oColor = iVertexColor * emissive; \n";
if (RenderingManager::useMRT()) _outStream <<
" oColor1 = float4(1, 0, 0, 1); \n";
_outStream <<
"}";
fshader->setSource(_outStream.str());
fshader->load();
fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());
// Clouds
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif");
clouds_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+5);
clouds_ent->setVisibilityFlags(RV_Sky);
clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
SceneNode* clouds_node = mRootNode->createChildSceneNode();
clouds_node->attachObject(clouds_ent);
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
clouds_ent->setCastShadows(false);
// Clouds vertex shader
HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
@ -525,8 +635,11 @@ void SkyManager::create()
outStream2 <<
"void main_fp( \n"
" in float2 uv : TEXCOORD0, \n"
" out float4 oColor : COLOR, \n"
" in float4 color : TEXCOORD1, \n"
" out float4 oColor : COLOR, \n";
if (RenderingManager::useMRT()) outStream2 <<
" out float4 oColor1 : COLOR1, \n";
outStream2 <<
" uniform sampler2D texture : TEXUNIT0, \n"
" uniform sampler2D secondTexture : TEXUNIT1, \n"
" uniform float transitionFactor, \n"
@ -538,7 +651,10 @@ void SkyManager::create()
"{ \n"
" uv += float2(0,1) * time * speed * 0.003; \n" // Scroll in y direction
" float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n"
" oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n"
" oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n";
if (RenderingManager::useMRT()) outStream2 <<
" oColor1 = float4(1, 0, 0, 1); \n";
outStream2 <<
"}";
mCloudFragmentShader->setSource(outStream2.str());
mCloudFragmentShader->load();
@ -564,6 +680,8 @@ void SkyManager::create()
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCloudMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("textures\\tx_sky_cloudy.dds");
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("");
mCreated = true;
@ -594,7 +712,7 @@ void SkyManager::update(float duration)
if (!mEnabled) return;
// UV Scroll the clouds
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", mEnvironment->mWorld->getTimeScaleFactor()/30.f);
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);
/// \todo improve this
mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
@ -633,7 +751,7 @@ void SkyManager::update(float duration)
mSecunda->setVisible(mSecundaEnabled);
// rotate the stars by 360 degrees every 4 days
mAtmosphereNight->roll(Degree(mEnvironment->mWorld->getTimeScaleFactor()*duration*360 / (3600*96.f)));
mAtmosphereNight->roll(Degree(MWBase::Environment::get().getWorld()->getTimeScaleFactor()*duration*360 / (3600*96.f)));
}
void SkyManager::enable()
@ -653,12 +771,14 @@ void SkyManager::disable()
void SkyManager::setMoonColour (bool red)
{
if (!mCreated) return;
mSecunda->setColour( red ? ColourValue(1.0, 0.0784, 0.0784)
: ColourValue(1.0, 1.0, 1.0));
}
void SkyManager::setCloudsOpacity(float opacity)
{
if (!mCreated) return;
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(opacity));
}
@ -734,7 +854,8 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
strength = 1.f;
mSunGlare->setVisibility(weather.mGlareView * mGlareFade * strength);
mSun->setVisibility(mGlareFade >= 0.5 ? weather.mGlareView * mGlareFade * strength : 0);
mSun->setVisibility(weather.mGlareView * strength);
mAtmosphereNight->setVisible(weather.mNight && mEnabled);
}
@ -813,11 +934,13 @@ void SkyManager::setThunder(const float factor)
void SkyManager::setMasserFade(const float fade)
{
if (!mCreated) return;
mMasser->setVisibility(fade);
}
void SkyManager::setSecundaFade(const float fade)
{
if (!mCreated) return;
mSecunda->setVisibility(fade);
}
@ -837,3 +960,18 @@ Ogre::SceneNode* SkyManager::getSunNode()
if (!mCreated) return 0;
return mSun->getNode();
}
void SkyManager::setSkyPosition(const Ogre::Vector3& position)
{
mRootNode->_setDerivedPosition(position);
}
void SkyManager::resetSkyPosition()
{
mRootNode->setPosition(0,0,0);
}
void SkyManager::scaleSky(float scale)
{
mRootNode->setScale(scale, scale, scale);
}

@ -36,30 +36,31 @@ namespace MWRender
BillboardObject();
virtual ~BillboardObject() {}
void setColour(const Ogre::ColourValue& pColour);
void setPosition(const Ogre::Vector3& pPosition);
void setVisible(const bool visible);
void setRenderQueue(unsigned int id);
void setVisibilityFlags(int flags);
void setSize(const float size);
Ogre::Vector3 getPosition() const;
void setVisibility(const float visibility);
Ogre::SceneNode* getNode();
protected:
virtual void init(const Ogre::String& textureName,
const float size,
const Ogre::Vector3& position,
Ogre::SceneNode* rootNode);
Ogre::SceneNode* mNode;
Ogre::MaterialPtr mMaterial;
Ogre::BillboardSet* mBBSet;
};
/*
* The moons need a seperate class because of their shader (which allows them to be partially transparent)
*/
@ -71,9 +72,9 @@ namespace MWRender
const Ogre::Vector3& position,
Ogre::SceneNode* rootNode
);
virtual ~Moon() {}
enum Phase
{
Phase_New = 0,
@ -85,29 +86,29 @@ namespace MWRender
Phase_WaningHalf,
Phase_WaningCrescent
};
enum Type
{
Type_Masser = 0,
Type_Secunda
};
void setPhase(const Phase& phase);
void setType(const Type& type);
void setSkyColour(const Ogre::ColourValue& colour);
Phase getPhase() const;
unsigned int getPhaseInt() const;
private:
Type mType;
Phase mPhase;
};
class SkyManager
{
public:
SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera, MWWorld::Environment* env);
SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera);
~SkyManager();
void update(float duration);
@ -168,10 +169,13 @@ namespace MWRender
void setGlare(const float glare);
Ogre::Vector3 getRealSunPos();
void setSkyPosition(const Ogre::Vector3& position);
void resetSkyPosition();
void scaleSky(float scale);
private:
bool mCreated;
MWWorld::Environment* mEnvironment;
float mHour;
int mDay;
int mMonth;
@ -180,21 +184,21 @@ namespace MWRender
BillboardObject* mSunGlare;
Moon* mMasser;
Moon* mSecunda;
Ogre::Viewport* mViewport;
Ogre::SceneNode* mRootNode;
Ogre::SceneManager* mSceneMgr;
Ogre::SceneNode* mAtmosphereDay;
Ogre::SceneNode* mAtmosphereNight;
Ogre::MaterialPtr mCloudMaterial;
Ogre::MaterialPtr mAtmosphereMaterial;
Ogre::MaterialPtr mStarsMaterials[7];
Ogre::HighLevelGpuProgramPtr mCloudFragmentShader;
// remember some settings so we don't have to apply them again if they didnt change
Ogre::String mClouds;
Ogre::String mNextClouds;
@ -204,17 +208,17 @@ namespace MWRender
float mStarsOpacity;
Ogre::ColourValue mCloudColour;
Ogre::ColourValue mSkyColour;
Ogre::Overlay* mThunderOverlay;
Ogre::TextureUnitState* mThunderTextureUnit;
float mRemainingTransitionTime;
float mGlare; // target
float mGlareFade; // actual
void ModVertexAlpha(Ogre::Entity* ent, unsigned int meshType);
bool mEnabled;
bool mSunEnabled;
bool mMasserEnabled;

@ -4,9 +4,13 @@
#include "../mwworld/world.hpp"
#include "../mwbase/environment.hpp"
#include "terrainmaterial.hpp"
#include "terrain.hpp"
#include "renderconst.hpp"
#include "shadows.hpp"
#include <components/settings/settings.hpp>
using namespace Ogre;
@ -15,8 +19,8 @@ namespace MWRender
//----------------------------------------------------------------------------------------------
TerrainManager::TerrainManager(Ogre::SceneManager* mgr, const MWWorld::Environment& evn) :
mEnvironment(evn), mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize))
TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) :
mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend)
{
TerrainMaterialGeneratorPtr matGen;
@ -47,9 +51,19 @@ namespace MWRender
mActiveProfile->setLayerSpecularMappingEnabled(false);
mActiveProfile->setLayerNormalMappingEnabled(false);
mActiveProfile->setLayerParallaxMappingEnabled(false);
mActiveProfile->setReceiveDynamicShadowsEnabled(false);
//composite maps lead to a drastic reduction in loading time so are
bool shadows = Settings::Manager::getBool("enabled", "Shadows");
mActiveProfile->setReceiveDynamicShadowsEnabled(shadows);
mActiveProfile->setReceiveDynamicShadowsDepth(shadows);
if (Settings::Manager::getBool("split", "Shadows"))
mActiveProfile->setReceiveDynamicShadowsPSSM(mRendering->getShadows()->getPSSMSetup());
else
mActiveProfile->setReceiveDynamicShadowsPSSM(0);
mActiveProfile->setShadowFar(mRendering->getShadows()->getShadowFar());
mActiveProfile->setShadowFadeStart(mRendering->getShadows()->getFadeStart());
//composite maps lead to a drastic increase in loading time so are
//disabled
mActiveProfile->setCompositeMapEnabled(false);
@ -95,7 +109,7 @@ namespace MWRender
const int cellX = store->cell->getGridX();
const int cellY = store->cell->getGridY();
ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().lands.search(cellX, cellY);
if ( land != NULL )
{
if (!land->dataLoaded)
@ -162,6 +176,8 @@ namespace MWRender
x * numTextures, y * numTextures,
numTextures,
indexes);
terrain->setVisibilityFlags(RV_Terrain);
terrain->setRenderQueueGroup(RQG_Main);
if ( land && land->landData->usingColours )
{
@ -254,7 +270,7 @@ namespace MWRender
{
//NB: All vtex ids are +1 compared to the ltex ids
assert( (int)mEnvironment.mWorld->getStore().landTexts.getSize() >= (int)ltexIndex - 1 &&
assert( (int)MWBase::Environment::get().getWorld()->getStore().landTexts.getSize() >= (int)ltexIndex - 1 &&
"LAND.VTEX must be within the bounds of the LTEX array");
std::string texture;
@ -264,7 +280,7 @@ namespace MWRender
}
else
{
texture = mEnvironment.mWorld->getStore().landTexts.search(ltexIndex-1)->texture;
texture = MWBase::Environment::get().getWorld()->getStore().landTexts.search(ltexIndex-1)->texture;
//TODO this is needed due to MWs messed up texture handling
texture = texture.substr(0, texture.rfind(".")) + ".dds";
}
@ -420,7 +436,7 @@ namespace MWRender
}
ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().lands.search(cellX, cellY);
if ( land != NULL )
{
if (!land->dataLoaded)

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

Loading…
Cancel
Save