Merged next

actorid
Alexander "Ace" Olofsson 13 years ago
commit b1af18e98d

@ -15,7 +15,7 @@ include (OpenMWMacros)
# Version # Version
set (OPENMW_VERSION_MAJOR 0) set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 13) set (OPENMW_VERSION_MINOR 14)
set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") 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(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) 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 # Sound source selection
option(USE_FFMPEG "use ffmpeg for sound" OFF) option(USE_FFMPEG "use ffmpeg for sound" OFF)
option(USE_AUDIERE "use audiere 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/renderer.cpp
${LIBDIR}/openengine/ogre/mouselook.cpp ${LIBDIR}/openengine/ogre/mouselook.cpp
${LIBDIR}/openengine/ogre/fader.cpp ${LIBDIR}/openengine/ogre/fader.cpp
${LIBDIR}/openengine/ogre/imagerotate.cpp
) )
set(OENGINE_GUI set(OENGINE_GUI
${LIBDIR}/openengine/gui/events.cpp ${LIBDIR}/openengine/gui/events.cpp
@ -116,6 +122,7 @@ set(OENGINE_BULLET
${LIBDIR}/openengine/bullet/physic.hpp ${LIBDIR}/openengine/bullet/physic.hpp
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp ${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
${LIBDIR}/openengine/bullet/BulletShapeLoader.h ${LIBDIR}/openengine/bullet/BulletShapeLoader.h
) )
set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET}) 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}) link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
if(APPLE) if (APPLE)
# List used Ogre plugins # List used Ogre plugins
SET(USED_OGRE_PLUGINS "RenderSystem_GL" SET(USED_OGRE_PLUGINS ${OGRE_RenderSystem_GL_LIBRARY_REL}
"Plugin_OctreeSceneManager" ${OGRE_Plugin_OctreeSceneManager_LIBRARY_REL}
"Plugin_CgProgramManager" ${OGRE_Plugin_CgProgramManager_LIBRARY_REL}
"Plugin_ParticleFX") ${OGRE_Plugin_ParticleFX_LIBRARY_REL})
endif(APPLE) endif (APPLE)
add_subdirectory( files/) add_subdirectory(files/)
add_subdirectory( files/mygui ) add_subdirectory(files/mygui)
# Specify build paths # Specify build paths
@ -227,6 +234,9 @@ endif (APPLE)
configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
"${OpenMW_BINARY_DIR}/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 configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
"${OpenMW_BINARY_DIR}/openmw.cfg") "${OpenMW_BINARY_DIR}/openmw.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
@ -240,37 +250,42 @@ endif (WIN32)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.linux configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.linux
"${OpenMW_BINARY_DIR}/plugins.cfg") "${OpenMW_BINARY_DIR}/plugins.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
"${OpenMW_BINARY_DIR}/openmw.desktop")
endif() endif()
if (APPLE) 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 configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac
"${OpenMW_BINARY_DIR}/plugins.cfg") "${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 configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
"${APP_BUNDLE_DIR}/Contents/Info.plist") "${APP_BUNDLE_DIR}/Contents/Info.plist")
configure_file(${OpenMW_SOURCE_DIR}/files/mac/openmw.icns configure_file(${OpenMW_SOURCE_DIR}/files/mac/openmw.icns
"${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) "${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) endif (APPLE)
@ -303,11 +318,12 @@ if(DPKG_PROGRAM)
endif() endif()
#Install icon and desktop file #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(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 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}/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}/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") 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) endif(DPKG_PROGRAM)
if(WIN32) if(WIN32)
FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*") FILE(GLOB dll_files "${OpenMW_BINARY_DIR}/Release/*.dll")
INSTALL(FILES ${files} DESTINATION ".") INSTALL(FILES ${dll_files} DESTINATION ".")
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") 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 ".") INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
SET(CPACK_GENERATOR "NSIS") SET(CPACK_GENERATOR "NSIS")
@ -356,8 +380,12 @@ if(WIN32)
SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO}) SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE}) SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher") 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_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_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt") SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
@ -367,7 +395,7 @@ if(WIN32)
SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe") 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_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_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") SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe")
if(EXISTS ${VCREDIST32}) if(EXISTS ${VCREDIST32})
@ -401,17 +429,14 @@ add_subdirectory (components)
# Apps and tools # Apps and tools
add_subdirectory( apps/openmw ) add_subdirectory( apps/openmw )
option(BUILD_ESMTOOL "build ESM inspector" ON)
if (BUILD_ESMTOOL) if (BUILD_ESMTOOL)
add_subdirectory( apps/esmtool ) add_subdirectory( apps/esmtool )
endif() endif()
option(BUILD_LAUNCHER "build Launcher inspector" ON)
if (BUILD_LAUNCHER) if (BUILD_LAUNCHER)
add_subdirectory( apps/launcher ) add_subdirectory( apps/launcher )
endif() endif()
option(BUILD_MWINIIMPORTER "build MWiniImporter inspector" ON)
if (BUILD_MWINIIMPORTER) if (BUILD_MWINIIMPORTER)
add_subdirectory( apps/mwiniimporter ) add_subdirectory( apps/mwiniimporter )
endif() endif()
@ -503,10 +528,12 @@ if (APPLE)
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) 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(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}/openmw.cfg.install" RENAME "openmw.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}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" 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_GENERATOR "DragNDrop")
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
@ -515,22 +542,25 @@ if (APPLE)
set(APPS "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}") set(APPS "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}")
set(PLUGINS "") set(PLUGINS "")
set(ABSOLUTE_PLUGINS "")
# Scan Plugins dir for *.dylibs foreach (PLUGIN ${USED_OGRE_PLUGINS})
set(PLUGIN_SEARCH_ROOT "${APP_BUNDLE_DIR}/Contents/Plugins") get_filename_component(PLUGIN_ABS ${PLUGIN} REALPATH)
file(GLOB_RECURSE ALL_PLUGINS "${PLUGIN_SEARCH_ROOT}/*.dylib") set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS})
endforeach ()
set(PLUGIN_INSTALL_BASE "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins") set(PLUGIN_INSTALL_BASE "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins")
foreach(PLUGIN ${ALL_PLUGINS}) install(FILES ${ABSOLUTE_PLUGINS} DESTINATION "${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins" COMPONENT Runtime)
string(REPLACE "${PLUGIN_SEARCH_ROOT}/" "" PLUGIN_RELATIVE "${PLUGIN}") foreach (PLUGIN ${ABSOLUTE_PLUGINS})
get_filename_component(PLUGIN_RELATIVE ${PLUGIN} NAME)
set(PLUGINS ${PLUGINS} "${PLUGIN_INSTALL_BASE}/${PLUGIN_RELATIVE}") 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 #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 "") set(DIRS "")
# Overriding item resolving during installation, it needed if # 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. # 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. # 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 if (item MATCHES \"Frameworks\") # if it is a framework
# get last segment of path # get last segment of path
get_filename_component(fname \"\${item}\" NAME_WE) 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) if (ri)
message(STATUS \"found \${ri} for \${item}\")
string(REGEX REPLACE \"^.*/Frameworks/.*\\\\.framework\" \"\" item_part \${item}) string(REGEX REPLACE \"^.*/Frameworks/.*\\\\.framework\" \"\" item_part \${item})
set(ri \"\${ri}\${item_part}\") set(ri \"\${ri}\${item_part}\")
set(\${resolved_item_var} \${ri} PARENT_SCOPE) set(\${resolved_item_var} \${ri} PARENT_SCOPE)
set(\${resolved_var} 1 PARENT_SCOPE) set(\${resolved_var} 1 PARENT_SCOPE)
set(OPENMW_RESOLVED_ITEMS \${_OPENMW_RESOLVED_ITEMS} \${ri})
endif() endif()
else() else()
# code path for standard (non-framework) libs (ogre & qt pugins) # 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()
endif() endif()
endfunction(gp_resolve_item_override) endfunction(gp_resolve_item_override)
@ -568,10 +603,5 @@ if (APPLE)
include(BundleUtilities) include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"${PLUGINS}\" \"${DIRS}\") fixup_bundle(\"${APPS}\" \"${PLUGINS}\" \"${DIRS}\")
" COMPONENT Runtime) " COMPONENT Runtime)
include(CPack)
include(CPack)
set(CMAKE_EXE_LINKER_FLAGS "-arch i386")
set(CMAKE_CXX_FLAGS "-arch i386")
endif (APPLE) endif (APPLE)

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

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

@ -10,7 +10,8 @@
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/files/collections.hpp> #include <components/files/collections.hpp>
#include "mwworld/environment.hpp" #include "mwbase/environment.hpp"
#include "mwworld/ptr.hpp" #include "mwworld/ptr.hpp"
namespace Compiler namespace Compiler
@ -78,7 +79,7 @@ namespace OMW
std::string mFocusName; std::string mFocusName;
std::map<std::string,std::string> mFallbackMap; std::map<std::string,std::string> mFallbackMap;
MWWorld::Environment mEnvironment; MWBase::Environment mEnvironment;
Compiler::Extensions mExtensions; Compiler::Extensions mExtensions;
Compiler::Context *mScriptContext; 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); assert (ref->base != NULL);
const std::string &model = ref->base->model; const std::string &model = ref->base->model;
if (!model.empty()) if (!model.empty())
{ {
MWRender::Objects& objects = renderingInterface.getObjects(); 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 = ESMS::LiveCellRef<ESM::Activator, MWWorld::RefData> *ref =
ptr.get<ESM::Activator>(); ptr.get<ESM::Activator>();

@ -12,7 +12,7 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \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 <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
@ -54,9 +55,9 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Apparatus::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -70,6 +71,14 @@ namespace MWClass
return ref->base->script; 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() void Apparatus::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Apparatus); boost::shared_ptr<Class> instance (new Apparatus);

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

@ -9,11 +9,11 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwrender/objects.hpp" #include "../mwrender/objects.hpp"
#include "../mwsound/soundmanager.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 = ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
@ -58,9 +58,9 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Armor::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -121,7 +121,7 @@ namespace MWClass
return std::make_pair (slots, false); 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 = ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
@ -147,19 +147,27 @@ namespace MWClass
if (typeGmst.empty()) if (typeGmst.empty())
return -1; 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) ref->base->data.weight)
return ESM::Skill::LightArmor; 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) ref->base->data.weight)
return ESM::Skill::MediumArmor; return ESM::Skill::MediumArmor;
return ESM::Skill::HeavyArmor; 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() void Armor::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Armor); boost::shared_ptr<Class> instance (new Armor);
@ -167,9 +175,9 @@ namespace MWClass
registerClass (typeid (ESM::Armor).name(), instance); 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) if (es == ESM::Skill::LightArmor)
return std::string("Item Armor Light Up"); return std::string("Item Armor Light Up");
else if (es == ESM::Skill::MediumArmor) else if (es == ESM::Skill::MediumArmor)
@ -178,9 +186,9 @@ namespace MWClass
return std::string("Item Armor Heavy Up"); 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) if (es == ESM::Skill::LightArmor)
return std::string("Item Armor Light Down"); return std::string("Item Armor Light Down");
else if (es == ESM::Skill::MediumArmor) else if (es == ESM::Skill::MediumArmor)

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

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
@ -54,11 +55,11 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr, 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 // 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -72,6 +73,14 @@ namespace MWClass
return ref->base->script; 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() void Book::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Book); boost::shared_ptr<Class> instance (new Book);
@ -79,12 +88,12 @@ namespace MWClass
registerClass (typeid (ESM::Book).name(), instance); 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"); 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"); return std::string("Item Book Down");
} }

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const; virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr ///< 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(); 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 ///< 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 ///< Return the put down sound Id
}; };
} }

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
@ -55,9 +56,9 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Clothing::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -89,7 +90,7 @@ namespace MWClass
static const int sMapping[size][2] = 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::Belt, MWWorld::InventoryStore::Slot_Belt },
{ ESM::Clothing::Robe, MWWorld::InventoryStore::Slot_Robe }, { ESM::Clothing::Robe, MWWorld::InventoryStore::Slot_Robe },
{ ESM::Clothing::Pants, MWWorld::InventoryStore::Slot_Pants }, { ESM::Clothing::Pants, MWWorld::InventoryStore::Slot_Pants },
@ -111,8 +112,7 @@ namespace MWClass
return std::make_pair (slots, false); return std::make_pair (slots, false);
} }
int Clothing::getEquipmentSkill (const MWWorld::Ptr& ptr, int Clothing::getEquipmentSkill (const MWWorld::Ptr& ptr) const
const MWWorld::Environment& environment) const
{ {
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref = ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
@ -123,6 +123,14 @@ namespace MWClass
return -1; 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() void Clothing::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Clothing); boost::shared_ptr<Class> instance (new Clothing);
@ -130,7 +138,7 @@ namespace MWClass
registerClass (typeid (ESM::Clothing).name(), instance); 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 = ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
@ -142,7 +150,7 @@ namespace MWClass
return std::string("Item Clothes Up"); 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 = ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();

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

@ -5,11 +5,12 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/nullaction.hpp" #include "../mwworld/nullaction.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/customdata.hpp" #include "../mwworld/customdata.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
@ -76,7 +77,7 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Container::activate (const MWWorld::Ptr& ptr, 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 lockedSound = "LockedChest";
const std::string trapActivationSound = "Disarm Trap Fail"; const std::string trapActivationSound = "Disarm Trap Fail";
@ -85,7 +86,7 @@ namespace MWClass
{ {
// TODO check for key // TODO check for key
std::cout << "Locked container" << std::endl; 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); return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
} }
else else
@ -100,7 +101,7 @@ namespace MWClass
{ {
// Trap activation goes here // Trap activation goes here
std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl; 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 = ""; ptr.getCellRef().trap = "";
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction); 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; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const; virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const;

@ -6,9 +6,10 @@
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/mechanicsmanager.hpp" #include "../mwmechanics/mechanicsmanager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp" #include "../mwworld/actiontalk.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/customdata.hpp" #include "../mwworld/customdata.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
@ -74,7 +75,7 @@ namespace MWClass
actors.insertCreature(ptr); 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 = ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
ptr.get<ESM::Creature>(); 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 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, 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)); 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; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, 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 ///< 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 ///< Enable reference; only does the non-rendering part
virtual std::string getName (const MWWorld::Ptr& ptr) const; virtual std::string getName (const MWWorld::Ptr& ptr) const;
@ -36,7 +36,7 @@ namespace MWClass
///< Return creature stats ///< Return creature stats
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual MWWorld::ContainerStore& getContainerStore ( virtual MWWorld::ContainerStore& getContainerStore (

@ -5,11 +5,12 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/nullaction.hpp" #include "../mwworld/nullaction.hpp"
#include "../mwworld/actionteleport.hpp" #include "../mwworld/actionteleport.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
@ -58,7 +59,7 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Door::activate (const MWWorld::Ptr& ptr, 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 = ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
@ -73,7 +74,7 @@ namespace MWClass
// TODO check for key // TODO check for key
// TODO report failure to player (message, sound?). Look up behaviour of original MW. // TODO report failure to player (message, sound?). Look up behaviour of original MW.
std::cout << "Locked!" << std::endl; 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); return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
} }
@ -81,7 +82,7 @@ namespace MWClass
{ {
// Trap activation // Trap activation
std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl; 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 = ""; ptr.getCellRef().trap = "";
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction); return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
} }
@ -89,11 +90,11 @@ namespace MWClass
if (ref->ref.teleport) if (ref->ref.teleport)
{ {
// teleport door // teleport door
if (environment.mWorld->getPlayer().getPlayer()==actor) if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor)
{ {
// the player is using the door // the player is using the door
// The reason this is not 3D is that it would get interrupted when you teleport // The reason this is not 3D is that it would get interrupted when you teleport
environment.mSoundManager->playSound(openSound, 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound(openSound, 1.0, 1.0);
return boost::shared_ptr<MWWorld::Action> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTeleportPlayer (ref->ref.destCell, ref->ref.doorDest)); new MWWorld::ActionTeleportPlayer (ref->ref.destCell, ref->ref.doorDest));
} }
@ -110,7 +111,7 @@ namespace MWClass
// TODO return action for rotating the door // TODO return action for rotating the door
// This is a little pointless, but helps with testing // 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); 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; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const; virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
@ -52,9 +53,9 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Ingredient::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -68,6 +69,14 @@ namespace MWClass
return ref->base->script; 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() void Ingredient::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Ingredient); boost::shared_ptr<Class> instance (new Ingredient);
@ -75,12 +84,12 @@ namespace MWClass
registerClass (typeid (ESM::Ingredient).name(), instance); 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"); 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"); return std::string("Item Ingredient Down");
} }

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const; virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr ///< 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(); 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 ///< 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 ///< Return the put down sound Id
}; };
} }

@ -5,10 +5,11 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/nullaction.hpp" #include "../mwworld/nullaction.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwsound/soundmanager.hpp" #include "../mwsound/soundmanager.hpp"
@ -39,7 +40,7 @@ namespace MWClass
objects.insertLight (ptr, r, g, b, radius); 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 = ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>(); 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 = ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
if (!ref->base->sound.empty()) 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, 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 = ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
@ -83,7 +84,7 @@ namespace MWClass
if (!(ref->base->data.flags & ESM::Light::Carry)) if (!(ref->base->data.flags & ESM::Light::Carry))
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction); 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -110,6 +111,14 @@ namespace MWClass
return std::make_pair (slots, false); 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() void Light::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Light); boost::shared_ptr<Class> instance (new Light);
@ -117,12 +126,12 @@ namespace MWClass
registerClass (typeid (ESM::Light).name(), instance); 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"); 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"); return std::string("Item Misc Down");
} }

@ -12,9 +12,9 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, 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 ///< Enable reference; only does the non-rendering part
/// \attention This is not the same as the script instruction with the same name. References /// \attention This is not the same as the script instruction with the same name. References
/// should only be enabled while in an active cell. /// should only be enabled while in an active cell.
@ -24,7 +24,7 @@ namespace MWClass
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const; 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 ///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped? /// 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(); 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 ///< 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 ///< Return the put down sound Id
}; };
} }

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Tool>();
@ -56,9 +57,9 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Lockpick::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -81,6 +82,14 @@ namespace MWClass
return std::make_pair (slots, false); 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() void Lockpick::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Lockpick); boost::shared_ptr<Class> instance (new Lockpick);
@ -88,12 +97,12 @@ namespace MWClass
registerClass (typeid (ESM::Tool).name(), instance); 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"); 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"); return std::string("Item Lockpick Down");
} }

@ -12,14 +12,14 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const; 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 ///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped? /// 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(); 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 ///< 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 ///< Return the put down sound Id
}; };
} }

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
@ -54,9 +55,9 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Miscellaneous::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -70,6 +71,14 @@ namespace MWClass
return ref->base->script; 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() void Miscellaneous::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Miscellaneous); boost::shared_ptr<Class> instance (new Miscellaneous);
@ -77,7 +86,7 @@ namespace MWClass
registerClass (typeid (ESM::Miscellaneous).name(), instance); 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 = ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
@ -89,7 +98,7 @@ namespace MWClass
return std::string("Item Misc Up"); 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 = ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const; virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr ///< 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(); 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 ///< 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 ///< Return the put down sound Id
}; };
} }

@ -14,11 +14,12 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp" #include "../mwworld/actiontalk.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwworld/customdata.hpp" #include "../mwworld/customdata.hpp"
#include "../mwbase/environment.hpp"
namespace namespace
{ {
const Ogre::Radian kOgrePi (Ogre::Math::PI); const Ogre::Radian kOgrePi (Ogre::Math::PI);
@ -53,28 +54,40 @@ namespace MWClass
// NPC stats // NPC stats
if (!ref->base->faction.empty()) if (!ref->base->faction.empty())
{ {
// TODO research how initial rank is stored. The information in loadnpc.hpp are at if(ref->base->npdt52.gold != -10)
// best very unclear. {
data->mNpcStats.mFactionRank[ref->base->faction] = 0; 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) if(ref->base->npdt52.gold != -10)
data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]); {
for (int i=0; i<27; ++i)
// creature stats data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]);
data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength);
data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); // creature stats
data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower); data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength);
data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility); data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence);
data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed); data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower);
data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance); data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility);
data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality); data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed);
data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck); data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance);
data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health); data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality);
data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana); data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck);
data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue); data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health);
data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana);
data->mCreatureStats.mLevel = ref->base->npdt52.level; 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 // \todo add initial container content
@ -93,10 +106,13 @@ namespace MWClass
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const 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 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, 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)); return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
} }
@ -281,7 +297,6 @@ namespace MWClass
void Npc::registerSelf() void Npc::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Npc); boost::shared_ptr<Class> instance (new Npc);
registerClass (typeid (ESM::NPC).name(), instance); registerClass (typeid (ESM::NPC).name(), instance);
} }
} }

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

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
@ -54,9 +55,9 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Potion::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -70,6 +71,14 @@ namespace MWClass
return ref->base->script; 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() void Potion::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Potion); boost::shared_ptr<Class> instance (new Potion);
@ -77,12 +86,12 @@ namespace MWClass
registerClass (typeid (ESM::Potion).name(), instance); 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"); 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"); return std::string("Item Potion Down");
} }

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const; virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr ///< 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(); 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 ///< 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 ///< Return the put down sound Id
}; };
} }

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
@ -55,9 +56,9 @@ namespace MWClass
return ref->base->name; return ref->base->name;
} }
boost::shared_ptr<MWWorld::Action> Probe::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -80,6 +81,14 @@ namespace MWClass
return std::make_pair (slots, false); 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() void Probe::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Probe); boost::shared_ptr<Class> instance (new Probe);
@ -87,12 +96,12 @@ namespace MWClass
registerClass (typeid (ESM::Probe).name(), instance); 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"); 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"); return std::string("Item Probe Down");
} }

@ -12,14 +12,14 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const; 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 ///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped? /// 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(); 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 ///< 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 ///< Return the put down sound Id
}; };
} }

@ -5,9 +5,10 @@
#include <components/esm_store/cell_store.hpp> #include <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
@ -54,9 +55,9 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Repair::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -70,6 +71,14 @@ namespace MWClass
return ref->base->script; 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() void Repair::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Repair); boost::shared_ptr<Class> instance (new Repair);
@ -77,12 +86,12 @@ namespace MWClass
registerClass (typeid (ESM::Repair).name(), instance); 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"); 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"); return std::string("Item Repair Down");
} }

@ -12,25 +12,28 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string. /// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, 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 ///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const; virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr ///< 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(); 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 ///< 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 ///< 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 = ESMS::LiveCellRef<ESM::Static, MWWorld::RefData> *ref =
ptr.get<ESM::Static>(); ptr.get<ESM::Static>();

@ -12,7 +12,7 @@ namespace MWClass
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual std::string getName (const MWWorld::Ptr& ptr) 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); ///< \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 <components/esm_store/cell_store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwrender/objects.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 = ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
@ -55,9 +56,9 @@ namespace MWClass
} }
boost::shared_ptr<MWWorld::Action> Weapon::activate (const MWWorld::Ptr& ptr, 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> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionTake (ptr));
@ -108,8 +109,7 @@ namespace MWClass
return std::make_pair (slots, stack); return std::make_pair (slots, stack);
} }
int Weapon::getEquipmentSkill (const MWWorld::Ptr& ptr, int Weapon::getEquipmentSkill (const MWWorld::Ptr& ptr) const
const MWWorld::Environment& environment) const
{ {
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref = ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
@ -139,6 +139,14 @@ namespace MWClass
return -1; 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() void Weapon::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Weapon); boost::shared_ptr<Class> instance (new Weapon);
@ -146,7 +154,7 @@ namespace MWClass
registerClass (typeid (ESM::Weapon).name(), instance); 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 = ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
@ -192,7 +200,7 @@ namespace MWClass
return std::string("Item Misc Up"); 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 = ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();

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

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

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

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

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

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

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

@ -23,7 +23,6 @@ namespace MWGui
private: private:
MWScript::CompilerContext mCompilerContext; MWScript::CompilerContext mCompilerContext;
MWWorld::Environment& mEnvironment;
std::vector<std::string> mNames; std::vector<std::string> mNames;
bool compile (const std::string& cmd, Compiler::Output& output); bool compile (const std::string& cmd, Compiler::Output& output);
@ -51,7 +50,7 @@ namespace MWGui
StringList::iterator current; StringList::iterator current;
std::string editString; 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(); 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 "window_manager.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
#include "../mwworld/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwdialogue/dialoguemanager.hpp" #include "../mwdialogue/dialoguemanager.hpp"
#include <assert.h> #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) DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager), : WindowBase("openmw_dialogue_window_layout.xml", parWindowManager)
mEnvironment(environment)
{ {
// Centre dialog // Centre dialog
center(); 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 /// \todo scrolling the dialogue history with the mouse wheel doesn't work using this solution
getWidget(eventbox, "EventBox"); getWidget(eventbox, "EventBox");
eventbox->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked); eventbox->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked);
//Topics list //Topics list
getWidget(topicsList, "TopicsList"); getWidget(topicsList, "TopicsList");
topicsList->setScrollVisible(true); topicsList->setScrollVisible(true);
@ -83,9 +82,9 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
if(color != "#B29154") if(color != "#B29154")
{ {
UString key = history->getColorTextAt(cursorPosition); 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) void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
{ {
mEnvironment.mDialogueManager->goodbyeSelected(); MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
} }
void DialogueWindow::onSelectTopic(MyGUI::ListBox* _sender, size_t _index) 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) if (_index == MyGUI::ITEM_NONE)
return; return;
std::string topic = _sender->getItemNameAt(_index); 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) void DialogueWindow::startDialogue(std::string npcName)
@ -183,6 +182,16 @@ void DialogueWindow::addText(std::string text)
void DialogueWindow::addTitle(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); history->addDialogHeading(text);
} }

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

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

@ -31,6 +31,11 @@ HUD::HUD(int width, int height, int fpsLevel)
, fpscounter(NULL) , fpscounter(NULL)
, trianglecounter(NULL) , trianglecounter(NULL)
, batchcounter(NULL) , batchcounter(NULL)
, hmsBaseLeft(0)
, weapBoxBaseLeft(0)
, spellBoxBaseLeft(0)
, effectBoxBaseRight(0)
, minimapBoxBaseRight(0)
{ {
setCoord(0,0, width, height); setCoord(0,0, width, height);
@ -38,32 +43,32 @@ HUD::HUD(int width, int height, int fpsLevel)
getWidget(health, "Health"); getWidget(health, "Health");
getWidget(magicka, "Magicka"); getWidget(magicka, "Magicka");
getWidget(stamina, "Stamina"); getWidget(stamina, "Stamina");
hmsBaseLeft = health->getLeft();
// Item and spell images and status bars // Item and spell images and status bars
getWidget(weapBox, "WeapBox");
getWidget(weapImage, "WeapImage"); getWidget(weapImage, "WeapImage");
getWidget(weapStatus, "WeapStatus"); getWidget(weapStatus, "WeapStatus");
weapBoxBaseLeft = weapBox->getLeft();
getWidget(spellBox, "SpellBox");
getWidget(spellImage, "SpellImage"); getWidget(spellImage, "SpellImage");
getWidget(spellStatus, "SpellStatus"); getWidget(spellStatus, "SpellStatus");
spellBoxBaseLeft = spellBox->getLeft();
getWidget(effectBox, "EffectBox"); getWidget(effectBox, "EffectBox");
getWidget(effect1, "Effect1"); getWidget(effect1, "Effect1");
effectBoxBaseRight = effectBox->getRight();
getWidget(minimapBox, "MiniMapBox");
minimapBoxBaseRight = minimapBox->getRight();
getWidget(minimap, "MiniMap"); getWidget(minimap, "MiniMap");
getWidget(compass, "Compass"); getWidget(compass, "Compass");
getWidget(crosshair, "Crosshair"); getWidget(crosshair, "Crosshair");
if ( fpsLevel == 2 ){ setFpsLevel(fpsLevel);
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");
}
getWidget(trianglecounter, "TriangleCounter"); getWidget(trianglecounter, "TriangleCounter");
getWidget(batchcounter, "BatchCounter"); getWidget(batchcounter, "BatchCounter");
@ -81,6 +86,28 @@ HUD::HUD(int width, int height, int fpsLevel)
LocalMapBase::init(minimap, this); 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) void HUD::setFPS(float fps)
{ {
fpscounter->setCaption(boost::lexical_cast<std::string>((int)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) void HUD::setPlayerDir(const float x, const float y)
{ {
if (!minimapBox->getVisible() || (x == mLastPositionX && y == mLastPositionY)) return;
MyGUI::ISubWidget* main = compass->getSubWidgetMain(); MyGUI::ISubWidget* main = compass->getSubWidgetMain();
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>(); MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
float angle = std::atan2(x,y); float angle = std::atan2(x,y);
rotatingSubskin->setAngle(angle); rotatingSubskin->setAngle(angle);
mLastPositionX = x;
mLastPositionY = y;
} }
void HUD::setPlayerPos(const float x, const float y) void HUD::setPlayerPos(const float x, const float y)
{ {
if (!minimapBox->getVisible() || (x == mLastDirectionX && y == mLastDirectionY)) return;
MyGUI::IntSize size = minimap->getCanvasSize(); 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::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(); MyGUI::IntCoord viewsize = minimap->getCoord();
@ -179,99 +212,39 @@ void HUD::setPlayerPos(const float x, const float y)
minimap->setViewOffset(pos); minimap->setViewOffset(pos);
compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); 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"); mLastDirectionX = x;
getWidget(mGlobalMap, "GlobalMap"); mLastDirectionY = y;
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));
} }
void MapWindow::setPlayerDir(const float x, const float y) void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible)
{ {
if (!mVisible) return; int weapDx = 0, spellDx = 0;
MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); if (!hmsVisible)
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>(); spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft;
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
float angle = std::atan2(x,y); if (!weapVisible)
rotatingSubskin->setAngle(angle); 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; // effect box can have variable width -> variable left coordinate
if (!mGlobal) int effectsDx = 0;
mLastDragPos = MyGUI::IntPoint(_left, _top); if (!minimapBoxVisible)
} effectsDx = minimapBoxBaseRight - effectBoxBaseRight;
void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) minimapBox->setVisible(minimapBoxVisible);
{ effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop());
if (_id!=MyGUI::MouseButton::Left) return; effectBox->setVisible(effectBoxVisible);
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" );
} }
LocalMapBase::LocalMapBase() LocalMapBase::LocalMapBase()
@ -283,6 +256,10 @@ LocalMapBase::LocalMapBase()
, mPrefix() , mPrefix()
, mChanged(true) , mChanged(true)
, mLayout(NULL) , mLayout(NULL)
, mLastPositionX(0.0f)
, mLastPositionY(0.0f)
, mLastDirectionX(0.0f)
, mLastDirectionY(0.0f)
{ {
} }

@ -53,6 +53,11 @@ namespace MWGui
void applyFogOfWar(); void applyFogOfWar();
OEngine::GUI::Layout* mLayout; OEngine::GUI::Layout* mLayout;
float mLastPositionX;
float mLastPositionY;
float mLastDirectionX;
float mLastDirectionY;
}; };
class HUD : public OEngine::GUI::Layout, public LocalMapBase class HUD : public OEngine::GUI::Layout, public LocalMapBase
@ -71,11 +76,15 @@ namespace MWGui
void setBatchCount(size_t count); void setBatchCount(size_t count);
void setPlayerDir(const float x, const float y); void setPlayerDir(const float x, const float y);
void setPlayerPos(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::ProgressPtr health, magicka, stamina;
MyGUI::Widget *weapBox, *spellBox;
MyGUI::ImageBox *weapImage, *spellImage; MyGUI::ImageBox *weapImage, *spellImage;
MyGUI::ProgressPtr weapStatus, spellStatus; MyGUI::ProgressPtr weapStatus, spellStatus;
MyGUI::WidgetPtr effectBox; MyGUI::Widget *effectBox, *minimapBox;
MyGUI::ImageBox* effect1; MyGUI::ImageBox* effect1;
MyGUI::ScrollView* minimap; MyGUI::ScrollView* minimap;
MyGUI::ImageBox* compass; MyGUI::ImageBox* compass;
@ -85,30 +94,12 @@ namespace MWGui
MyGUI::TextBox* fpscounter; MyGUI::TextBox* fpscounter;
MyGUI::TextBox* trianglecounter; MyGUI::TextBox* trianglecounter;
MyGUI::TextBox* batchcounter; 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: private:
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); // bottom left elements
void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
void onWorldButtonClicked(MyGUI::Widget* _sender); // bottom right elements
int minimapBoxBaseRight, effectBoxBaseRight;
MyGUI::ScrollView* mGlobalMap;
MyGUI::ImageBox* mPlayerArrow;
MyGUI::Button* mButton;
MyGUI::IntPoint mLastDragPos;
bool mVisible;
bool mGlobal;
}; };
class MainMenu : public OEngine::GUI::Layout 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; const int StatsWindow::lineHeight = 18;
StatsWindow::StatsWindow (WindowManager& parWindowManager) StatsWindow::StatsWindow (WindowManager& parWindowManager)
: WindowBase("openmw_stats_window_layout.xml", parWindowManager) : WindowPinnableBase("openmw_stats_window_layout.xml", parWindowManager)
, skillAreaWidget(NULL) , skillAreaWidget(NULL)
, skillClientWidget(NULL) , skillClientWidget(NULL)
, skillScrollerWidget(NULL) , skillScrollerWidget(NULL)
@ -381,3 +381,8 @@ void StatsWindow::updateScroller()
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
} }
void StatsWindow::onPinToggled()
{
mWindowManager.setHMSVisibility(!mPinned);
}

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

@ -4,26 +4,30 @@
#include "review.hpp" #include "review.hpp"
#include "dialogue.hpp" #include "dialogue.hpp"
#include "dialogue_history.hpp" #include "dialogue_history.hpp"
#include "map_window.hpp"
#include "stats_window.hpp" #include "stats_window.hpp"
#include "messagebox.hpp" #include "messagebox.hpp"
#include "../mwmechanics/mechanicsmanager.hpp" #include "../mwmechanics/mechanicsmanager.hpp"
#include "../mwinput/inputmanager.hpp" #include "../mwinput/inputmanager.hpp"
#include "../mwbase/environment.hpp"
#include "console.hpp" #include "console.hpp"
#include "journalwindow.hpp" #include "journalwindow.hpp"
#include "charactercreation.hpp" #include "charactercreation.hpp"
#include <components/settings/settings.hpp>
#include <assert.h> #include <assert.h>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
using namespace MWGui; 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) const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath)
: mGuiManager(NULL) : mGuiManager(NULL)
, environment(environment)
, hud(NULL) , hud(NULL)
, map(NULL) , map(NULL)
, menu(NULL) , menu(NULL)
@ -71,17 +75,17 @@ WindowManager::WindowManager(MWWorld::Environment& environment,
hud = new HUD(w,h, showFPSLevel); hud = new HUD(w,h, showFPSLevel);
menu = new MainMenu(w,h); menu = new MainMenu(w,h);
map = new MapWindow(); map = new MapWindow(*this);
stats = new StatsWindow(*this); stats = new StatsWindow(*this);
console = new Console(w,h, environment, extensions); console = new Console(w,h, extensions);
mJournal = new JournalWindow(*this); mJournal = new JournalWindow(*this);
mMessageBoxManager = new MessageBoxManager(this); mMessageBoxManager = new MessageBoxManager(this);
dialogueWindow = new DialogueWindow(*this,environment); dialogueWindow = new DialogueWindow(*this);
// The HUD is always on // The HUD is always on
hud->setVisible(true); hud->setVisible(true);
mCharGen = new CharacterCreation(this, &environment); mCharGen = new CharacterCreation(this);
// Setup player stats // Setup player stats
for (int i = 0; i < ESM::Attribute::Length; ++i) for (int i = 0; i < ESM::Attribute::Length; ++i)
@ -140,7 +144,7 @@ void WindowManager::update()
if (needModeChange) if (needModeChange)
{ {
needModeChange = false; needModeChange = false;
environment.mInputManager->setGuiMode(nextMode); MWBase::Environment::get().getInputManager()->setGuiMode(nextMode);
nextMode = GM_Game; nextMode = GM_Game;
} }
if (showFPSLevel > 0) if (showFPSLevel > 0)
@ -151,11 +155,6 @@ void WindowManager::update()
} }
} }
MWWorld::Environment& WindowManager::getEnvironment()
{
return environment;
}
void WindowManager::setNextMode(GuiMode newMode) void WindowManager::setNextMode(GuiMode newMode)
{ {
nextMode = newMode; nextMode = newMode;
@ -164,7 +163,7 @@ void WindowManager::setNextMode(GuiMode newMode)
void WindowManager::setGuiMode(GuiMode newMode) void WindowManager::setGuiMode(GuiMode newMode)
{ {
environment.mInputManager->setGuiMode(newMode); MWBase::Environment::get().getInputManager()->setGuiMode(newMode);
} }
void WindowManager::updateVisible() void WindowManager::updateVisible()
@ -385,7 +384,7 @@ int WindowManager::readPressedButton ()
const std::string &WindowManager::getGameSettingString(const std::string &id, const std::string &default_) 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) if (setting && setting->type == ESM::VT_String)
return setting->str; return setting->str;
return default_; return default_;
@ -409,7 +408,7 @@ void WindowManager::onFrame (float frameDuration)
const ESMS::ESMStore& WindowManager::getStore() const const ESMS::ESMStore& WindowManager::getStore() const
{ {
return environment.mWorld->getStore(); return MWBase::Environment::get().getWorld()->getStore();
} }
void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
@ -456,8 +455,26 @@ void WindowManager::setPlayerDir(const float x, const float y)
hud->setPlayerDir(x,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() void WindowManager::toggleFogOfWar()
{ {
map->toggleFogOfWar(); map->toggleFogOfWar();
hud->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 namespace MWWorld
{ {
class Environment;
class World; class World;
} }
@ -83,7 +82,7 @@ namespace MWGui
typedef std::vector<Faction> FactionList; typedef std::vector<Faction> FactionList;
typedef std::vector<int> SkillList; 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(); virtual ~WindowManager();
void setGuiMode(GuiMode newMode); void setGuiMode(GuiMode newMode);
@ -95,8 +94,6 @@ namespace MWGui
*/ */
void update(); void update();
MWWorld::Environment& getEnvironment();
void setMode(GuiMode newMode) void setMode(GuiMode newMode)
{ {
if (newMode==GM_Inventory && allowed==GW_None) 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 setPlayerDir(const float x, const float y); ///< set player view direction in map space
void toggleFogOfWar(); void toggleFogOfWar();
int toggleFps();
///< toggle fps display @return resulting fps level
void setInteriorMapTexture(const int x, const int y); void setInteriorMapTexture(const int x, const int y);
///< set the index of the map texture that should be used (for interiors) ///< 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> template<typename T>
void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr. 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. void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
@ -184,7 +189,6 @@ namespace MWGui
private: private:
OEngine::GUI::MyGUIManager *mGuiManager; OEngine::GUI::MyGUIManager *mGuiManager;
MWWorld::Environment& environment;
HUD *hud; HUD *hud;
MapWindow *map; MapWindow *map;
MainMenu *menu; 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_QuickLoad,
A_QuickMenu, A_QuickMenu,
A_GameMenu, A_GameMenu,
A_ToggleWeapon,
A_ToggleSpell,
A_ToggleFps, // Toggle FPS display (this is temporary)
A_LAST // Marker for the last item A_LAST // Marker for the last item
}; };
@ -86,6 +90,45 @@ namespace MWInput
/* InputImpl Methods */ /* 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() void screenshot()
{ {
mEngine.screenshot(); mEngine.screenshot();
@ -143,11 +186,13 @@ namespace MWInput
void toggleAutoMove() void toggleAutoMove()
{ {
if (windows.isGuiMode()) return;
player.setAutoMove (!player.getAutoMove()); player.setAutoMove (!player.getAutoMove());
} }
void toggleWalking() void toggleWalking()
{ {
if (windows.isGuiMode()) return;
player.toggleRunning(); player.toggleRunning();
} }
@ -197,7 +242,12 @@ namespace MWInput
"Auto Move"); "Auto Move");
disp->funcs.bind(A_ToggleWalk, boost::bind(&InputImpl::toggleWalking, this), disp->funcs.bind(A_ToggleWalk, boost::bind(&InputImpl::toggleWalking, this),
"Toggle Walk/Run"); "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 // Add the exit listener
ogre.getRoot()->addFrameListener(&exit); ogre.getRoot()->addFrameListener(&exit);
@ -242,6 +292,9 @@ namespace MWInput
disp->bind(A_AutoMove, KC_Z); disp->bind(A_AutoMove, KC_Z);
disp->bind(A_ToggleSneak, KC_X); disp->bind(A_ToggleSneak, KC_X);
disp->bind(A_ToggleWalk, KC_C); 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 // Key bindings for polled keys
// NOTE: These keys are constantly being polled. Only add keys that must be checked each frame. // 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 "stat.hpp"
#include "magiceffects.hpp" #include "magiceffects.hpp"
#include "spells.hpp"
namespace MWMechanics namespace MWMechanics
{ {
@ -14,7 +15,7 @@ namespace MWMechanics
Stat<int> mAttributes[8]; Stat<int> mAttributes[8];
DynamicStat<int> mDynamic[3]; // health, magicka, fatigue DynamicStat<int> mDynamic[3]; // health, magicka, fatigue
int mLevel; int mLevel;
std::set<std::string> mAbilities; Spells mSpells;
MagicEffects mMagicEffects; 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 "../mwgui/window_manager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
@ -14,7 +15,7 @@ namespace MWMechanics
{ {
void MechanicsManager::buildPlayer() 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::CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr); MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr);
@ -23,7 +24,7 @@ namespace MWMechanics
// reset // reset
creatureStats.mLevel = player->npdt52.level; creatureStats.mLevel = player->npdt52.level;
creatureStats.mAbilities.clear(); creatureStats.mSpells.clear();
creatureStats.mMagicEffects = MagicEffects(); creatureStats.mMagicEffects = MagicEffects();
for (int i=0; i<27; ++i) for (int i=0; i<27; ++i)
@ -33,10 +34,10 @@ namespace MWMechanics
if (mRaceSelected) if (mRaceSelected)
{ {
const ESM::Race *race = const ESM::Race *race =
mEnvironment.mWorld->getStore().races.find ( MWBase::Environment::get().getWorld()->getStore().races.find (
mEnvironment.mWorld->getPlayer().getRace()); 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) 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()); for (std::vector<std::string>::const_iterator iter (race->powers.list.begin());
iter!=race->powers.list.end(); ++iter) iter!=race->powers.list.end(); ++iter)
{ {
insertSpell (*iter, ptr); creatureStats.mSpells.add (*iter);
} }
} }
// birthsign // birthsign
if (!mEnvironment.mWorld->getPlayer().getBirthsign().empty()) if (!MWBase::Environment::get().getWorld()->getPlayer().getBirthsign().empty())
{ {
const ESM::BirthSign *sign = const ESM::BirthSign *sign =
mEnvironment.mWorld->getStore().birthSigns.find ( MWBase::Environment::get().getWorld()->getStore().birthSigns.find (
mEnvironment.mWorld->getPlayer().getBirthsign()); MWBase::Environment::get().getWorld()->getPlayer().getBirthsign());
for (std::vector<std::string>::const_iterator iter (sign->powers.list.begin()); for (std::vector<std::string>::const_iterator iter (sign->powers.list.begin());
iter!=sign->powers.list.end(); ++iter) iter!=sign->powers.list.end(); ++iter)
{ {
insertSpell (*iter, ptr); creatureStats.mSpells.add (*iter);
} }
} }
// class // class
if (mClassSelected) 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) for (int i=0; i<2; ++i)
{ {
@ -121,7 +122,7 @@ namespace MWMechanics
} }
typedef ESMS::IndexListT<ESM::Skill>::MapType ContainerType; 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) 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()); 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) void MechanicsManager::adjustMagicEffects (MWWorld::Ptr& creature)
{ {
MWMechanics::CreatureStats& creatureStats = MWMechanics::CreatureStats& creatureStats =
MWWorld::Class::get (creature).getCreatureStats (creature); MWWorld::Class::get (creature).getCreatureStats (creature);
MagicEffects now; MagicEffects now = creatureStats.mSpells.getMagicEffects();
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);
for (std::vector<ESM::ENAMstruct>::const_iterator iter = spell->effects.list.begin(); /// \todo add effects from active spells and equipment
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
MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now); MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now);
@ -220,8 +176,8 @@ namespace MWMechanics
// TODO apply diff to other stats // TODO apply diff to other stats
} }
MechanicsManager::MechanicsManager (MWWorld::Environment& environment) MechanicsManager::MechanicsManager()
: mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false), : mUpdatePlayer (true), mClassSelected (false),
mRaceSelected (false) mRaceSelected (false)
{ {
buildPlayer(); buildPlayer();
@ -229,7 +185,7 @@ namespace MWMechanics
void MechanicsManager::addActor (const MWWorld::Ptr& ptr) void MechanicsManager::addActor (const MWWorld::Ptr& ptr)
{ {
mActors.insert (ptr); mActors.addActor (ptr);
} }
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr) void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
@ -237,7 +193,7 @@ namespace MWMechanics
if (ptr==mWatched) if (ptr==mWatched)
mWatched = MWWorld::Ptr(); mWatched = MWWorld::Ptr();
mActors.erase (ptr); mActors.removeActor (ptr);
} }
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore) void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
@ -245,16 +201,7 @@ namespace MWMechanics
if (!mWatched.isEmpty() && mWatched.getCell()==cellStore) if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
mWatched = MWWorld::Ptr(); mWatched = MWWorld::Ptr();
std::set<MWWorld::Ptr>::iterator iter = mActors.begin(); mActors.dropActors (cellStore);
while (iter!=mActors.end())
if (iter->getCell()==cellStore)
{
//std::cout << "Erasing an actor";
mActors.erase (iter++);
}
else
++iter;
} }
void MechanicsManager::watchActor (const MWWorld::Ptr& ptr) void MechanicsManager::watchActor (const MWWorld::Ptr& ptr)
@ -262,7 +209,8 @@ namespace MWMechanics
mWatched = ptr; 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()) if (!mWatched.isEmpty())
{ {
@ -289,7 +237,7 @@ namespace MWMechanics
{ {
mWatchedCreature.mAttributes[i] = stats.mAttributes[i]; 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]; 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; update = true;
mWatchedNpc.mSkill[i] = npcStats.mSkill[i]; 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) 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) if (mUpdatePlayer)
{ {
// basic player profile; should not change anymore after the creation phase is finished. // basic player profile; should not change anymore after the creation phase is finished.
mEnvironment.mWindowManager->setValue ("name", mEnvironment.mWorld->getPlayer().getName()); MWBase::Environment::get().getWindowManager()->setValue ("name", MWBase::Environment::get().getWorld()->getPlayer().getName());
mEnvironment.mWindowManager->setValue ("race", MWBase::Environment::get().getWindowManager()->setValue ("race",
mEnvironment.mWorld->getStore().races.find (mEnvironment.mWorld->getPlayer(). MWBase::Environment::get().getWorld()->getStore().races.find (MWBase::Environment::get().getWorld()->getPlayer().
getRace())->name); getRace())->name);
mEnvironment.mWindowManager->setValue ("class", MWBase::Environment::get().getWindowManager()->setValue ("class",
mEnvironment.mWorld->getPlayer().getClass().name); MWBase::Environment::get().getWorld()->getPlayer().getClass().name);
mUpdatePlayer = false; mUpdatePlayer = false;
MWGui::WindowManager::SkillList majorSkills (5); MWGui::WindowManager::SkillList majorSkills (5);
@ -338,33 +286,26 @@ namespace MWMechanics
for (int i=0; i<5; ++i) for (int i=0; i<5; ++i)
{ {
minorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][0]; minorSkills[i] = MWBase::Environment::get().getWorld()->getPlayer().getClass().data.skills[i][0];
majorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][1]; 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(); mActors.update (movement, duration, paused);
++iter)
{
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
if (vector!=Ogre::Vector3::ZERO)
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
}
} }
void MechanicsManager::setPlayerName (const std::string& name) void MechanicsManager::setPlayerName (const std::string& name)
{ {
mEnvironment.mWorld->getPlayer().setName (name); MWBase::Environment::get().getWorld()->getPlayer().setName (name);
mUpdatePlayer = true; mUpdatePlayer = true;
} }
void MechanicsManager::setPlayerRace (const std::string& race, bool male) void MechanicsManager::setPlayerRace (const std::string& race, bool male)
{ {
mEnvironment.mWorld->getPlayer().setGender (male); MWBase::Environment::get().getWorld()->getPlayer().setGender (male);
mEnvironment.mWorld->getPlayer().setRace (race); MWBase::Environment::get().getWorld()->getPlayer().setRace (race);
mRaceSelected = true; mRaceSelected = true;
buildPlayer(); buildPlayer();
mUpdatePlayer = true; mUpdatePlayer = true;
@ -372,14 +313,14 @@ namespace MWMechanics
void MechanicsManager::setPlayerBirthsign (const std::string& id) void MechanicsManager::setPlayerBirthsign (const std::string& id)
{ {
mEnvironment.mWorld->getPlayer().setBirthsign (id); MWBase::Environment::get().getWorld()->getPlayer().setBirthsign (id);
buildPlayer(); buildPlayer();
mUpdatePlayer = true; mUpdatePlayer = true;
} }
void MechanicsManager::setPlayerClass (const std::string& id) 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; mClassSelected = true;
buildPlayer(); buildPlayer();
mUpdatePlayer = true; mUpdatePlayer = true;
@ -387,7 +328,7 @@ namespace MWMechanics
void MechanicsManager::setPlayerClass (const ESM::Class& class_) void MechanicsManager::setPlayerClass (const ESM::Class& class_)
{ {
mEnvironment.mWorld->getPlayer().setClass (class_); MWBase::Environment::get().getWorld()->getPlayer().setClass (class_);
mClassSelected = true; mClassSelected = true;
buildPlayer(); buildPlayer();
mUpdatePlayer = true; mUpdatePlayer = true;

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

@ -2,14 +2,19 @@
#define GAME_MWMECHANICS_NPCSTATS_H #define GAME_MWMECHANICS_NPCSTATS_H
#include <map> #include <map>
#include <set>
#include "stat.hpp" #include "stat.hpp"
#include "drawstate.hpp"
namespace MWMechanics namespace MWMechanics
{ {
/// \brief Additional stats for NPCs /// \brief Additional stats for NPCs
/// ///
/// For non-NPC-specific stats, see the CreatureStats struct. /// 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 struct NpcStats
{ {
@ -24,9 +29,10 @@ namespace MWMechanics
bool mRun; bool mRun;
bool mSneak; bool mSneak;
bool mCombat; bool mCombat;
DrawState mDrawState;
NpcStats() : mForceRun (false), mForceSneak (false), mRun (false), mSneak (false), 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){ void Actors::setMwRoot(Ogre::SceneNode* root){
mMwRoot = root; mMwRoot = root;
} }
void Actors::insertNPC(const MWWorld::Ptr& ptr){ void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv){
insertBegin(ptr, true, true); insertBegin(ptr, true, true);
NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mEnvironment, mRend); 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_){ void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){
Ogre::SceneNode* cellnode; 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){ void Actors::insertCreature (const MWWorld::Ptr& ptr){
insertBegin(ptr, true, true); 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)); //mAllActors.insert(std::pair<MWWorld::Ptr, Animation*>(ptr,anim));
delete mAllActors[ptr]; delete mAllActors[ptr];
mAllActors[ptr] = anim; mAllActors[ptr] = anim;

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

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

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

@ -1,4 +1,5 @@
#include "creatureanimation.hpp" #include "creatureanimation.hpp"
#include "renderconst.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
@ -9,7 +10,7 @@ namespace MWRender{
CreatureAnimation::~CreatureAnimation(){ 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(); insert = ptr.getRefData().getBaseNode();
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref = ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
ptr.get<ESM::Creature>(); ptr.get<ESM::Creature>();
@ -20,6 +21,28 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme
std::string meshNumbered = mesh + getUniqueID(mesh) + ">|"; std::string meshNumbered = mesh + getUniqueID(mesh) + ">|";
NifOgre::NIFLoader::load(meshNumbered); NifOgre::NIFLoader::load(meshNumbered);
base = mRend.getScene()->createEntity(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>|"; std::string meshZero = mesh + "0000>|";
if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){ if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){

@ -7,20 +7,19 @@
#include "../mwworld/refdata.hpp" #include "../mwworld/refdata.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/environment.hpp"
#include "components/nifogre/ogre_nif_loader.hpp" #include "components/nifogre/ogre_nif_loader.hpp"
namespace MWRender{ namespace MWRender{
class CreatureAnimation: public Animation{ class CreatureAnimation: public Animation{
public: public:
virtual ~CreatureAnimation(); 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); virtual void runAnimation(float timepassed);
}; };
} }
#endif #endif

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

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

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

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

@ -1,6 +1,8 @@
#include "npcanimation.hpp" #include "npcanimation.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "renderconst.hpp"
#include "../mwbase/environment.hpp"
using namespace Ogre; using namespace Ogre;
using namespace NifOgre; 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 = ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
ptr.get<ESM::NPC>(); 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 //Part selection on last character of the file string
// " Tri Chest // " Tri Chest
@ -34,16 +76,22 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
std::string hairID = ref->base->hair; std::string hairID = ref->base->hair;
std::string headID = ref->base->head; 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 = //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); 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); 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 ; /*std::cout << "Race: " << ref->base->race ;
if(female){ if(female){
@ -56,7 +104,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
std::string smodel = "meshes\\base_anim.nif"; std::string smodel = "meshes\\base_anim.nif";
if(beast) if(isBeast)
smodel = "meshes\\base_animkna.nif"; smodel = "meshes\\base_animkna.nif";
insert = ptr.getRefData().getBaseNode(); insert = ptr.getRefData().getBaseNode();
@ -65,6 +113,29 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
NifOgre::NIFLoader::load(smodel); NifOgre::NIFLoader::load(smodel);
base = mRend.getScene()->createEntity(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 base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones
//stay in the same place when we skipanim, or open a gui window //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); textmappings = NIFLoader::getSingletonPtr()->getTextIndices(smodel);
insert->attachObject(base); insert->attachObject(base);
if(female)
if(isFemale)
insert->scale(race->data.height.female, race->data.height.female, race->data.height.female); insert->scale(race->data.height.female, race->data.height.female, race->data.height.female);
else else
insert->scale(race->data.height.male, race->data.height.male, race->data.height.male); insert->scale(race->data.height.male, race->data.height.male, race->data.height.male);
std::string headModel = "meshes\\" + updateParts();
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");
} }
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
} void NpcAnimation::updateParts(){
if(ankle){
insertBoundedPart("meshes\\" + ankle->model + "*|", "Left Ankle"); //Ogre::Quaternion(Ogre::Radian(3.14 / 4), Ogre::Vector3(1, 0, 0)),blank); //1,0,0, blank); bool apparelChanged = false;
insertBoundedPart("meshes\\" + ankle->model, "Right Ankle");
}
if (armr){ //inv.getSlot(MWWorld::InventoryStore::Slot_Robe);
insertBoundedPart("meshes\\" + armr->model, "Right Upper Arm"); 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){ if(skirtiter != inv.getSlot(MWWorld::InventoryStore::Slot_Skirt)){
insertBoundedPart("meshes\\" + arml->model + "*|", "Left Upper Arm"); //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) }
{ if(cuirass != inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)){
insertBoundedPart("meshes\\" + forearmr->model, "Right Forearm"); cuirass = inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass);
} removePartGroup(MWWorld::InventoryStore::Slot_Cuirass);
if(forearml) apparelChanged = true;
insertBoundedPart("meshes\\" + forearml->model + "*|", "Left Forearm");
if (wristr) }
{ if(greaves != inv.getSlot(MWWorld::InventoryStore::Slot_Greaves)){
insertBoundedPart("meshes\\" + wristr->model, "Right Wrist"); 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){ Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){
NIFLoader::load(mesh); 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; std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix;
NIFLoader::load(meshNumbered); 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); std::vector<Nif::NiTriShapeCopy>* shape = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix));
entityparts.push_back(ent); if(shape){
shapes = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix)); handleShapes(shape, part, base->getSkeleton());
if(shapes){
shapeparts.push_back(shapes);
handleShapes(shapes, ent, base->getSkeleton());
} }
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> pair = std::make_pair(part, shape);
return pair;
}
}
void NpcAnimation::runAnimation(float timepassed){ void NpcAnimation::runAnimation(float timepassed){
if(timeToChange > .2){
timeToChange = 0;
updateParts();
}
timeToChange += timepassed;
//1. Add the amount of time passed to time //1. Add the amount of time passed to time
//2. Handle the animation transforms dependent on time //2. Handle the animation transforms dependent on time
@ -262,23 +577,285 @@ void NpcAnimation::runAnimation(float timepassed){
time = startTime + (time - stopTime); 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(); vecRotPos.clear();
std::vector<Nif::NiTriShapeCopy>* shapes = *shapepartsiter;
Ogre::Entity* theentity = *entitypartsiter;
handleShapes(shapes, theentity, base->getSkeleton()); if(lFreeFoot.first)
shapepartsiter++; handleShapes(lFreeFoot.second, lFreeFoot.first, base->getSkeleton());
entitypartsiter++; 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/property.hpp>
#include <components/nif/controller.hpp> #include <components/nif/controller.hpp>
#include <components/nif/extra.hpp> #include <components/nif/extra.hpp>
#include <utility>
#include "../mwworld/refdata.hpp" #include "../mwworld/refdata.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/environment.hpp"
#include "components/nifogre/ogre_nif_loader.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{ namespace MWRender{
class NpcAnimation: public Animation{ 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: 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(); virtual ~NpcAnimation();
Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); 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); 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/nifogre/ogre_nif_loader.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include "renderconst.hpp"
using namespace MWRender; using namespace MWRender;
bool Objects::lightConst = false; // These are the Morrowind.ini defaults
float Objects::lightConstValue = 0.0f;
bool Objects::lightLinear = true;
int Objects::lightLinearMethod = 1;
float Objects::lightLinearValue = 3; float Objects::lightLinearValue = 3;
float Objects::lightLinearRadiusMult = 1; float Objects::lightLinearRadiusMult = 1;
bool Objects::lightQuadratic = false;
int Objects::lightQuadraticMethod = 2;
float Objects::lightQuadraticValue = 16; float Objects::lightQuadraticValue = 16;
float Objects::lightQuadraticRadiusMult = 1; float Objects::lightQuadraticRadiusMult = 1;
bool Objects::lightOutQuadInLin = false; bool Objects::lightOutQuadInLin = true;
bool Objects::lightQuadratic = false;
int Objects::uniqueID = 0; int Objects::uniqueID = 0;
@ -112,11 +108,32 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
bounds.scale(insert->getScale()); bounds.scale(insert->getScale());
mBounds[ptr.getCell()].merge(bounds); 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); 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 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)); sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
mStaticGeometrySmall[ptr.getCell()] = sg; 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 else
sg = mStaticGeometrySmall[ptr.getCell()]; 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->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); mRenderer.getScene()->destroyEntity(ent);
} }
} }
@ -168,35 +191,61 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f
assert(insert); assert(insert);
Ogre::Light *light = mRenderer.getScene()->createLight(); Ogre::Light *light = mRenderer.getScene()->createLight();
light->setDiffuseColour (r, g, b); 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) if (ref->base->data.flags & ESM::Light::Negative)
cval = lightConstValue; 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) float r = radius * lightLinearRadiusMult;
radius *= lightLinearRadiusMult; float attenuation = lightLinearValue / r;
if(lightQuadratic) light->setAttenuation(r*10, 0, attenuation, 0);
radius *= lightQuadraticRadiusMult;
if(lightLinear)
lval = lightLinearValue / pow(radius, lightLinearMethod);
if(lightQuadratic)
qval = lightQuadraticValue / pow(radius, lightQuadraticMethod);
} }
else else
{ {
// FIXME: float r = radius * lightQuadraticRadiusMult;
// Do quadratic or linear, depending if we're in an exterior or interior float attenuation = lightQuadraticValue / pow(r, 2);
// cell, respectively. Ignore lightLinear and lightQuadratic. light->setAttenuation(r*10, 0, 0, attenuation);
} }
light->setAttenuation(10*radius, cval, lval, qval);
insert->attachObject(light); insert->attachObject(light);
mLights.push_back(info);
} }
bool Objects::deleteObject (const MWWorld::Ptr& ptr) bool Objects::deleteObject (const MWWorld::Ptr& ptr)
@ -277,12 +326,12 @@ Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell)
void Objects::enableLights() void Objects::enableLights()
{ {
std::vector<std::string>::iterator it = mLights.begin(); std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end()) 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; ++it;
} }
else else
@ -292,12 +341,12 @@ void Objects::enableLights()
void Objects::disableLights() void Objects::disableLights()
{ {
std::vector<std::string>::iterator it = mLights.begin(); std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end()) 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; ++it;
} }
else 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{ 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{ class Objects{
OEngine::Render::OgreRenderer &mRenderer; OEngine::Render::OgreRenderer &mRenderer;
std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes; std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes;
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry; std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry;
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall; std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall;
std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds; std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds;
std::vector<std::string> mLights; std::vector<LightInfo> mLights;
Ogre::SceneNode* mMwRoot; Ogre::SceneNode* mMwRoot;
bool mIsStatic; bool mIsStatic;
static int uniqueID; static int uniqueID;
static bool lightConst;
static float lightConstValue;
static bool lightLinear;
static int lightLinearMethod;
static float lightLinearValue; static float lightLinearValue;
static float lightLinearRadiusMult; static float lightLinearRadiusMult;
static bool lightQuadratic; static bool lightQuadratic;
static int lightQuadraticMethod;
static float lightQuadraticValue; static float lightQuadraticValue;
static float lightQuadraticRadiusMult; static float lightQuadraticRadiusMult;
@ -39,7 +68,7 @@ class Objects{
///< Remove all movable objects from \a node. ///< Remove all movable objects from \a node.
public: public:
Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer){} Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer) {}
~Objects(){} ~Objects(){}
void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);
@ -48,6 +77,9 @@ public:
void enableLights(); void enableLights();
void disableLights(); void disableLights();
void update (const float dt);
///< per-frame update
Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*); Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*);
///< get a bounding box that encloses all objects in the specified cell ///< get a bounding box that encloses all objects in the specified cell

@ -1,4 +1,5 @@
#include "occlusionquery.hpp" #include "occlusionquery.hpp"
#include "renderconst.hpp"
#include <OgreRenderSystem.h> #include <OgreRenderSystem.h>
#include <OgreRoot.h> #include <OgreRoot.h>
@ -40,9 +41,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
return; 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 matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");
MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels"); MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels");
matQueryArea->setDepthWriteEnabled(false); matQueryArea->setDepthWriteEnabled(false);
@ -62,25 +60,31 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
mBBQueryTotal = mRendering->getScene()->createBillboardSet(1); mBBQueryTotal = mRendering->getScene()->createBillboardSet(1);
mBBQueryTotal->setCastShadows(false);
mBBQueryTotal->setDefaultDimensions(150, 150); mBBQueryTotal->setDefaultDimensions(150, 150);
mBBQueryTotal->createBillboard(Vector3::ZERO); mBBQueryTotal->createBillboard(Vector3::ZERO);
mBBQueryTotal->setMaterialName("QueryTotalPixels"); mBBQueryTotal->setMaterialName("QueryTotalPixels");
mBBQueryTotal->setRenderQueueGroup(queue+1); mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery);
mBBNodeReal->attachObject(mBBQueryTotal); mBBNodeReal->attachObject(mBBQueryTotal);
mBBQueryVisible = mRendering->getScene()->createBillboardSet(1); mBBQueryVisible = mRendering->getScene()->createBillboardSet(1);
mBBQueryVisible->setCastShadows(false);
mBBQueryVisible->setDefaultDimensions(150, 150); mBBQueryVisible->setDefaultDimensions(150, 150);
mBBQueryVisible->createBillboard(Vector3::ZERO); mBBQueryVisible->createBillboard(Vector3::ZERO);
mBBQueryVisible->setMaterialName("QueryVisiblePixels"); mBBQueryVisible->setMaterialName("QueryVisiblePixels");
mBBQueryVisible->setRenderQueueGroup(queue+1); mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery);
mBBNodeReal->attachObject(mBBQueryVisible); mBBNodeReal->attachObject(mBBQueryVisible);
mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1); mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1);
/// \todo ideally this should occupy exactly 1 pixel on the screen /// \todo ideally this should occupy exactly 1 pixel on the screen
mBBQuerySingleObject->setCastShadows(false);
mBBQuerySingleObject->setDefaultDimensions(0.003, 0.003); mBBQuerySingleObject->setDefaultDimensions(0.003, 0.003);
mBBQuerySingleObject->createBillboard(Vector3::ZERO); mBBQuerySingleObject->createBillboard(Vector3::ZERO);
mBBQuerySingleObject->setMaterialName("QueryVisiblePixels"); mBBQuerySingleObject->setMaterialName("QueryVisiblePixels");
mBBQuerySingleObject->setRenderQueueGroup(queue); mBBQuerySingleObject->setRenderQueueGroup(RQG_OcclusionQuery);
mBBQuerySingleObject->setVisibilityFlags(RV_OcclusionQuery);
mObjectNode->attachObject(mBBQuerySingleObject); mObjectNode->attachObject(mBBQuerySingleObject);
mRendering->getScene()->addRenderObjectListener(this); 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 * 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 * 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) 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/esm/loadstat.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include "shadows.hpp"
#include "shaderhelper.hpp"
#include "localmap.hpp"
#include "water.hpp"
using namespace MWRender; using namespace MWRender;
using namespace Ogre; using namespace Ogre;
namespace MWRender { namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment) RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine)
:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0) :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0)
{ {
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); 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 //The fog type must be set before any terrain objects are created as if the
//fog type is set to FOG_NONE then the initially created terrain won't have any fog //fog type is set to FOG_NONE then the initially created terrain won't have any fog
@ -39,14 +43,41 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
std::string filter = Settings::Manager::getString("texture filtering", "General"); std::string filter = Settings::Manager::getString("texture filtering", "General");
if (filter == "anisotropic") tfo = TFO_ANISOTROPIC; if (filter == "anisotropic") tfo = TFO_ANISOTROPIC;
else if (filter == "trilinear") tfo = TFO_TRILINEAR; 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().setDefaultTextureFiltering(tfo);
MaterialManager::getSingleton().setDefaultAnisotropy(Settings::Manager::getInt("anisotropy", "General")); MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
// Load resources // Load resources
ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); 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 // Turn the entire scene (represented by the 'root' node) -90
// degrees around the x axis. This makes Z go upwards, and Y go into // 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 // 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(); Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode();
cameraPitchNode->attachObject(mRendering.getCamera()); cameraPitchNode->attachObject(mRendering.getCamera());
mShadows = new Shadows(&mRendering);
mShaderHelper = new ShaderHelper(this);
mTerrainManager = new TerrainManager(mRendering.getScene(), this);
//mSkyManager = 0; //mSkyManager = 0;
mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera(), &environment); mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera());
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
mWater = 0;
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mSun = 0; mSun = 0;
mDebugging = new Debugging(mMwRoot, environment, engine); mDebugging = new Debugging(mMwRoot, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this, &environment); mLocalMap = new MWRender::LocalMap(&mRendering, this);
} }
RenderingManager::~RenderingManager () RenderingManager::~RenderingManager ()
{ {
//TODO: destroy mSun?
delete mPlayer; delete mPlayer;
delete mSkyManager; delete mSkyManager;
delete mDebugging; delete mDebugging;
@ -122,8 +155,7 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store)
void RenderingManager::removeWater () void RenderingManager::removeWater ()
{ {
if(mWater){ if(mWater){
delete mWater; mWater->setActive(false);
mWater = 0;
} }
} }
@ -139,6 +171,7 @@ void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
mDebugging->cellAdded(store); mDebugging->cellAdded(store);
if (store->cell->isExterior()) if (store->cell->isExterior())
mTerrainManager->cellAdded(store); mTerrainManager->cellAdded(store);
waterAdded(store);
} }
void RenderingManager::addObject (const MWWorld::Ptr& ptr){ 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){ void RenderingManager::update (float duration){
mActors.update (duration); mActors.update (duration);
mObjects.update (duration);
mOcclusionQuery->update(duration); mOcclusionQuery->update(duration);
@ -191,15 +225,16 @@ void RenderingManager::update (float duration){
mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() );
checkUnderwater(); checkUnderwater();
mWater->update();
} }
void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){
if(store->cell->data.flags & store->cell->HasWater){ if(store->cell->data.flags & store->cell->HasWater){
if(mWater == 0) if(mWater == 0)
mWater = new MWRender::Water(mRendering.getCamera(), store->cell); mWater = new MWRender::Water(mRendering.getCamera(), mSkyManager, store->cell);
else else
mWater->changeCell(store->cell); mWater->changeCell(store->cell);
//else mWater->setActive(true);
} }
else else
removeWater(); removeWater();
@ -263,11 +298,25 @@ bool RenderingManager::toggleRenderMode(int mode)
{ {
if (mRendering.getCamera()->getPolygonMode() == PM_SOLID) 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); mRendering.getCamera()->setPolygonMode(PM_WIREFRAME);
return true; return true;
} }
else 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); mRendering.getCamera()->setPolygonMode(PM_SOLID);
return false; return false;
} }
@ -276,23 +325,29 @@ bool RenderingManager::toggleRenderMode(int mode)
void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell) void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
{ {
Ogre::ColourValue color; Ogre::ColourValue color;
color.setAsABGR (mCell.cell->ambi.fog); 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) 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 low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
float high = max / (density) * Settings::Manager::getFloat("fog end 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.getCamera()->setFarClipDistance ( max / density );
mRendering.getViewport()->setBackgroundColour (colour); 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) void RenderingManager::configureAmbient(ESMS::CellStore<MWWorld::RefData> &mCell)
{ {
mAmbientColor.setAsABGR (mCell.cell->ambi.ambient); mAmbientColor.setAsABGR (mCell.cell->ambi.ambient);
setAmbientMode(); setAmbientMode();
// Create a "sun" that shines light downwards. It doesn't look // Create a "sun" that shines light downwards. It doesn't look
// completely right, but leave it for now. // completely right, but leave it for now.
if(!mSun) if(!mSun)
{ {
mSun = mRendering.getScene()->createLight(); mSun = mRendering.getScene()->createLight();
} }
Ogre::ColourValue colour; Ogre::ColourValue colour;
colour.setAsABGR (mCell.cell->ambi.sunlight); colour.setAsABGR (mCell.cell->ambi.sunlight);
mSun->setDiffuseColour (colour); mSun->setDiffuseColour (colour);
mSun->setType(Ogre::Light::LT_DIRECTIONAL); mSun->setType(Ogre::Light::LT_DIRECTIONAL);
mSun->setDirection(0,-1,0); mSun->setDirection(0,-1,0);
} }
// Switch through lighting modes. // Switch through lighting modes.
void RenderingManager::toggleLight() void RenderingManager::toggleLight()
{ {
if (mAmbientMode==2) if (mAmbientMode==2)
mAmbientMode = 0; mAmbientMode = 0;
else else
++mAmbientMode; ++mAmbientMode;
switch (mAmbientMode) switch (mAmbientMode)
{ {
case 0: std::cout << "Setting lights to normal\n"; break; case 0: std::cout << "Setting lights to normal\n"; break;
case 1: std::cout << "Turning the lights up\n"; break; case 1: std::cout << "Turning the lights up\n"; break;
case 2: std::cout << "Turning the lights to full\n"; break; case 2: std::cout << "Turning the lights to full\n"; break;
} }
setAmbientMode(); setAmbientMode();
} }
void RenderingManager::checkUnderwater(){ void RenderingManager::checkUnderwater()
if(mWater){ {
if(mWater)
{
mWater->checkUnderwater( mRendering.getCamera()->getRealPosition().y ); mWater->checkUnderwater( mRendering.getCamera()->getRealPosition().y );
} }
} }
@ -371,7 +428,9 @@ void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr)
void RenderingManager::setSunColour(const Ogre::ColourValue& colour) void RenderingManager::setSunColour(const Ogre::ColourValue& colour)
{ {
if (!mSunEnabled) return;
mSun->setDiffuseColour(colour); mSun->setDiffuseColour(colour);
mSun->setSpecularColour(colour);
mTerrainManager->setDiffuse(colour); mTerrainManager->setDiffuse(colour);
} }
@ -383,12 +442,21 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour)
void RenderingManager::sunEnable() 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() 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) void RenderingManager::setSunDirection(const Ogre::Vector3& direction)
@ -421,11 +489,33 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell)
void RenderingManager::disableLights() void RenderingManager::disableLights()
{ {
mObjects.disableLights(); mObjects.disableLights();
sunDisable();
} }
void RenderingManager::enableLights() void RenderingManager::enableLights()
{ {
mObjects.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 } // namespace

@ -25,17 +25,12 @@
#include "objects.hpp" #include "objects.hpp"
#include "actors.hpp" #include "actors.hpp"
#include "player.hpp" #include "player.hpp"
#include "water.hpp"
#include "localmap.hpp"
#include "occlusionquery.hpp" #include "occlusionquery.hpp"
namespace Ogre namespace Ogre
{ {
class Camera;
class Viewport;
class SceneManager; class SceneManager;
class SceneNode; class SceneNode;
class RaySceneQuery;
class Quaternion; class Quaternion;
class Vector3; class Vector3;
} }
@ -48,7 +43,10 @@ namespace MWWorld
namespace MWRender namespace MWRender
{ {
class Shadows;
class ShaderHelper;
class LocalMap;
class Water;
class RenderingManager: private RenderingInterface { class RenderingManager: private RenderingInterface {
@ -59,7 +57,7 @@ class RenderingManager: private RenderingInterface {
virtual MWRender::Actors& getActors(); virtual MWRender::Actors& getActors();
public: 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(); virtual ~RenderingManager();
@ -84,6 +82,8 @@ class RenderingManager: private RenderingInterface {
void removeWater(); void removeWater();
static const bool useMRT();
void preCellChange (MWWorld::Ptr::CellStore* store); void preCellChange (MWWorld::Ptr::CellStore* store);
///< this event is fired immediately before changing cell ///< this event is fired immediately before changing cell
@ -115,6 +115,11 @@ class RenderingManager: private RenderingInterface {
bool occlusionQuerySupported() { return mOcclusionQuery->supported(); }; bool occlusionQuerySupported() { return mOcclusionQuery->supported(); };
OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; }; OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; };
Shadows* getShadows();
void switchToInterior();
void switchToExterior();
void setGlare(bool glare); void setGlare(bool glare);
void skyEnable (); void skyEnable ();
void skyDisable (); void skyDisable ();
@ -150,6 +155,8 @@ class RenderingManager: private RenderingInterface {
void setAmbientMode(); void setAmbientMode();
bool mSunEnabled;
SkyManager* mSkyManager; SkyManager* mSkyManager;
OcclusionQuery* mOcclusionQuery; OcclusionQuery* mOcclusionQuery;
@ -181,6 +188,10 @@ class RenderingManager: private RenderingInterface {
MWRender::Debugging *mDebugging; MWRender::Debugging *mDebugging;
MWRender::LocalMap* mLocalMap; 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 <components/nifogre/ogre_nif_loader.hpp>
#include "../mwworld/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "occlusionquery.hpp" #include "renderconst.hpp"
#include "renderingmanager.hpp"
using namespace MWRender; using namespace MWRender;
using namespace Ogre; using namespace Ogre;
@ -60,6 +61,11 @@ Vector3 BillboardObject::getPosition() const
return Vector3(p.x, -p.z, p.y); return Vector3(p.x, -p.z, p.y);
} }
void BillboardObject::setVisibilityFlags(int flags)
{
mBBSet->setVisibilityFlags(flags);
}
void BillboardObject::setColour(const ColourValue& pColour) void BillboardObject::setColour(const ColourValue& pColour)
{ {
mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(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 /// \todo These billboards are not 100% correct, might want to revisit them later
mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1); mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1);
mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize); mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
mBBSet->setRenderQueueGroup(RENDER_QUEUE_MAIN+2);
mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON); mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON);
mBBSet->setCommonDirection( -position.normalisedCopy() ); mBBSet->setCommonDirection( -position.normalisedCopy() );
mBBSet->setVisibilityFlags(RV_Sky);
mNode = rootNode->createChildSceneNode(); mNode = rootNode->createChildSceneNode();
mNode->setPosition(finalPosition); mNode->setPosition(finalPosition);
mNode->attachObject(mBBSet); mNode->attachObject(mBBSet);
mBBSet->createBillboard(0,0,0); mBBSet->createBillboard(0,0,0);
mBBSet->setCastShadows(false);
mMaterial = MaterialManager::getSingleton().create("BillboardMaterial"+StringConverter::toString(bodyCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mMaterial = MaterialManager::getSingleton().create("BillboardMaterial"+StringConverter::toString(bodyCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
mMaterial->removeAllTechniques(); mMaterial->removeAllTechniques();
@ -109,6 +116,65 @@ void BillboardObject::init(const String& textureName,
p->createTextureUnitState(textureName); p->createTextureUnitState(textureName);
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount)); 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++; bodyCount++;
} }
@ -157,7 +223,10 @@ Moon::Moon( const String& textureName,
outStream2 << outStream2 <<
"void main_fp( \n" "void main_fp( \n"
" in float2 uv : TEXCOORD0, \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 sampler2D texture : TEXUNIT0, \n"
" uniform float4 skyColour, \n" " uniform float4 skyColour, \n"
" uniform float4 diffuse, \n" " uniform float4 diffuse, \n"
@ -165,7 +234,10 @@ Moon::Moon( const String& textureName,
") \n" ") \n"
"{ \n" "{ \n"
" float4 tex = tex2D(texture, uv); \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) // use a circle for the alpha (compute UV distance to center)
// looks a bit bad because its not filtered on the edges, // looks a bit bad because its not filtered on the edges,
// but it's cheaper than a seperate alpha texture. // but it's cheaper than a seperate alpha texture.
@ -199,10 +271,10 @@ void Moon::setPhase(const Moon::Phase& phase)
{ {
// Colour texture // Colour texture
Ogre::String textureName = "textures\\tx_"; Ogre::String textureName = "textures\\tx_";
if (mType == Moon::Type_Secunda) textureName += "secunda_"; if (mType == Moon::Type_Secunda) textureName += "secunda_";
else textureName += "masser_"; else textureName += "masser_";
if (phase == Moon::Phase_New) textureName += "new"; if (phase == Moon::Phase_New) textureName += "new";
else if (phase == Moon::Phase_WaxingCrescent) textureName += "one_wax"; else if (phase == Moon::Phase_WaxingCrescent) textureName += "one_wax";
else if (phase == Moon::Phase_WaxingHalf) textureName += "half_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_WaningHalf) textureName += "half_wan";
else if (phase == Moon::Phase_WaningGibbous) textureName += "three_wan"; else if (phase == Moon::Phase_WaningGibbous) textureName += "three_wan";
else if (phase == Moon::Phase_Full) textureName += "full"; else if (phase == Moon::Phase_Full) textureName += "full";
textureName += ".dds"; textureName += ".dds";
mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(textureName); mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(textureName);
mPhase = phase; 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(); ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock();
} }
SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera, MWWorld::Environment* env) SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
: mEnvironment(env) : mHour(0.0f)
, mHour(0.0f)
, mDay(0) , mDay(0)
, mMonth(0) , mMonth(0)
, mSun(NULL) , 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 = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode);
mSecunda->setType(Moon::Type_Secunda); 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 = 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); mMasser->setType(Moon::Type_Masser);
mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode); 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 = 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(); HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
@ -375,7 +448,9 @@ void SkyManager::create()
/// \todo sky_night_02.nif (available in Bloodmoon) /// \todo sky_night_02.nif (available in Bloodmoon)
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif"); MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
Entity* night1_ent = mSceneMgr->createEntity("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 = mRootNode->createChildSceneNode();
mAtmosphereNight->attachObject(night1_ent); mAtmosphereNight->attachObject(night1_ent);
@ -413,7 +488,10 @@ void SkyManager::create()
outStream5 << outStream5 <<
"void main_fp( \n" "void main_fp( \n"
" in float2 uv : TEXCOORD0, \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" " in float fade : TEXCOORD1, \n"
" uniform sampler2D texture : TEXUNIT0, \n" " uniform sampler2D texture : TEXUNIT0, \n"
" uniform float opacity, \n" " uniform float opacity, \n"
@ -421,7 +499,10 @@ void SkyManager::create()
" uniform float4 emissive \n" " uniform float4 emissive \n"
") \n" ") \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->setSource(outStream5.str());
stars_fp->load(); stars_fp->load();
@ -445,10 +526,12 @@ void SkyManager::create()
// Atmosphere (day) // Atmosphere (day)
mesh = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif"); mesh = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif");
Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif"); Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif");
atmosphere_ent->setCastShadows(false);
ModVertexAlpha(atmosphere_ent, 0); 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 = mRootNode->createChildSceneNode();
mAtmosphereDay->attachObject(atmosphere_ent); mAtmosphereDay->attachObject(atmosphere_ent);
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial(); mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
@ -466,29 +549,56 @@ void SkyManager::create()
" float4 position : POSITION, \n" " float4 position : POSITION, \n"
" in float4 color : COLOR, \n" " in float4 color : COLOR, \n"
" out float4 oPosition : POSITION, \n" " out float4 oPosition : POSITION, \n"
" out float4 oColor : COLOR, \n" " out float4 oVertexColor : TEXCOORD0, \n"
" uniform float4 emissive, \n"
" uniform float4x4 worldViewProj \n" " uniform float4x4 worldViewProj \n"
") \n" ") \n"
"{ \n" "{ \n"
" oPosition = mul( worldViewProj, position ); \n" " oPosition = mul( worldViewProj, position ); \n"
" oColor = color * emissive; \n" " oVertexColor = color; \n"
"}"; "}";
vshader->setSource(outStream.str()); vshader->setSource(outStream.str());
vshader->load(); vshader->load();
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); 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)->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 // Clouds
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif"); NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
Entity* clouds_ent = mSceneMgr->createEntity("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(); SceneNode* clouds_node = mRootNode->createChildSceneNode();
clouds_node->attachObject(clouds_ent); clouds_node->attachObject(clouds_ent);
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial(); mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
clouds_ent->setCastShadows(false);
// Clouds vertex shader // Clouds vertex shader
HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
@ -525,8 +635,11 @@ void SkyManager::create()
outStream2 << outStream2 <<
"void main_fp( \n" "void main_fp( \n"
" in float2 uv : TEXCOORD0, \n" " in float2 uv : TEXCOORD0, \n"
" out float4 oColor : COLOR, \n"
" in float4 color : TEXCOORD1, \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 texture : TEXUNIT0, \n"
" uniform sampler2D secondTexture : TEXUNIT1, \n" " uniform sampler2D secondTexture : TEXUNIT1, \n"
" uniform float transitionFactor, \n" " uniform float transitionFactor, \n"
@ -538,7 +651,10 @@ void SkyManager::create()
"{ \n" "{ \n"
" uv += float2(0,1) * time * speed * 0.003; \n" // Scroll in y direction " uv += float2(0,1) * time * speed * 0.003; \n" // Scroll in y direction
" float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n" " 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->setSource(outStream2.str());
mCloudFragmentShader->load(); mCloudFragmentShader->load();
@ -564,6 +680,8 @@ void SkyManager::create()
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCloudMaterial->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(""); mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("");
mCreated = true; mCreated = true;
@ -594,7 +712,7 @@ void SkyManager::update(float duration)
if (!mEnabled) return; if (!mEnabled) return;
// UV Scroll the clouds // 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 /// \todo improve this
mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) ); mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
@ -633,7 +751,7 @@ void SkyManager::update(float duration)
mSecunda->setVisible(mSecundaEnabled); mSecunda->setVisible(mSecundaEnabled);
// rotate the stars by 360 degrees every 4 days // 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() void SkyManager::enable()
@ -653,12 +771,14 @@ void SkyManager::disable()
void SkyManager::setMoonColour (bool red) void SkyManager::setMoonColour (bool red)
{ {
if (!mCreated) return;
mSecunda->setColour( red ? ColourValue(1.0, 0.0784, 0.0784) mSecunda->setColour( red ? ColourValue(1.0, 0.0784, 0.0784)
: ColourValue(1.0, 1.0, 1.0)); : ColourValue(1.0, 1.0, 1.0));
} }
void SkyManager::setCloudsOpacity(float opacity) void SkyManager::setCloudsOpacity(float opacity)
{ {
if (!mCreated) return;
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(opacity)); mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(opacity));
} }
@ -734,7 +854,8 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
strength = 1.f; strength = 1.f;
mSunGlare->setVisibility(weather.mGlareView * mGlareFade * strength); 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); mAtmosphereNight->setVisible(weather.mNight && mEnabled);
} }
@ -813,11 +934,13 @@ void SkyManager::setThunder(const float factor)
void SkyManager::setMasserFade(const float fade) void SkyManager::setMasserFade(const float fade)
{ {
if (!mCreated) return;
mMasser->setVisibility(fade); mMasser->setVisibility(fade);
} }
void SkyManager::setSecundaFade(const float fade) void SkyManager::setSecundaFade(const float fade)
{ {
if (!mCreated) return;
mSecunda->setVisibility(fade); mSecunda->setVisibility(fade);
} }
@ -837,3 +960,18 @@ Ogre::SceneNode* SkyManager::getSunNode()
if (!mCreated) return 0; if (!mCreated) return 0;
return mSun->getNode(); 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(); BillboardObject();
virtual ~BillboardObject() {} virtual ~BillboardObject() {}
void setColour(const Ogre::ColourValue& pColour); void setColour(const Ogre::ColourValue& pColour);
void setPosition(const Ogre::Vector3& pPosition); void setPosition(const Ogre::Vector3& pPosition);
void setVisible(const bool visible); void setVisible(const bool visible);
void setRenderQueue(unsigned int id); void setRenderQueue(unsigned int id);
void setVisibilityFlags(int flags);
void setSize(const float size); void setSize(const float size);
Ogre::Vector3 getPosition() const; Ogre::Vector3 getPosition() const;
void setVisibility(const float visibility); void setVisibility(const float visibility);
Ogre::SceneNode* getNode(); Ogre::SceneNode* getNode();
protected: protected:
virtual void init(const Ogre::String& textureName, virtual void init(const Ogre::String& textureName,
const float size, const float size,
const Ogre::Vector3& position, const Ogre::Vector3& position,
Ogre::SceneNode* rootNode); Ogre::SceneNode* rootNode);
Ogre::SceneNode* mNode; Ogre::SceneNode* mNode;
Ogre::MaterialPtr mMaterial; Ogre::MaterialPtr mMaterial;
Ogre::BillboardSet* mBBSet; Ogre::BillboardSet* mBBSet;
}; };
/* /*
* The moons need a seperate class because of their shader (which allows them to be partially transparent) * 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, const Ogre::Vector3& position,
Ogre::SceneNode* rootNode Ogre::SceneNode* rootNode
); );
virtual ~Moon() {} virtual ~Moon() {}
enum Phase enum Phase
{ {
Phase_New = 0, Phase_New = 0,
@ -85,29 +86,29 @@ namespace MWRender
Phase_WaningHalf, Phase_WaningHalf,
Phase_WaningCrescent Phase_WaningCrescent
}; };
enum Type enum Type
{ {
Type_Masser = 0, Type_Masser = 0,
Type_Secunda Type_Secunda
}; };
void setPhase(const Phase& phase); void setPhase(const Phase& phase);
void setType(const Type& type); void setType(const Type& type);
void setSkyColour(const Ogre::ColourValue& colour); void setSkyColour(const Ogre::ColourValue& colour);
Phase getPhase() const; Phase getPhase() const;
unsigned int getPhaseInt() const; unsigned int getPhaseInt() const;
private: private:
Type mType; Type mType;
Phase mPhase; Phase mPhase;
}; };
class SkyManager class SkyManager
{ {
public: public:
SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera, MWWorld::Environment* env); SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera);
~SkyManager(); ~SkyManager();
void update(float duration); void update(float duration);
@ -168,10 +169,13 @@ namespace MWRender
void setGlare(const float glare); void setGlare(const float glare);
Ogre::Vector3 getRealSunPos(); Ogre::Vector3 getRealSunPos();
void setSkyPosition(const Ogre::Vector3& position);
void resetSkyPosition();
void scaleSky(float scale);
private: private:
bool mCreated; bool mCreated;
MWWorld::Environment* mEnvironment;
float mHour; float mHour;
int mDay; int mDay;
int mMonth; int mMonth;
@ -180,21 +184,21 @@ namespace MWRender
BillboardObject* mSunGlare; BillboardObject* mSunGlare;
Moon* mMasser; Moon* mMasser;
Moon* mSecunda; Moon* mSecunda;
Ogre::Viewport* mViewport; Ogre::Viewport* mViewport;
Ogre::SceneNode* mRootNode; Ogre::SceneNode* mRootNode;
Ogre::SceneManager* mSceneMgr; Ogre::SceneManager* mSceneMgr;
Ogre::SceneNode* mAtmosphereDay; Ogre::SceneNode* mAtmosphereDay;
Ogre::SceneNode* mAtmosphereNight; Ogre::SceneNode* mAtmosphereNight;
Ogre::MaterialPtr mCloudMaterial; Ogre::MaterialPtr mCloudMaterial;
Ogre::MaterialPtr mAtmosphereMaterial; Ogre::MaterialPtr mAtmosphereMaterial;
Ogre::MaterialPtr mStarsMaterials[7]; Ogre::MaterialPtr mStarsMaterials[7];
Ogre::HighLevelGpuProgramPtr mCloudFragmentShader; Ogre::HighLevelGpuProgramPtr mCloudFragmentShader;
// remember some settings so we don't have to apply them again if they didnt change // remember some settings so we don't have to apply them again if they didnt change
Ogre::String mClouds; Ogre::String mClouds;
Ogre::String mNextClouds; Ogre::String mNextClouds;
@ -204,17 +208,17 @@ namespace MWRender
float mStarsOpacity; float mStarsOpacity;
Ogre::ColourValue mCloudColour; Ogre::ColourValue mCloudColour;
Ogre::ColourValue mSkyColour; Ogre::ColourValue mSkyColour;
Ogre::Overlay* mThunderOverlay; Ogre::Overlay* mThunderOverlay;
Ogre::TextureUnitState* mThunderTextureUnit; Ogre::TextureUnitState* mThunderTextureUnit;
float mRemainingTransitionTime; float mRemainingTransitionTime;
float mGlare; // target float mGlare; // target
float mGlareFade; // actual float mGlareFade; // actual
void ModVertexAlpha(Ogre::Entity* ent, unsigned int meshType); void ModVertexAlpha(Ogre::Entity* ent, unsigned int meshType);
bool mEnabled; bool mEnabled;
bool mSunEnabled; bool mSunEnabled;
bool mMasserEnabled; bool mMasserEnabled;

@ -4,9 +4,13 @@
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "../mwbase/environment.hpp"
#include "terrainmaterial.hpp" #include "terrainmaterial.hpp"
#include "terrain.hpp" #include "terrain.hpp"
#include "renderconst.hpp"
#include "shadows.hpp"
#include <components/settings/settings.hpp>
using namespace Ogre; using namespace Ogre;
@ -15,8 +19,8 @@ namespace MWRender
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
TerrainManager::TerrainManager(Ogre::SceneManager* mgr, const MWWorld::Environment& evn) : TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) :
mEnvironment(evn), mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)) mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend)
{ {
TerrainMaterialGeneratorPtr matGen; TerrainMaterialGeneratorPtr matGen;
@ -47,9 +51,19 @@ namespace MWRender
mActiveProfile->setLayerSpecularMappingEnabled(false); mActiveProfile->setLayerSpecularMappingEnabled(false);
mActiveProfile->setLayerNormalMappingEnabled(false); mActiveProfile->setLayerNormalMappingEnabled(false);
mActiveProfile->setLayerParallaxMappingEnabled(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 //disabled
mActiveProfile->setCompositeMapEnabled(false); mActiveProfile->setCompositeMapEnabled(false);
@ -95,7 +109,7 @@ namespace MWRender
const int cellX = store->cell->getGridX(); const int cellX = store->cell->getGridX();
const int cellY = store->cell->getGridY(); 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 != NULL )
{ {
if (!land->dataLoaded) if (!land->dataLoaded)
@ -162,6 +176,8 @@ namespace MWRender
x * numTextures, y * numTextures, x * numTextures, y * numTextures,
numTextures, numTextures,
indexes); indexes);
terrain->setVisibilityFlags(RV_Terrain);
terrain->setRenderQueueGroup(RQG_Main);
if ( land && land->landData->usingColours ) if ( land && land->landData->usingColours )
{ {
@ -254,7 +270,7 @@ namespace MWRender
{ {
//NB: All vtex ids are +1 compared to the ltex ids //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"); "LAND.VTEX must be within the bounds of the LTEX array");
std::string texture; std::string texture;
@ -264,7 +280,7 @@ namespace MWRender
} }
else 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 //TODO this is needed due to MWs messed up texture handling
texture = texture.substr(0, texture.rfind(".")) + ".dds"; 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 != NULL )
{ {
if (!land->dataLoaded) if (!land->dataLoaded)

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

Loading…
Cancel
Save