forked from mirror/openmw-tes3mp
Merge branch 'dialogue' of https://github.com/zinnschlag/openmw.git into DialogueSystem
This commit is contained in:
commit
61914a70bd
212 changed files with 4829 additions and 25151 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -7,6 +7,9 @@ Docs/mainpage.hpp
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
*/CMakeFiles
|
*/CMakeFiles
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
|
moc_*.cxx
|
||||||
|
cmake_install.cmake
|
||||||
|
*.[ao]
|
||||||
Makefile
|
Makefile
|
||||||
makefile
|
makefile
|
||||||
data
|
data
|
||||||
|
|
204
CMakeLists.txt
204
CMakeLists.txt
|
@ -1,11 +1,13 @@
|
||||||
project(OpenMW)
|
project(OpenMW)
|
||||||
|
|
||||||
IF (APPLE)
|
if (APPLE)
|
||||||
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/OpenMW.app")
|
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
|
||||||
|
|
||||||
|
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}")
|
||||||
|
|
||||||
# using 10.6 sdk
|
# using 10.6 sdk
|
||||||
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.6.sdk")
|
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.6.sdk")
|
||||||
ENDIF (APPLE)
|
endif (APPLE)
|
||||||
|
|
||||||
# Macros
|
# Macros
|
||||||
|
|
||||||
|
@ -16,8 +18,8 @@ include (OpenMWMacros)
|
||||||
# Version
|
# Version
|
||||||
|
|
||||||
set (OPENMW_VERSION_MAJOR 0)
|
set (OPENMW_VERSION_MAJOR 0)
|
||||||
set (OPENMW_VERSION_MINOR 11)
|
set (OPENMW_VERSION_MINOR 12)
|
||||||
set (OPENMW_VERSION_RELEASE 1)
|
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}")
|
||||||
|
|
||||||
|
@ -94,6 +96,7 @@ source_group(libs\\mangle FILES ${MANGLE_ALL})
|
||||||
set(OENGINE_OGRE
|
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
|
||||||
)
|
)
|
||||||
set(OENGINE_GUI
|
set(OENGINE_GUI
|
||||||
${LIBDIR}/openengine/gui/events.cpp
|
${LIBDIR}/openengine/gui/events.cpp
|
||||||
|
@ -188,9 +191,8 @@ find_package(OpenAL REQUIRED)
|
||||||
find_package(Bullet REQUIRED)
|
find_package(Bullet REQUIRED)
|
||||||
include_directories("."
|
include_directories("."
|
||||||
${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE
|
${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE
|
||||||
${OIS_INCLUDE_DIR} ${Boost_INCLUDE_DIR}
|
${OIS_INCLUDE_DIRS} ${Boost_INCLUDE_DIR}
|
||||||
${PLATFORM_INCLUDE_DIR}
|
${PLATFORM_INCLUDE_DIR}
|
||||||
${CMAKE_HOME_DIRECTORY}/extern/caelum/include
|
|
||||||
${CMAKE_HOME_DIRECTORY}/extern/mygui_3.0.1/MyGUIEngine/include
|
${CMAKE_HOME_DIRECTORY}/extern/mygui_3.0.1/MyGUIEngine/include
|
||||||
${CMAKE_HOME_DIRECTORY}/extern/mygui_3.0.1/OgrePlatform/include
|
${CMAKE_HOME_DIRECTORY}/extern/mygui_3.0.1/OgrePlatform/include
|
||||||
${OPENAL_INCLUDE_DIR}
|
${OPENAL_INCLUDE_DIR}
|
||||||
|
@ -200,7 +202,14 @@ include_directories("."
|
||||||
|
|
||||||
link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR})
|
link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR})
|
||||||
|
|
||||||
add_subdirectory( extern/caelum )
|
if(APPLE)
|
||||||
|
# List used Ogre plugins
|
||||||
|
SET(USED_OGRE_PLUGINS "RenderSystem_GL"
|
||||||
|
"Plugin_OctreeSceneManager"
|
||||||
|
"Plugin_CgProgramManager"
|
||||||
|
"Plugin_ParticleFX")
|
||||||
|
endif(APPLE)
|
||||||
|
|
||||||
add_subdirectory( extern/mygui_3.0.1 )
|
add_subdirectory( extern/mygui_3.0.1 )
|
||||||
|
|
||||||
# Make sure that certain libraries are used as static libraries
|
# Make sure that certain libraries are used as static libraries
|
||||||
|
@ -210,9 +219,6 @@ add_subdirectory( extern/mygui_3.0.1 )
|
||||||
# MyGUI: extern/mygui_3.0.0/
|
# MyGUI: extern/mygui_3.0.0/
|
||||||
add_definitions(-DMYGUI_STATIC)
|
add_definitions(-DMYGUI_STATIC)
|
||||||
|
|
||||||
# Caelum: extern/caelum/
|
|
||||||
add_definitions(-DCAELUM_STATIC)
|
|
||||||
|
|
||||||
# Specify build paths
|
# Specify build paths
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
@ -243,22 +249,17 @@ if (APPLE)
|
||||||
"${OpenMW_BINARY_DIR}/plugins.cfg")
|
"${OpenMW_BINARY_DIR}/plugins.cfg")
|
||||||
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
|
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
|
||||||
"${APP_BUNDLE_DIR}/Contents/Info.plist" COPYONLY)
|
"${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
|
# prepare plugins
|
||||||
configure_file(${OGRE_PLUGIN_DIR}/RenderSystem_GL.dylib
|
foreach(plugin ${USED_OGRE_PLUGINS})
|
||||||
"${APP_BUNDLE_DIR}/Contents/Plugins/RenderSystem_GL.dylib" COPYONLY)
|
configure_file("${OGRE_PLUGIN_DIR}/${plugin}.dylib"
|
||||||
|
"${APP_BUNDLE_DIR}/Contents/Plugins/${plugin}.dylib"
|
||||||
configure_file(${OGRE_PLUGIN_DIR}/Plugin_OctreeSceneManager.dylib
|
COPYONLY)
|
||||||
"${APP_BUNDLE_DIR}/Contents/Plugins/Plugin_OctreeSceneManager.dylib" COPYONLY)
|
endforeach()
|
||||||
|
|
||||||
configure_file(${OGRE_PLUGIN_DIR}/Plugin_ParticleFX.dylib
|
|
||||||
"${APP_BUNDLE_DIR}/Contents/Plugins/Plugin_ParticleFX.dylib" COPYONLY)
|
|
||||||
|
|
||||||
endif (APPLE)
|
endif (APPLE)
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,36 +269,6 @@ if (CMAKE_COMPILER_IS_GNUCC)
|
||||||
add_definitions (-Wall)
|
add_definitions (-Wall)
|
||||||
endif (CMAKE_COMPILER_IS_GNUCC)
|
endif (CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
|
||||||
# Apple bundling
|
|
||||||
# TODO REWRITE!
|
|
||||||
if (APPLE)
|
|
||||||
set(MISC_FILES
|
|
||||||
${APP_BUNDLE_DIR}/Contents/MacOS/openmw.cfg
|
|
||||||
${APP_BUNDLE_DIR}/Contents/MacOS/plugins.cfg)
|
|
||||||
|
|
||||||
set(OGRE_PLUGINS
|
|
||||||
${APP_BUNDLE_DIR}/Contents/Plugins/*)
|
|
||||||
|
|
||||||
install(FILES ${MISC_FILES} DESTINATION ../MacOS)
|
|
||||||
install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Plugins" DESTINATION ..)
|
|
||||||
install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Resources/resources" DESTINATION ../Resources)
|
|
||||||
set(CPACK_GENERATOR "Bundle")
|
|
||||||
set(CPACK_BUNDLE_PLIST "${CMAKE_SOURCE_DIR}/files/mac/Info.plist")
|
|
||||||
set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/files/mac/openmw.icns")
|
|
||||||
set(CPACK_BUNDLE_NAME "OpenMW")
|
|
||||||
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
|
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
|
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
|
||||||
|
|
||||||
include(CPack)
|
|
||||||
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "-arch i386")
|
|
||||||
set(CMAKE_CXX_FLAGS "-arch i386")
|
|
||||||
|
|
||||||
endif (APPLE)
|
|
||||||
|
|
||||||
|
|
||||||
if(DPKG_PROGRAM)
|
if(DPKG_PROGRAM)
|
||||||
SET(CMAKE_INSTALL_PREFIX "/usr")
|
SET(CMAKE_INSTALL_PREFIX "/usr")
|
||||||
|
|
||||||
|
@ -326,7 +297,7 @@ if(DPKG_PROGRAM)
|
||||||
|
|
||||||
SET(CPACK_GENERATOR "DEB")
|
SET(CPACK_GENERATOR "DEB")
|
||||||
SET(CPACK_PACKAGE_NAME "openmw")
|
SET(CPACK_PACKAGE_NAME "openmw")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://openmw.com")
|
SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://openmw.org")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "${PACKAGE_MAINTAINER}")
|
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "${PACKAGE_MAINTAINER}")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "A reimplementation of The Elder Scrolls III: Morrowind
|
SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "A reimplementation of The Elder Scrolls III: Morrowind
|
||||||
|
@ -351,6 +322,54 @@ if(DPKG_PROGRAM)
|
||||||
include(CPack)
|
include(CPack)
|
||||||
endif(DPKG_PROGRAM)
|
endif(DPKG_PROGRAM)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*")
|
||||||
|
INSTALL(FILES ${files} DESTINATION ".")
|
||||||
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg")
|
||||||
|
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
|
||||||
|
|
||||||
|
SET(CPACK_GENERATOR "NSIS")
|
||||||
|
SET(CPACK_PACKAGE_NAME "OpenMW")
|
||||||
|
SET(CPACK_PACKAGE_VENDOR "OpenMW.org")
|
||||||
|
SET(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
|
||||||
|
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
||||||
|
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher")
|
||||||
|
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
|
||||||
|
SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
|
||||||
|
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
|
||||||
|
SET(CPACK_NSIS_DISPLAY_NAME "OpenMW")
|
||||||
|
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
|
||||||
|
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
|
||||||
|
SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
|
||||||
|
|
||||||
|
SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe")
|
||||||
|
if(EXISTS ${VCREDIST32})
|
||||||
|
INSTALL(FILES ${VCREDIST32} DESTINATION "redist")
|
||||||
|
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x86.exe\\\" /q'" )
|
||||||
|
endif(EXISTS ${VCREDIST32})
|
||||||
|
|
||||||
|
SET(VCREDIST64 "${OpenMW_BINARY_DIR}/vcredist_x64.exe")
|
||||||
|
if(EXISTS ${VCREDIST64})
|
||||||
|
INSTALL(FILES ${VCREDIST64} DESTINATION "redist")
|
||||||
|
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x64.exe\\\" /q'" )
|
||||||
|
endif(EXISTS ${VCREDIST64})
|
||||||
|
|
||||||
|
SET(OALREDIST "${OpenMW_BINARY_DIR}/oalinst.exe")
|
||||||
|
if(EXISTS ${OALREDIST})
|
||||||
|
INSTALL(FILES ${OALREDIST} DESTINATION "redist")
|
||||||
|
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}
|
||||||
|
ExecWait '\\\"$INSTDIR\\\\redist\\\\oalinst.exe\\\" /s'" )
|
||||||
|
endif(EXISTS ${OALREDIST})
|
||||||
|
|
||||||
|
if(CMAKE_CL_64)
|
||||||
|
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(CPack)
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
# Components
|
# Components
|
||||||
add_subdirectory (components)
|
add_subdirectory (components)
|
||||||
|
|
||||||
|
@ -405,3 +424,82 @@ if (WIN32)
|
||||||
#set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
#set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
||||||
#set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
|
#set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Apple bundling
|
||||||
|
if (APPLE)
|
||||||
|
set(INSTALL_SUBDIR OpenMW)
|
||||||
|
|
||||||
|
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
|
||||||
|
install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
set(CPACK_GENERATOR "DragNDrop")
|
||||||
|
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
||||||
|
set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
|
||||||
|
set(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
|
||||||
|
set(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
||||||
|
|
||||||
|
set(APPS "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}")
|
||||||
|
set(PLUGINS "")
|
||||||
|
|
||||||
|
# Scan Plugins dir for *.dylibs
|
||||||
|
set(PLUGIN_SEARCH_ROOT "${APP_BUNDLE_DIR}/Contents/Plugins")
|
||||||
|
file(GLOB_RECURSE ALL_PLUGINS "${PLUGIN_SEARCH_ROOT}/*.dylib")
|
||||||
|
|
||||||
|
set(PLUGIN_INSTALL_BASE "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins")
|
||||||
|
foreach(PLUGIN ${ALL_PLUGINS})
|
||||||
|
string(REPLACE "${PLUGIN_SEARCH_ROOT}/" "" PLUGIN_RELATIVE "${PLUGIN}")
|
||||||
|
set(PLUGINS ${PLUGINS} "${PLUGIN_INSTALL_BASE}/${PLUGIN_RELATIVE}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
#For now, search unresolved dependencies only in default system paths, so if you put unresolveable (i.e. with @executable_path in id name) lib or framework somewhere else, it would fail
|
||||||
|
set(DIRS "")
|
||||||
|
|
||||||
|
# Overriding item resolving during installation, it needed if
|
||||||
|
# some library already has be "fixed up", i.e. its id name contains @executable_path,
|
||||||
|
# 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 limitations:
|
||||||
|
# 1. Handles only frameworks, not simple libs
|
||||||
|
INSTALL(CODE "
|
||||||
|
set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES})
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||||
|
set(CMAKE_SYSTEM_FRAMEWORK_PATH ${CMAKE_SYSTEM_FRAMEWORK_PATH})
|
||||||
|
|
||||||
|
set(OPENMW_RESOLVED_ITEMS \"\")
|
||||||
|
|
||||||
|
function(gp_resolve_item_override context item exepath dirs resolved_item_var resolved_var)
|
||||||
|
if(item MATCHES \"@executable_path\" AND NOT \${\${resolved_var}})
|
||||||
|
if (item MATCHES \"Frameworks\") # if it is a framework
|
||||||
|
# get last segment of path
|
||||||
|
get_filename_component(fname \"\${item}\" NAME_WE)
|
||||||
|
find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} /Library/Frameworks)
|
||||||
|
if (ri)
|
||||||
|
message(STATUS \"found \${ri} for \${item}\")
|
||||||
|
string(REGEX REPLACE \"^.*/Frameworks/.*\\\\.framework\" \"\" item_part \${item})
|
||||||
|
set(ri \"\${ri}\${item_part}\")
|
||||||
|
set(\${resolved_item_var} \${ri} PARENT_SCOPE)
|
||||||
|
set(\${resolved_var} 1 PARENT_SCOPE)
|
||||||
|
set(OPENMW_RESOLVED_ITEMS \${_OPENMW_RESOLVED_ITEMS} \${ri})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# code path for standard (non-framework) libs (ogre & qt pugins)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction(gp_resolve_item_override)
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0009 OLD)
|
||||||
|
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||||
|
include(BundleUtilities)
|
||||||
|
fixup_bundle(\"${APPS}\" \"${PLUGINS}\" \"${DIRS}\")
|
||||||
|
" COMPONENT Runtime)
|
||||||
|
|
||||||
|
include(CPack)
|
||||||
|
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "-arch i386")
|
||||||
|
set(CMAKE_CXX_FLAGS "-arch i386")
|
||||||
|
|
||||||
|
endif (APPLE)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
set(ESMTOOL
|
set(ESMTOOL
|
||||||
esmtool_cmd.c
|
|
||||||
esmtool_cmd.h
|
|
||||||
esmtool.cpp
|
esmtool.cpp
|
||||||
)
|
)
|
||||||
source_group(apps\\esmtool FILES ${ESMTOOL})
|
source_group(apps\\esmtool FILES ${ESMTOOL})
|
||||||
|
|
|
@ -1,35 +1,138 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
#include <components/esm/esm_reader.hpp>
|
#include <components/esm/esm_reader.hpp>
|
||||||
#include <components/esm/records.hpp>
|
#include <components/esm/records.hpp>
|
||||||
|
|
||||||
#include "esmtool_cmd.h"
|
#define ESMTOOL_VERSION 1.1
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ESM;
|
using namespace ESM;
|
||||||
|
|
||||||
|
// Create a local alias for brevity
|
||||||
|
namespace bpo = boost::program_options;
|
||||||
|
|
||||||
void printRaw(ESMReader &esm);
|
void printRaw(ESMReader &esm);
|
||||||
void loadCell(Cell &cell, ESMReader &esm, bool quiet);
|
void loadCell(Cell &cell, ESMReader &esm, bool quiet);
|
||||||
|
|
||||||
int main(int argc, char**argv)
|
// Based on the legacy struct
|
||||||
|
struct Arguments
|
||||||
{
|
{
|
||||||
gengetopt_args_info info;
|
unsigned int raw_given;
|
||||||
|
unsigned int quiet_given;
|
||||||
|
unsigned int loadcells_given;
|
||||||
|
std::string encoding;
|
||||||
|
std::string filename;
|
||||||
|
};
|
||||||
|
|
||||||
if(cmdline_parser(argc, argv, &info) != 0)
|
bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
return 1;
|
{
|
||||||
|
bpo::options_description desc("Inspect and extract from Morrowind ES files (ESM, ESP, ESS)\nSyntax: esmtool [options] file \nAllowed options");
|
||||||
|
|
||||||
if(info.inputs_num != 1)
|
desc.add_options()
|
||||||
|
("help,h", "print help message.")
|
||||||
|
("version,v", "print version information and quit.")
|
||||||
|
("raw,r", "Show an unformattet list of all records and subrecords.")
|
||||||
|
("quiet,q", "Supress all record information. Useful for speed tests.")
|
||||||
|
("loadcells,C", "Browse through contents of all cells.")
|
||||||
|
|
||||||
|
( "encoding,e", bpo::value<std::string>(&(info.encoding))->
|
||||||
|
default_value("win1252"),
|
||||||
|
"Character encoding used in ESMTool:\n"
|
||||||
|
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
|
||||||
|
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
|
||||||
|
"\n\twin1252 - Western European (Latin) alphabet, used by default")
|
||||||
|
;
|
||||||
|
|
||||||
|
std::string finalText = "\nIf no option is given, the default action is to parse all records in the archive\nand display diagnostic information.";
|
||||||
|
|
||||||
|
// input-file is hidden and used as a positional argument
|
||||||
|
bpo::options_description hidden("Hidden Options");
|
||||||
|
|
||||||
|
hidden.add_options()
|
||||||
|
( "input-file,i", bpo::value< vector<std::string> >(), "input file")
|
||||||
|
;
|
||||||
|
|
||||||
|
bpo::positional_options_description p;
|
||||||
|
p.add("input-file", -1);
|
||||||
|
|
||||||
|
// there might be a better way to do this
|
||||||
|
bpo::options_description all;
|
||||||
|
all.add(desc).add(hidden);
|
||||||
|
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv)
|
||||||
|
.options(all).positional(p).run();
|
||||||
|
|
||||||
|
bpo::variables_map variables;
|
||||||
|
bpo::store(valid_opts, variables);
|
||||||
|
bpo::notify(variables);
|
||||||
|
|
||||||
|
if (variables.count ("help"))
|
||||||
{
|
{
|
||||||
if(info.inputs_num == 0)
|
std::cout << desc << finalText << std::endl;
|
||||||
cout << "ERROR: missing ES file\n\n";
|
return false;
|
||||||
else
|
}
|
||||||
cout << "ERROR: more than one ES file specified\n\n";
|
if (variables.count ("version"))
|
||||||
cmdline_parser_print_help();
|
{
|
||||||
return 1;
|
std::cout << "ESMTool version " << ESMTOOL_VERSION << std::endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !variables.count("input-file") )
|
||||||
|
{
|
||||||
|
std::cout << "\nERROR: missing ES file\n\n";
|
||||||
|
std::cout << desc << finalText << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handling gracefully the user adding multiple files
|
||||||
|
if (variables["input-file"].as< vector<std::string> >().size() > 1)
|
||||||
|
{
|
||||||
|
std::cout << "\nERROR: more than one ES file specified\n\n";
|
||||||
|
std::cout << desc << finalText << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.filename = variables["input-file"].as< vector<std::string> >()[0];
|
||||||
|
|
||||||
|
info.raw_given = variables.count ("raw");
|
||||||
|
info.quiet_given = variables.count ("quiet");
|
||||||
|
info.loadcells_given = variables.count ("loadcells");
|
||||||
|
|
||||||
|
// Font encoding settings
|
||||||
|
info.encoding = variables["encoding"].as<std::string>();
|
||||||
|
if (info.encoding == "win1250")
|
||||||
|
{
|
||||||
|
std::cout << "Using Central and Eastern European font encoding." << std::endl;
|
||||||
|
}
|
||||||
|
else if (info.encoding == "win1251")
|
||||||
|
{
|
||||||
|
std::cout << "Using Cyrillic font encoding." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(info.encoding != "win1252")
|
||||||
|
{
|
||||||
|
std::cout << info.encoding << " is not a valid encoding option." << std::endl;
|
||||||
|
info.encoding = "win1252";
|
||||||
|
}
|
||||||
|
std::cout << "Using default (English) font encoding." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char**argv)
|
||||||
|
{
|
||||||
|
Arguments info;
|
||||||
|
if(!parseOptions (argc, argv, info))
|
||||||
|
return 1;
|
||||||
|
|
||||||
ESMReader esm;
|
ESMReader esm;
|
||||||
const char* filename = info.inputs[0];
|
esm.setEncoding(info.encoding);
|
||||||
|
|
||||||
|
string filename = info.filename;
|
||||||
cout << "\nFile: " << filename << endl;
|
cout << "\nFile: " << filename << endl;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package "esmtool"
|
|
||||||
version "1.0"
|
|
||||||
purpose "Inspect and extract from Morrowind ES files (ESM, ESP, ESS)"
|
|
||||||
args "--unamed-opts=ES-FILE -F esmtool_cmd -G"
|
|
||||||
|
|
||||||
option "raw" r "Show an unformattet list of all records and subrecords" optional
|
|
||||||
option "quiet" q "Supress all record information. Useful for speed tests." optional
|
|
||||||
option "loadcells" C "Browse through contents of all cells." optional
|
|
||||||
|
|
||||||
text "\nIf no option is given, the default action is to parse all records in the archive and display diagnostic information."
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,179 +0,0 @@
|
||||||
/** @file esmtool_cmd.h
|
|
||||||
* @brief The header file for the command line option parser
|
|
||||||
* generated by GNU Gengetopt version 2.22.2
|
|
||||||
* http://www.gnu.org/software/gengetopt.
|
|
||||||
* DO NOT modify this file, since it can be overwritten
|
|
||||||
* @author GNU Gengetopt by Lorenzo Bettini */
|
|
||||||
|
|
||||||
#ifndef ESMTOOL_CMD_H
|
|
||||||
#define ESMTOOL_CMD_H
|
|
||||||
|
|
||||||
/* If we use autoconf. */
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h> /* for FILE */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#ifndef CMDLINE_PARSER_PACKAGE
|
|
||||||
/** @brief the program name (used for printing errors) */
|
|
||||||
#define CMDLINE_PARSER_PACKAGE "esmtool"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CMDLINE_PARSER_PACKAGE_NAME
|
|
||||||
/** @brief the complete program name (used for help and version) */
|
|
||||||
#define CMDLINE_PARSER_PACKAGE_NAME "esmtool"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CMDLINE_PARSER_VERSION
|
|
||||||
/** @brief the program version */
|
|
||||||
#define CMDLINE_PARSER_VERSION "1.0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @brief Where the command line options are stored */
|
|
||||||
struct gengetopt_args_info
|
|
||||||
{
|
|
||||||
const char *help_help; /**< @brief Print help and exit help description. */
|
|
||||||
const char *version_help; /**< @brief Print version and exit help description. */
|
|
||||||
const char *raw_help; /**< @brief Show an unformattet list of all records and subrecords help description. */
|
|
||||||
const char *quiet_help; /**< @brief Supress all record information. Useful for speed tests. help description. */
|
|
||||||
const char *loadcells_help; /**< @brief Browse through contents of all cells. help description. */
|
|
||||||
|
|
||||||
unsigned int help_given ; /**< @brief Whether help was given. */
|
|
||||||
unsigned int version_given ; /**< @brief Whether version was given. */
|
|
||||||
unsigned int raw_given ; /**< @brief Whether raw was given. */
|
|
||||||
unsigned int quiet_given ; /**< @brief Whether quiet was given. */
|
|
||||||
unsigned int loadcells_given ; /**< @brief Whether loadcells was given. */
|
|
||||||
|
|
||||||
char **inputs ; /**< @brief unamed options (options without names) */
|
|
||||||
unsigned inputs_num ; /**< @brief unamed options number */
|
|
||||||
} ;
|
|
||||||
|
|
||||||
/** @brief The additional parameters to pass to parser functions */
|
|
||||||
struct cmdline_parser_params
|
|
||||||
{
|
|
||||||
int override; /**< @brief whether to override possibly already present options (default 0) */
|
|
||||||
int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */
|
|
||||||
int check_required; /**< @brief whether to check that all required options were provided (default 1) */
|
|
||||||
int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */
|
|
||||||
int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */
|
|
||||||
} ;
|
|
||||||
|
|
||||||
/** @brief the purpose string of the program */
|
|
||||||
extern const char *gengetopt_args_info_purpose;
|
|
||||||
/** @brief the usage string of the program */
|
|
||||||
extern const char *gengetopt_args_info_usage;
|
|
||||||
/** @brief all the lines making the help output */
|
|
||||||
extern const char *gengetopt_args_info_help[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The command line parser
|
|
||||||
* @param argc the number of command line options
|
|
||||||
* @param argv the command line options
|
|
||||||
* @param args_info the structure where option information will be stored
|
|
||||||
* @return 0 if everything went fine, NON 0 if an error took place
|
|
||||||
*/
|
|
||||||
int cmdline_parser (int argc, char * const *argv,
|
|
||||||
struct gengetopt_args_info *args_info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The command line parser (version with additional parameters - deprecated)
|
|
||||||
* @param argc the number of command line options
|
|
||||||
* @param argv the command line options
|
|
||||||
* @param args_info the structure where option information will be stored
|
|
||||||
* @param override whether to override possibly already present options
|
|
||||||
* @param initialize whether to initialize the option structure my_args_info
|
|
||||||
* @param check_required whether to check that all required options were provided
|
|
||||||
* @return 0 if everything went fine, NON 0 if an error took place
|
|
||||||
* @deprecated use cmdline_parser_ext() instead
|
|
||||||
*/
|
|
||||||
int cmdline_parser2 (int argc, char * const *argv,
|
|
||||||
struct gengetopt_args_info *args_info,
|
|
||||||
int override, int initialize, int check_required);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The command line parser (version with additional parameters)
|
|
||||||
* @param argc the number of command line options
|
|
||||||
* @param argv the command line options
|
|
||||||
* @param args_info the structure where option information will be stored
|
|
||||||
* @param params additional parameters for the parser
|
|
||||||
* @return 0 if everything went fine, NON 0 if an error took place
|
|
||||||
*/
|
|
||||||
int cmdline_parser_ext (int argc, char * const *argv,
|
|
||||||
struct gengetopt_args_info *args_info,
|
|
||||||
struct cmdline_parser_params *params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save the contents of the option struct into an already open FILE stream.
|
|
||||||
* @param outfile the stream where to dump options
|
|
||||||
* @param args_info the option struct to dump
|
|
||||||
* @return 0 if everything went fine, NON 0 if an error took place
|
|
||||||
*/
|
|
||||||
int cmdline_parser_dump(FILE *outfile,
|
|
||||||
struct gengetopt_args_info *args_info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save the contents of the option struct into a (text) file.
|
|
||||||
* This file can be read by the config file parser (if generated by gengetopt)
|
|
||||||
* @param filename the file where to save
|
|
||||||
* @param args_info the option struct to save
|
|
||||||
* @return 0 if everything went fine, NON 0 if an error took place
|
|
||||||
*/
|
|
||||||
int cmdline_parser_file_save(const char *filename,
|
|
||||||
struct gengetopt_args_info *args_info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the help
|
|
||||||
*/
|
|
||||||
void cmdline_parser_print_help(void);
|
|
||||||
/**
|
|
||||||
* Print the version
|
|
||||||
*/
|
|
||||||
void cmdline_parser_print_version(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes all the fields a cmdline_parser_params structure
|
|
||||||
* to their default values
|
|
||||||
* @param params the structure to initialize
|
|
||||||
*/
|
|
||||||
void cmdline_parser_params_init(struct cmdline_parser_params *params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocates dynamically a cmdline_parser_params structure and initializes
|
|
||||||
* all its fields to their default values
|
|
||||||
* @return the created and initialized cmdline_parser_params structure
|
|
||||||
*/
|
|
||||||
struct cmdline_parser_params *cmdline_parser_params_create(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the passed gengetopt_args_info structure's fields
|
|
||||||
* (also set default values for options that have a default)
|
|
||||||
* @param args_info the structure to initialize
|
|
||||||
*/
|
|
||||||
void cmdline_parser_init (struct gengetopt_args_info *args_info);
|
|
||||||
/**
|
|
||||||
* Deallocates the string fields of the gengetopt_args_info structure
|
|
||||||
* (but does not deallocate the structure itself)
|
|
||||||
* @param args_info the structure to deallocate
|
|
||||||
*/
|
|
||||||
void cmdline_parser_free (struct gengetopt_args_info *args_info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks that all the required options were specified
|
|
||||||
* @param args_info the structure to check
|
|
||||||
* @param prog_name the name of the program that will be used to print
|
|
||||||
* possible errors
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int cmdline_parser_required (struct gengetopt_args_info *args_info,
|
|
||||||
const char *prog_name);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* ESMTOOL_CMD_H */
|
|
|
@ -41,8 +41,10 @@ source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC
|
||||||
find_package(Qt4 REQUIRED)
|
find_package(Qt4 REQUIRED)
|
||||||
set(QT_USE_QTGUI 1)
|
set(QT_USE_QTGUI 1)
|
||||||
|
|
||||||
find_package(PNG REQUIRED)
|
if (NOT APPLE) # this dependency can be completely removed, but now it only tested on OS X
|
||||||
include_directories(${PNG_INCLUDE_DIR})
|
find_package(PNG REQUIRED)
|
||||||
|
include_directories(${PNG_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
QT4_ADD_RESOURCES(RCC_SRCS resources.qrc)
|
QT4_ADD_RESOURCES(RCC_SRCS resources.qrc)
|
||||||
QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
|
QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
|
||||||
|
@ -71,9 +73,13 @@ endif()
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
|
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
|
||||||
"${APP_BUNDLE_DIR}/../launcher.qss")
|
"${APP_BUNDLE_DIR}/../launcher.qss")
|
||||||
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
|
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.cfg
|
||||||
"${APP_BUNDLE_DIR}/../launcher.cfg")
|
"${APP_BUNDLE_DIR}/../launcher.cfg")
|
||||||
else()
|
else()
|
||||||
|
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
|
||||||
|
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/resources/launcher.qss")
|
||||||
|
|
||||||
|
# Fallback in case getGlobalDataPath does not point to resources
|
||||||
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
|
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
|
||||||
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.qss")
|
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.qss")
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <components/esm/esm_reader.hpp>
|
#include <components/esm/esm_reader.hpp>
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
#include <components/files/multidircollection.hpp>
|
#include <components/files/multidircollection.hpp>
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include "datafilespage.hpp"
|
#include "datafilespage.hpp"
|
||||||
#include "lineedit.hpp"
|
#include "lineedit.hpp"
|
||||||
|
@ -26,7 +26,9 @@ bool rowSmallerThan(const QModelIndex &index1, const QModelIndex &index2)
|
||||||
return index1.row() <= index2.row();
|
return index1.row() <= index2.row();
|
||||||
}
|
}
|
||||||
|
|
||||||
DataFilesPage::DataFilesPage(QWidget *parent) : QWidget(parent)
|
DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, mCfgMgr(cfg)
|
||||||
{
|
{
|
||||||
mDataFilesModel = new QStandardItemModel(); // Contains all plugins with masters
|
mDataFilesModel = new QStandardItemModel(); // Contains all plugins with masters
|
||||||
mPluginsModel = new PluginsModel(); // Contains selectable plugins
|
mPluginsModel = new PluginsModel(); // Contains selectable plugins
|
||||||
|
@ -121,23 +123,88 @@ DataFilesPage::DataFilesPage(QWidget *parent) : QWidget(parent)
|
||||||
|
|
||||||
|
|
||||||
setupConfig();
|
setupConfig();
|
||||||
|
setupDataFiles();
|
||||||
createActions();
|
createActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesPage::setupDataFiles(const QStringList &paths, bool strict)
|
void DataFilesPage::setupConfig()
|
||||||
{
|
{
|
||||||
// Put the paths in a boost::filesystem vector to use with Files::Collections
|
QString config = QString::fromStdString((mCfgMgr.getLocalPath() / "launcher.cfg").string());
|
||||||
Files::PathContainer dataDirs;
|
QFile file(config);
|
||||||
|
|
||||||
foreach (const QString ¤tPath, paths) {
|
if (!file.exists()) {
|
||||||
dataDirs.push_back(boost::filesystem::path(currentPath.toStdString()));
|
config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open our config file
|
||||||
|
mLauncherConfig = new QSettings(config, QSettings::IniFormat);
|
||||||
|
mLauncherConfig->sync();
|
||||||
|
|
||||||
|
|
||||||
|
// Make sure we have no groups open
|
||||||
|
while (!mLauncherConfig->group().isEmpty()) {
|
||||||
|
mLauncherConfig->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
mLauncherConfig->beginGroup("Profiles");
|
||||||
|
QStringList profiles = mLauncherConfig->childGroups();
|
||||||
|
|
||||||
|
if (profiles.isEmpty()) {
|
||||||
|
// Add a default profile
|
||||||
|
profiles.append("Default");
|
||||||
|
}
|
||||||
|
|
||||||
|
mProfilesComboBox->addItems(profiles);
|
||||||
|
|
||||||
|
QString currentProfile = mLauncherConfig->value("CurrentProfile").toString();
|
||||||
|
|
||||||
|
if (currentProfile.isEmpty()) {
|
||||||
|
// No current profile selected
|
||||||
|
currentProfile = "Default";
|
||||||
|
}
|
||||||
|
mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(currentProfile));
|
||||||
|
|
||||||
|
mLauncherConfig->endGroup();
|
||||||
|
|
||||||
|
// Now we connect the combobox to do something if the profile changes
|
||||||
|
// This prevents strange behaviour while reading and appending the profiles
|
||||||
|
connect(mProfilesComboBox, SIGNAL(textChanged(const QString&, const QString&)), this, SLOT(profileChanged(const QString&, const QString&)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DataFilesPage::setupDataFiles()
|
||||||
|
{
|
||||||
|
// We use the Configuration Manager to retrieve the configuration values
|
||||||
|
boost::program_options::variables_map variables;
|
||||||
|
boost::program_options::options_description desc;
|
||||||
|
|
||||||
|
desc.add_options()
|
||||||
|
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken())
|
||||||
|
// ("data-local", boost::program_options::value<std::string>()->default_value(""))
|
||||||
|
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
||||||
|
("encoding", boost::program_options::value<std::string>()->default_value("win1252"));
|
||||||
|
|
||||||
|
mCfgMgr.readConfiguration(variables, desc);
|
||||||
|
|
||||||
|
// Put the paths in a boost::filesystem vector to use with Files::Collections
|
||||||
|
Files::PathContainer dataDirs(variables["data"].as<Files::PathContainer>());
|
||||||
|
|
||||||
|
// std::string local(variables["data-local"].as<std::string>());
|
||||||
|
// if (!local.empty())
|
||||||
|
// {
|
||||||
|
// dataDirs.push_back(Files::PathContainer::value_type(local));
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (dataDirs.size()>1)
|
||||||
|
dataDirs.resize (1);
|
||||||
|
|
||||||
|
mCfgMgr.processPaths(dataDirs);
|
||||||
|
|
||||||
// Create a file collection for the dataDirs
|
// Create a file collection for the dataDirs
|
||||||
Files::Collections mFileCollections(dataDirs, strict);
|
Files::Collections fileCollections(dataDirs, !variables["fs-strict"].as<bool>());
|
||||||
|
|
||||||
// First we add all the master files
|
// First we add all the master files
|
||||||
const Files::MultiDirCollection &esm = mFileCollections.getCollection(".esm");
|
const Files::MultiDirCollection &esm = fileCollections.getCollection(".esm");
|
||||||
unsigned int i = 0; // Row number
|
unsigned int i = 0; // Row number
|
||||||
|
|
||||||
for (Files::MultiDirCollection::TIter iter(esm.begin()); iter!=esm.end(); ++iter)
|
for (Files::MultiDirCollection::TIter iter(esm.begin()); iter!=esm.end(); ++iter)
|
||||||
|
@ -157,14 +224,14 @@ void DataFilesPage::setupDataFiles(const QStringList &paths, bool strict)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now on to the plugins
|
// Now on to the plugins
|
||||||
const Files::MultiDirCollection &esp = mFileCollections.getCollection(".esp");
|
const Files::MultiDirCollection &esp = fileCollections.getCollection(".esp");
|
||||||
|
|
||||||
for (Files::MultiDirCollection::TIter iter(esp.begin()); iter!=esp.end(); ++iter)
|
for (Files::MultiDirCollection::TIter iter(esp.begin()); iter!=esp.end(); ++iter)
|
||||||
{
|
{
|
||||||
ESMReader fileReader;
|
ESMReader fileReader;
|
||||||
QStringList availableMasters; // Will contain all found masters
|
QStringList availableMasters; // Will contain all found masters
|
||||||
|
|
||||||
fileReader.setEncoding("win1252"); // FIXME: This should be configurable!
|
fileReader.setEncoding(variables["encoding"].as<std::string>());
|
||||||
fileReader.open(iter->second.string());
|
fileReader.open(iter->second.string());
|
||||||
|
|
||||||
// First we fill the availableMasters and the mMastersWidget
|
// First we fill the availableMasters and the mMastersWidget
|
||||||
|
@ -234,54 +301,6 @@ void DataFilesPage::setupDataFiles(const QStringList &paths, bool strict)
|
||||||
readConfig();
|
readConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesPage::setupConfig()
|
|
||||||
{
|
|
||||||
Cfg::ConfigurationManager cfg;
|
|
||||||
|
|
||||||
QString config = (cfg.getRuntimeConfigPath() / "launcher.cfg").string().c_str();
|
|
||||||
QFile file(config);
|
|
||||||
|
|
||||||
if (!file.exists()) {
|
|
||||||
config = QString::fromStdString((cfg.getLocalConfigPath() / "launcher.cfg").string());
|
|
||||||
}
|
|
||||||
|
|
||||||
file.setFileName(config); // Just for displaying information
|
|
||||||
|
|
||||||
// Open our config file
|
|
||||||
mLauncherConfig = new QSettings(config, QSettings::IniFormat);
|
|
||||||
mLauncherConfig->sync();
|
|
||||||
|
|
||||||
|
|
||||||
// Make sure we have no groups open
|
|
||||||
while (!mLauncherConfig->group().isEmpty()) {
|
|
||||||
mLauncherConfig->endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
mLauncherConfig->beginGroup("Profiles");
|
|
||||||
QStringList profiles = mLauncherConfig->childGroups();
|
|
||||||
|
|
||||||
if (profiles.isEmpty()) {
|
|
||||||
// Add a default profile
|
|
||||||
profiles.append("Default");
|
|
||||||
}
|
|
||||||
|
|
||||||
mProfilesComboBox->addItems(profiles);
|
|
||||||
|
|
||||||
QString currentProfile = mLauncherConfig->value("CurrentProfile").toString();
|
|
||||||
|
|
||||||
if (currentProfile.isEmpty()) {
|
|
||||||
// No current profile selected
|
|
||||||
currentProfile = "Default";
|
|
||||||
}
|
|
||||||
mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(currentProfile));
|
|
||||||
|
|
||||||
mLauncherConfig->endGroup();
|
|
||||||
|
|
||||||
// Now we connect the combobox to do something if the profile changes
|
|
||||||
// This prevents strange behaviour while reading and appending the profiles
|
|
||||||
connect(mProfilesComboBox, SIGNAL(textChanged(const QString&, const QString&)), this, SLOT(profileChanged(const QString&, const QString&)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesPage::createActions()
|
void DataFilesPage::createActions()
|
||||||
{
|
{
|
||||||
// Refresh the plugins
|
// Refresh the plugins
|
||||||
|
@ -968,8 +987,8 @@ void DataFilesPage::readConfig()
|
||||||
|
|
||||||
void DataFilesPage::writeConfig(QString profile)
|
void DataFilesPage::writeConfig(QString profile)
|
||||||
{
|
{
|
||||||
// Don't overwrite the config if no plugins are found
|
// Don't overwrite the config if no masters are found
|
||||||
if (mPluginsModel->rowCount() < 1) {
|
if (mMastersWidget->rowCount() < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,6 +1000,61 @@ void DataFilesPage::writeConfig(QString profile)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare the OpenMW config
|
||||||
|
QString config = QString::fromStdString((mCfgMgr.getLocalPath() / "openmw.cfg").string());
|
||||||
|
QFile file(config);
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
config = QString::fromStdString((mCfgMgr.getUserPath() / "openmw.cfg").string());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the config as a QFile
|
||||||
|
file.setFileName(config);
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||||
|
// File cannot be opened or created
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle("Error writing OpenMW configuration file");
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(tr("<br><b>Could not open or create %0</b><br><br> \
|
||||||
|
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
||||||
|
msgBox.exec();
|
||||||
|
|
||||||
|
qApp->exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextStream in(&file);
|
||||||
|
QByteArray buffer;
|
||||||
|
|
||||||
|
// Remove all previous master/plugin entries from config
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
QString line = in.readLine();
|
||||||
|
if (!line.contains("master") && !line.contains("plugin")) {
|
||||||
|
buffer += line += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// Now we write back the other config entries
|
||||||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle("Error writing OpenMW configuration file");
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(tr("<br><b>Could not write to %0</b><br><br> \
|
||||||
|
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
||||||
|
msgBox.exec();
|
||||||
|
|
||||||
|
qApp->exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.write(buffer);
|
||||||
|
QTextStream gameConfig(&file);
|
||||||
|
|
||||||
// Make sure we have no groups open
|
// Make sure we have no groups open
|
||||||
while (!mLauncherConfig->group().isEmpty()) {
|
while (!mLauncherConfig->group().isEmpty()) {
|
||||||
mLauncherConfig->endGroup();
|
mLauncherConfig->endGroup();
|
||||||
|
@ -993,13 +1067,16 @@ void DataFilesPage::writeConfig(QString profile)
|
||||||
mLauncherConfig->beginGroup(profile);
|
mLauncherConfig->beginGroup(profile);
|
||||||
mLauncherConfig->remove(""); // Clear the subgroup
|
mLauncherConfig->remove(""); // Clear the subgroup
|
||||||
|
|
||||||
// First write the masters to the config
|
// First write the masters to the configs
|
||||||
const QStringList masterList = selectedMasters();
|
const QStringList masters = selectedMasters();
|
||||||
|
|
||||||
// We don't use foreach because we need i
|
// We don't use foreach because we need i
|
||||||
for (int i = 0; i < masterList.size(); ++i) {
|
for (int i = 0; i < masters.size(); ++i) {
|
||||||
const QString master = masterList.at(i);
|
const QString currentMaster = masters.at(i);
|
||||||
mLauncherConfig->setValue(QString("Master%0").arg(i), master);
|
|
||||||
|
mLauncherConfig->setValue(QString("Master%0").arg(i), currentMaster);
|
||||||
|
gameConfig << "master=" << currentMaster << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now write all checked plugins
|
// Now write all checked plugins
|
||||||
|
@ -1007,10 +1084,13 @@ void DataFilesPage::writeConfig(QString profile)
|
||||||
|
|
||||||
for (int i = 0; i < plugins.size(); ++i)
|
for (int i = 0; i < plugins.size(); ++i)
|
||||||
{
|
{
|
||||||
mLauncherConfig->setValue(QString("Plugin%1").arg(i), plugins.at(i));
|
const QString currentPlugin = plugins.at(i);
|
||||||
|
mLauncherConfig->setValue(QString("Plugin%1").arg(i), currentPlugin);
|
||||||
|
gameConfig << "plugin=" << currentPlugin << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
mLauncherConfig->endGroup();
|
mLauncherConfig->endGroup();
|
||||||
mLauncherConfig->endGroup();
|
mLauncherConfig->endGroup();
|
||||||
|
mLauncherConfig->sync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,24 +19,19 @@ class PluginsModel;
|
||||||
class PluginsView;
|
class PluginsView;
|
||||||
class ComboBox;
|
class ComboBox;
|
||||||
|
|
||||||
|
namespace Files { struct ConfigurationManager; }
|
||||||
|
|
||||||
class DataFilesPage : public QWidget
|
class DataFilesPage : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DataFilesPage(QWidget *parent = 0);
|
DataFilesPage(Files::ConfigurationManager& cfg, QWidget *parent = 0);
|
||||||
|
|
||||||
ComboBox *mProfilesComboBox;
|
ComboBox *mProfilesComboBox;
|
||||||
QSettings *mLauncherConfig;
|
|
||||||
|
|
||||||
const QStringList checkedPlugins();
|
|
||||||
const QStringList selectedMasters();
|
|
||||||
void setupConfig();
|
|
||||||
void readConfig();
|
|
||||||
void writeConfig(QString profile = QString());
|
void writeConfig(QString profile = QString());
|
||||||
|
|
||||||
void setupDataFiles(const QStringList &paths, bool strict);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void masterSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
void masterSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
||||||
void setCheckState(QModelIndex index);
|
void setCheckState(QModelIndex index);
|
||||||
|
@ -81,11 +76,20 @@ private:
|
||||||
QAction *mCheckAction;
|
QAction *mCheckAction;
|
||||||
QAction *mUncheckAction;
|
QAction *mUncheckAction;
|
||||||
|
|
||||||
|
Files::ConfigurationManager &mCfgMgr;
|
||||||
|
|
||||||
|
QSettings *mLauncherConfig;
|
||||||
|
|
||||||
|
const QStringList checkedPlugins();
|
||||||
|
const QStringList selectedMasters();
|
||||||
|
|
||||||
void addPlugins(const QModelIndex &index);
|
void addPlugins(const QModelIndex &index);
|
||||||
void removePlugins(const QModelIndex &index);
|
void removePlugins(const QModelIndex &index);
|
||||||
void uncheckPlugins();
|
void uncheckPlugins();
|
||||||
void createActions();
|
void createActions();
|
||||||
|
void setupDataFiles();
|
||||||
|
void setupConfig();
|
||||||
|
void readConfig();
|
||||||
void scrollToSelection();
|
void scrollToSelection();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
|
||||||
#include "graphicspage.hpp"
|
#include "graphicspage.hpp"
|
||||||
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
GraphicsPage::GraphicsPage(QWidget *parent) : QWidget(parent)
|
GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, mCfgMgr(cfg)
|
||||||
{
|
{
|
||||||
QGroupBox *rendererGroup = new QGroupBox(tr("Renderer"), this);
|
QGroupBox *rendererGroup = new QGroupBox(tr("Renderer"), this);
|
||||||
|
|
||||||
|
@ -147,21 +150,21 @@ void GraphicsPage::createPages()
|
||||||
|
|
||||||
void GraphicsPage::setupConfig()
|
void GraphicsPage::setupConfig()
|
||||||
{
|
{
|
||||||
QString ogreCfg = mCfg.getOgreConfigPath().string().c_str();
|
QString ogreCfg = mCfgMgr.getOgreConfigPath().string().c_str();
|
||||||
QFile file(ogreCfg);
|
QFile file(ogreCfg);
|
||||||
mOgreConfig = new QSettings(ogreCfg, QSettings::IniFormat);
|
mOgreConfig = new QSettings(ogreCfg, QSettings::IniFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPage::setupOgre()
|
void GraphicsPage::setupOgre()
|
||||||
{
|
{
|
||||||
QString pluginCfg = mCfg.getPluginsConfigPath().string().c_str();
|
QString pluginCfg = mCfgMgr.getPluginsConfigPath().string().c_str();
|
||||||
QFile file(pluginCfg);
|
QFile file(pluginCfg);
|
||||||
|
|
||||||
// Create a log manager so we can surpress debug text to stdout/stderr
|
// Create a log manager so we can surpress debug text to stdout/stderr
|
||||||
Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager;
|
Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager;
|
||||||
logMgr->createLog((mCfg.getLogPath().string() + "/launcherOgre.log"), true, false, false);
|
logMgr->createLog((mCfgMgr.getLogPath().string() + "/launcherOgre.log"), true, false, false);
|
||||||
|
|
||||||
QString ogreCfg = QString::fromStdString(mCfg.getOgreConfigPath().string());
|
QString ogreCfg = QString::fromStdString(mCfgMgr.getOgreConfigPath().string());
|
||||||
file.setFileName(ogreCfg);
|
file.setFileName(ogreCfg);
|
||||||
|
|
||||||
//we need to check that the path to the configuration file exists before we
|
//we need to check that the path to the configuration file exists before we
|
||||||
|
@ -177,7 +180,7 @@ void GraphicsPage::setupOgre()
|
||||||
Make sure you have write access to<br>%1<br><br>")).arg(configDir.path()));
|
Make sure you have write access to<br>%1<br><br>")).arg(configDir.path()));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
|
||||||
QApplication::exit(1);
|
qApp->exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +203,7 @@ void GraphicsPage::setupOgre()
|
||||||
|
|
||||||
qCritical("Error creating Ogre::Root, the error reported was:\n %s", qPrintable(ogreError));
|
qCritical("Error creating Ogre::Root, the error reported was:\n %s", qPrintable(ogreError));
|
||||||
|
|
||||||
QApplication::exit(1);
|
qApp->exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +237,7 @@ void GraphicsPage::setupOgre()
|
||||||
Please make sure the plugins.cfg file exists and contains a valid rendering plugin.<br>"));
|
Please make sure the plugins.cfg file exists and contains a valid rendering plugin.<br>"));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
|
||||||
QApplication::exit(1);
|
qApp->exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +423,7 @@ void GraphicsPage::writeConfig()
|
||||||
|
|
||||||
qCritical("Error validating configuration");
|
qCritical("Error validating configuration");
|
||||||
|
|
||||||
QApplication::exit(1);
|
qApp->exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +449,8 @@ void GraphicsPage::writeConfig()
|
||||||
|
|
||||||
qCritical("Error saving Ogre configuration, the error reported was:\n %s", qPrintable(ogreError));
|
qCritical("Error saving Ogre configuration, the error reported was:\n %s", qPrintable(ogreError));
|
||||||
|
|
||||||
QApplication::exit(1);
|
qApp->exit(1);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,21 +7,20 @@
|
||||||
#include <OgreRenderSystem.h>
|
#include <OgreRenderSystem.h>
|
||||||
#include <OgreConfigFile.h>
|
#include <OgreConfigFile.h>
|
||||||
#include <OgreConfigDialog.h>
|
#include <OgreConfigDialog.h>
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
|
||||||
|
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QStackedWidget;
|
class QStackedWidget;
|
||||||
class QSettings;
|
class QSettings;
|
||||||
|
|
||||||
|
namespace Files { struct ConfigurationManager; }
|
||||||
|
|
||||||
class GraphicsPage : public QWidget
|
class GraphicsPage : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GraphicsPage(QWidget *parent = 0);
|
GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent = 0);
|
||||||
|
|
||||||
QSettings *mOgreConfig;
|
|
||||||
|
|
||||||
void writeConfig();
|
void writeConfig();
|
||||||
|
|
||||||
|
@ -29,7 +28,6 @@ public slots:
|
||||||
void rendererChanged(const QString &renderer);
|
void rendererChanged(const QString &renderer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Cfg::ConfigurationManager mCfg;
|
|
||||||
Ogre::Root *mOgre;
|
Ogre::Root *mOgre;
|
||||||
Ogre::RenderSystem *mSelectedRenderSystem;
|
Ogre::RenderSystem *mSelectedRenderSystem;
|
||||||
Ogre::RenderSystem *mOpenGLRenderSystem;
|
Ogre::RenderSystem *mOpenGLRenderSystem;
|
||||||
|
@ -59,6 +57,10 @@ private:
|
||||||
QCheckBox *mD3DVSyncCheckBox;
|
QCheckBox *mD3DVSyncCheckBox;
|
||||||
QCheckBox *mD3DFullScreenCheckBox;
|
QCheckBox *mD3DFullScreenCheckBox;
|
||||||
|
|
||||||
|
QSettings *mOgreConfig;
|
||||||
|
|
||||||
|
Files::ConfigurationManager &mCfgMgr;
|
||||||
|
|
||||||
QString getConfigValue(const QString &key, Ogre::RenderSystem *renderer);
|
QString getConfigValue(const QString &key, Ogre::RenderSystem *renderer);
|
||||||
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
#include "maindialog.hpp"
|
#include "maindialog.hpp"
|
||||||
|
|
||||||
|
@ -17,17 +18,19 @@ int main(int argc, char *argv[])
|
||||||
dir.cdUp();
|
dir.cdUp();
|
||||||
dir.cdUp();
|
dir.cdUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// force Qt to load only LOCAL plugins, don't touch system Qt installation
|
||||||
|
QDir pluginsPath(QCoreApplication::applicationDirPath());
|
||||||
|
pluginsPath.cdUp();
|
||||||
|
pluginsPath.cd("Plugins");
|
||||||
|
|
||||||
|
QStringList libraryPaths;
|
||||||
|
libraryPaths << pluginsPath.path() << QCoreApplication::applicationDirPath();
|
||||||
|
app.setLibraryPaths(libraryPaths);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QDir::setCurrent(dir.absolutePath());
|
QDir::setCurrent(dir.absolutePath());
|
||||||
|
|
||||||
// Load the stylesheet
|
|
||||||
QFile file("./launcher.qss");
|
|
||||||
|
|
||||||
file.open(QFile::ReadOnly);
|
|
||||||
QString styleSheet = QLatin1String(file.readAll());
|
|
||||||
app.setStyleSheet(styleSheet);
|
|
||||||
|
|
||||||
MainDialog dialog;
|
MainDialog dialog;
|
||||||
return dialog.exec();
|
return dialog.exec();
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,20 @@ MainDialog::MainDialog()
|
||||||
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||||
setMinimumSize(QSize(575, 575));
|
setMinimumSize(QSize(575, 575));
|
||||||
|
|
||||||
|
// Load the stylesheet
|
||||||
|
QString config = QString::fromStdString((mCfgMgr.getGlobalDataPath() / "resources/launcher.qss").string());
|
||||||
|
QFile file(config);
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
file.setFileName(QString::fromStdString((mCfgMgr.getLocalPath() / "launcher.qss").string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
file.open(QFile::ReadOnly);
|
||||||
|
QString styleSheet = QLatin1String(file.readAll());
|
||||||
|
qApp->setStyleSheet(styleSheet);
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
|
||||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
||||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(play()));
|
connect(buttonBox, SIGNAL(accepted()), this, SLOT(play()));
|
||||||
|
|
||||||
|
@ -85,116 +99,13 @@ void MainDialog::createIcons()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList MainDialog::readConfig(const QString &fileName)
|
|
||||||
{
|
|
||||||
// We can't use QSettings directly because it
|
|
||||||
// does not support multiple keys with the same name
|
|
||||||
QFile file(fileName);
|
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle("Error opening OpenMW configuration file");
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not open %0</b><br><br> \
|
|
||||||
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
QApplication::exit(); // File cannot be opened or created
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextStream in(&file);
|
|
||||||
QStringList dataDirs;
|
|
||||||
QString dataLocal;
|
|
||||||
|
|
||||||
// Read the config line by line
|
|
||||||
while (!in.atEnd()) {
|
|
||||||
QString line = in.readLine();
|
|
||||||
|
|
||||||
if (line.startsWith("data=")) {
|
|
||||||
dataDirs.append(line.remove("data="));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the data-local key, if more than one are found only the last is used
|
|
||||||
if (line.startsWith("data-local=")) {
|
|
||||||
dataLocal = line.remove("data-local=");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read fs-strict key
|
|
||||||
if (line.startsWith("fs-strict=")) {
|
|
||||||
QString value = line.remove("fs-strict=");
|
|
||||||
|
|
||||||
(value.toLower() == QLatin1String("true"))
|
|
||||||
? mStrict = true
|
|
||||||
: mStrict = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the data-local= key to the end of the dataDirs for priority reasons
|
|
||||||
if (!dataLocal.isEmpty()) {
|
|
||||||
dataDirs.append(dataLocal);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dataDirs.isEmpty())
|
|
||||||
{
|
|
||||||
// Reset the global datadirs to the newly read entries
|
|
||||||
// Else return the previous dataDirs because nothing was found in this file;
|
|
||||||
mDataDirs = dataDirs;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
return mDataDirs;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainDialog::createPages()
|
void MainDialog::createPages()
|
||||||
{
|
{
|
||||||
mPlayPage = new PlayPage(this);
|
mPlayPage = new PlayPage(this);
|
||||||
mGraphicsPage = new GraphicsPage(this);
|
mGraphicsPage = new GraphicsPage(mCfgMgr, this);
|
||||||
mDataFilesPage = new DataFilesPage(this);
|
mDataFilesPage = new DataFilesPage(mCfgMgr, this);
|
||||||
|
|
||||||
// Retrieve all data entries from the configs
|
// Set the combobox of the play page to imitate the combobox on the datafilespage
|
||||||
QStringList dataDirs;
|
|
||||||
|
|
||||||
// Global location
|
|
||||||
QFile file(QString::fromStdString((mCfg.getGlobalConfigPath()/"openmw.cfg").string()));
|
|
||||||
if (file.exists()) {
|
|
||||||
dataDirs = readConfig(file.fileName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// User location
|
|
||||||
file.setFileName(QString::fromStdString((mCfg.getLocalConfigPath()/"openmw.cfg").string()));
|
|
||||||
if (file.exists()) {
|
|
||||||
dataDirs = readConfig(file.fileName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local location
|
|
||||||
file.setFileName("./openmw.cfg");
|
|
||||||
|
|
||||||
if (file.exists()) {
|
|
||||||
dataDirs = readConfig(file.fileName());
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
if (!dataDirs.isEmpty()) {
|
|
||||||
// Now pass the datadirs on to the DataFilesPage
|
|
||||||
mDataFilesPage->setupDataFiles(dataDirs, mStrict);
|
|
||||||
} else {
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle("Error reading OpenMW configuration file");
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not read the location of the data files</b><br><br> \
|
|
||||||
Please make sure OpenMW is correctly configured and try again.<br>"));
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
QApplication::exit(); // No data or data-local entries in openmw.cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the combobox of the play page to imitate the comobox on the datafilespage
|
|
||||||
mPlayPage->mProfilesComboBox->setModel(mDataFilesPage->mProfilesComboBox->model());
|
mPlayPage->mProfilesComboBox->setModel(mDataFilesPage->mProfilesComboBox->model());
|
||||||
mPlayPage->mProfilesComboBox->setCurrentIndex(mDataFilesPage->mProfilesComboBox->currentIndex());
|
mPlayPage->mProfilesComboBox->setCurrentIndex(mDataFilesPage->mProfilesComboBox->currentIndex());
|
||||||
|
|
||||||
|
@ -246,14 +157,16 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous)
|
||||||
void MainDialog::closeEvent(QCloseEvent *event)
|
void MainDialog::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
// Now write all config files
|
// Now write all config files
|
||||||
writeConfig();
|
mDataFilesPage->writeConfig();
|
||||||
|
mGraphicsPage->writeConfig();
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainDialog::play()
|
void MainDialog::play()
|
||||||
{
|
{
|
||||||
// First do a write of all the configs, just to be sure
|
// First do a write of all the configs, just to be sure
|
||||||
writeConfig();
|
mDataFilesPage->writeConfig();
|
||||||
|
mGraphicsPage->writeConfig();
|
||||||
|
|
||||||
#ifdef Q_WS_WIN
|
#ifdef Q_WS_WIN
|
||||||
QString game = "./openmw.exe";
|
QString game = "./openmw.exe";
|
||||||
|
@ -313,75 +226,3 @@ void MainDialog::play()
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainDialog::writeConfig()
|
|
||||||
{
|
|
||||||
// Write the profiles
|
|
||||||
mDataFilesPage->writeConfig();
|
|
||||||
mDataFilesPage->mLauncherConfig->sync();
|
|
||||||
|
|
||||||
// Write the graphics settings
|
|
||||||
mGraphicsPage->writeConfig();
|
|
||||||
mGraphicsPage->mOgreConfig->sync();
|
|
||||||
|
|
||||||
QStringList dataFiles = mDataFilesPage->selectedMasters();
|
|
||||||
dataFiles.append(mDataFilesPage->checkedPlugins());
|
|
||||||
|
|
||||||
// Open the config as a QFile
|
|
||||||
QFile file(QString::fromStdString((mCfg.getLocalConfigPath()/"openmw.cfg").string()));
|
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
|
||||||
// File cannot be opened or created
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle("Error writing OpenMW configuration file");
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not open or create %0</b><br><br> \
|
|
||||||
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
QApplication::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextStream in(&file);
|
|
||||||
QByteArray buffer;
|
|
||||||
|
|
||||||
// Remove all previous master/plugin entries from config
|
|
||||||
while (!in.atEnd()) {
|
|
||||||
QString line = in.readLine();
|
|
||||||
if (!line.contains("master") && !line.contains("plugin")) {
|
|
||||||
buffer += line += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
// Now we write back the other config entries
|
|
||||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle("Error writing OpenMW configuration file");
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not write to %0</b><br><br> \
|
|
||||||
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
QApplication::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.write(buffer);
|
|
||||||
|
|
||||||
QTextStream out(&file);
|
|
||||||
|
|
||||||
// Write the list of game files to the config
|
|
||||||
foreach (const QString ¤tFile, dataFiles) {
|
|
||||||
|
|
||||||
if (currentFile.endsWith(QString(".esm"), Qt::CaseInsensitive)) {
|
|
||||||
out << "master=" << currentFile << endl;
|
|
||||||
} else if (currentFile.endsWith(QString(".esp"), Qt::CaseInsensitive)) {
|
|
||||||
out << "plugin=" << currentFile << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
class QListWidget;
|
class QListWidget;
|
||||||
class QListWidgetItem;
|
class QListWidgetItem;
|
||||||
|
@ -28,15 +28,11 @@ public slots:
|
||||||
void play();
|
void play();
|
||||||
void profileChanged(int index);
|
void profileChanged(int index);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createIcons();
|
void createIcons();
|
||||||
void createPages();
|
void createPages();
|
||||||
void writeConfig();
|
|
||||||
void closeEvent(QCloseEvent *event);
|
void closeEvent(QCloseEvent *event);
|
||||||
|
|
||||||
QStringList readConfig(const QString &fileName);
|
|
||||||
|
|
||||||
QListWidget *mIconWidget;
|
QListWidget *mIconWidget;
|
||||||
QStackedWidget *mPagesWidget;
|
QStackedWidget *mPagesWidget;
|
||||||
|
|
||||||
|
@ -44,10 +40,7 @@ private:
|
||||||
GraphicsPage *mGraphicsPage;
|
GraphicsPage *mGraphicsPage;
|
||||||
DataFilesPage *mDataFilesPage;
|
DataFilesPage *mDataFilesPage;
|
||||||
|
|
||||||
QStringList mDataDirs;
|
Files::ConfigurationManager mCfgMgr;
|
||||||
bool mStrict;
|
|
||||||
|
|
||||||
Cfg::ConfigurationManager mCfg;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,8 +43,8 @@ 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 environment globals class action nullaction actionteleport
|
||||||
containerstore actiontalk actiontake containerstore manualref containerutil player cellfunctors
|
containerstore actiontalk actiontake manualref player cellfunctors
|
||||||
cells localscripts customdata
|
cells localscripts customdata weather
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwclass
|
add_openmw_dir (mwclass
|
||||||
|
@ -77,7 +77,6 @@ target_link_libraries(openmw
|
||||||
${OPENAL_LIBRARY}
|
${OPENAL_LIBRARY}
|
||||||
${SOUND_INPUT_LIBRARY}
|
${SOUND_INPUT_LIBRARY}
|
||||||
${BULLET_LIBRARIES}
|
${BULLET_LIBRARIES}
|
||||||
caelum
|
|
||||||
components
|
components
|
||||||
MyGUIEngine
|
MyGUIEngine
|
||||||
MyGUIOgrePlatform
|
MyGUIOgrePlatform
|
||||||
|
@ -86,10 +85,6 @@ target_link_libraries(openmw
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
find_library(CARBON_FRAMEWORK Carbon)
|
find_library(CARBON_FRAMEWORK Carbon)
|
||||||
target_link_libraries(openmw ${CARBON_FRAMEWORK})
|
target_link_libraries(openmw ${CARBON_FRAMEWORK})
|
||||||
install(TARGETS openmw
|
|
||||||
BUNDLE DESTINATION .
|
|
||||||
RUNTIME DESTINATION ../MacOS
|
|
||||||
COMPONENT Runtime)
|
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
if(DPKG_PROGRAM)
|
if(DPKG_PROGRAM)
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
#include <components/esm_store/cell_store.hpp>
|
#include <components/esm_store/cell_store.hpp>
|
||||||
#include <components/bsa/bsa_archive.hpp>
|
#include <components/bsa/bsa_archive.hpp>
|
||||||
#include <components/esm/esm_reader.hpp>
|
#include <components/esm/esm_reader.hpp>
|
||||||
#include <components/files/path.hpp>
|
#include <components/files/fixedpath.hpp>
|
||||||
|
#include <components/files/configurationmanager.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>
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ void OMW::Engine::executeLocalScripts()
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext (mEnvironment,
|
MWScript::InterpreterContext interpreterContext (mEnvironment,
|
||||||
&script.second.getRefData().getLocals(), script.second);
|
&script.second.getRefData().getLocals(), script.second);
|
||||||
mScriptManager->run (script.first, interpreterContext);
|
mEnvironment.mScriptManager->run (script.first, interpreterContext);
|
||||||
|
|
||||||
if (mEnvironment.mWorld->hasCellChanged())
|
if (mEnvironment.mWorld->hasCellChanged())
|
||||||
break;
|
break;
|
||||||
|
@ -171,7 +173,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OMW::Engine::Engine(Cfg::ConfigurationManager& configurationManager)
|
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||||
: mOgre (0)
|
: mOgre (0)
|
||||||
, mFpsLevel(0)
|
, mFpsLevel(0)
|
||||||
, mDebug (false)
|
, mDebug (false)
|
||||||
|
@ -181,7 +183,6 @@ OMW::Engine::Engine(Cfg::ConfigurationManager& configurationManager)
|
||||||
, mCompileAll (false)
|
, mCompileAll (false)
|
||||||
, mReportFocus (false)
|
, mReportFocus (false)
|
||||||
, mFocusTDiff (0)
|
, mFocusTDiff (0)
|
||||||
, mScriptManager (0)
|
|
||||||
, mScriptContext (0)
|
, mScriptContext (0)
|
||||||
, mFSStrict (false)
|
, mFSStrict (false)
|
||||||
, mCfgMgr(configurationManager)
|
, mCfgMgr(configurationManager)
|
||||||
|
@ -198,7 +199,7 @@ OMW::Engine::~Engine()
|
||||||
delete mEnvironment.mMechanicsManager;
|
delete mEnvironment.mMechanicsManager;
|
||||||
delete mEnvironment.mDialogueManager;
|
delete mEnvironment.mDialogueManager;
|
||||||
delete mEnvironment.mJournal;
|
delete mEnvironment.mJournal;
|
||||||
delete mScriptManager;
|
delete mEnvironment.mScriptManager;
|
||||||
delete mScriptContext;
|
delete mScriptContext;
|
||||||
delete mOgre;
|
delete mOgre;
|
||||||
}
|
}
|
||||||
|
@ -208,15 +209,16 @@ 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");
|
||||||
|
std::string dataDirectory;
|
||||||
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;
|
||||||
Bsa::addBSA (iter->second.string());
|
Bsa::addBSA(iter->second.string());
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Data dir " << mDataDir.string() << std::endl;
|
dataDirectory = iter->second.parent_path().string();
|
||||||
Bsa::addDir(mDataDir.string(), mFSStrict);
|
std::cout << "Data dir " << dataDirectory << std::endl;
|
||||||
|
Bsa::addDir(dataDirectory, mFSStrict);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add resources directory
|
// add resources directory
|
||||||
|
@ -237,9 +239,7 @@ void OMW::Engine::enableFSStrict(bool fsStrict)
|
||||||
|
|
||||||
void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs)
|
void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs)
|
||||||
{
|
{
|
||||||
/// \todo remove mDataDir, once resources system can handle multiple directories
|
mDataDirs = dataDirs;
|
||||||
assert (!dataDirs.empty());
|
|
||||||
mDataDir = dataDirs.back();
|
|
||||||
mFileCollections = Files::Collections (dataDirs, !mFSStrict);
|
mFileCollections = Files::Collections (dataDirs, !mFSStrict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ void OMW::Engine::go()
|
||||||
}
|
}
|
||||||
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() + std::string("/"),
|
mCfgMgr.getLogPath().string(),
|
||||||
mCfgMgr.getPluginsConfigPath().string(), false);
|
mCfgMgr.getPluginsConfigPath().string(), false);
|
||||||
|
|
||||||
// This has to be added BEFORE MyGUI is initialized, as it needs
|
// This has to be added BEFORE MyGUI is initialized, as it needs
|
||||||
|
@ -341,7 +341,7 @@ void OMW::Engine::go()
|
||||||
mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre->getRoot(),
|
mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre->getRoot(),
|
||||||
mOgre->getCamera(),
|
mOgre->getCamera(),
|
||||||
mEnvironment.mWorld->getStore(),
|
mEnvironment.mWorld->getStore(),
|
||||||
(mDataDir),
|
mDataDirs,
|
||||||
mUseSound, mFSStrict, mEnvironment);
|
mUseSound, mFSStrict, mEnvironment);
|
||||||
|
|
||||||
// Create script system
|
// Create script system
|
||||||
|
@ -349,11 +349,11 @@ void OMW::Engine::go()
|
||||||
mEnvironment);
|
mEnvironment);
|
||||||
mScriptContext->setExtensions (&mExtensions);
|
mScriptContext->setExtensions (&mExtensions);
|
||||||
|
|
||||||
mScriptManager = new MWScript::ScriptManager (mEnvironment.mWorld->getStore(), mVerboseScripts,
|
mEnvironment.mScriptManager = new MWScript::ScriptManager (mEnvironment.mWorld->getStore(),
|
||||||
*mScriptContext);
|
mVerboseScripts, *mScriptContext);
|
||||||
|
|
||||||
mEnvironment.mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(),
|
mEnvironment.mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(),
|
||||||
*mScriptManager);
|
*mEnvironment.mScriptManager);
|
||||||
|
|
||||||
// Create game mechanics system
|
// Create game mechanics system
|
||||||
mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (mEnvironment);
|
mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (mEnvironment);
|
||||||
|
@ -394,7 +394,7 @@ void OMW::Engine::go()
|
||||||
// scripts
|
// scripts
|
||||||
if (mCompileAll)
|
if (mCompileAll)
|
||||||
{
|
{
|
||||||
std::pair<int, int> result = mScriptManager->compileAll();
|
std::pair<int, int> result = mEnvironment.mScriptManager->compileAll();
|
||||||
|
|
||||||
if (result.first)
|
if (result.first)
|
||||||
std::cout
|
std::cout
|
||||||
|
@ -436,7 +436,7 @@ void OMW::Engine::activate()
|
||||||
if (!script.empty())
|
if (!script.empty())
|
||||||
{
|
{
|
||||||
mEnvironment.mWorld->getLocalScripts().setIgnore (ptr);
|
mEnvironment.mWorld->getLocalScripts().setIgnore (ptr);
|
||||||
mScriptManager->run (script, interpreterContext);
|
mEnvironment.mScriptManager->run (script, interpreterContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!interpreterContext.hasActivationBeenHandled())
|
if (!interpreterContext.hasActivationBeenHandled())
|
||||||
|
@ -445,6 +445,28 @@ void OMW::Engine::activate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OMW::Engine::screenshot()
|
||||||
|
{
|
||||||
|
// Count screenshots.
|
||||||
|
int shotCount = 0;
|
||||||
|
|
||||||
|
const std::string screenshotPath = mCfgMgr.getUserPath().string();
|
||||||
|
|
||||||
|
// Find the first unused filename with a do-while
|
||||||
|
std::ostringstream stream;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Reset the stream
|
||||||
|
stream.str("");
|
||||||
|
stream.clear();
|
||||||
|
|
||||||
|
stream << screenshotPath << "screenshot" << std::setw(3) << std::setfill('0') << shotCount++ << ".png";
|
||||||
|
|
||||||
|
} while (boost::filesystem::exists(stream.str()));
|
||||||
|
|
||||||
|
mOgre->screenshot(stream.str());
|
||||||
|
}
|
||||||
|
|
||||||
void OMW::Engine::setCompileAll (bool all)
|
void OMW::Engine::setCompileAll (bool all)
|
||||||
{
|
{
|
||||||
mCompileAll = all;
|
mCompileAll = all;
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <components/compiler/extensions.hpp>
|
#include <components/compiler/extensions.hpp>
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
|
||||||
|
|
||||||
#include "mwworld/environment.hpp"
|
#include "mwworld/environment.hpp"
|
||||||
#include "mwworld/ptr.hpp"
|
#include "mwworld/ptr.hpp"
|
||||||
|
@ -52,13 +51,18 @@ namespace OEngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Files
|
||||||
|
{
|
||||||
|
struct ConfigurationManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace OMW
|
namespace OMW
|
||||||
{
|
{
|
||||||
/// \brief Main engine class, that brings together all the components of OpenMW
|
/// \brief Main engine class, that brings together all the components of OpenMW
|
||||||
class Engine : private Ogre::FrameListener
|
class Engine : private Ogre::FrameListener
|
||||||
{
|
{
|
||||||
std::string mEncoding;
|
std::string mEncoding;
|
||||||
boost::filesystem::path mDataDir;
|
Files::PathContainer mDataDirs;
|
||||||
boost::filesystem::path mResDir;
|
boost::filesystem::path mResDir;
|
||||||
OEngine::Render::OgreRenderer *mOgre;
|
OEngine::Render::OgreRenderer *mOgre;
|
||||||
std::string mCellName;
|
std::string mCellName;
|
||||||
|
@ -74,10 +78,9 @@ namespace OMW
|
||||||
std::string mFocusName;
|
std::string mFocusName;
|
||||||
|
|
||||||
MWWorld::Environment mEnvironment;
|
MWWorld::Environment mEnvironment;
|
||||||
MWScript::ScriptManager *mScriptManager;
|
|
||||||
Compiler::Extensions mExtensions;
|
Compiler::Extensions mExtensions;
|
||||||
Compiler::Context *mScriptContext;
|
Compiler::Context *mScriptContext;
|
||||||
|
|
||||||
|
|
||||||
Files::Collections mFileCollections;
|
Files::Collections mFileCollections;
|
||||||
bool mFSStrict;
|
bool mFSStrict;
|
||||||
|
@ -101,7 +104,7 @@ namespace OMW
|
||||||
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
|
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Engine(Cfg::ConfigurationManager& configurationManager);
|
Engine(Files::ConfigurationManager& configurationManager);
|
||||||
virtual ~Engine();
|
virtual ~Engine();
|
||||||
|
|
||||||
/// Enable strict filesystem mode (do not fold case)
|
/// Enable strict filesystem mode (do not fold case)
|
||||||
|
@ -149,6 +152,9 @@ namespace OMW
|
||||||
/// Activate the focussed object.
|
/// Activate the focussed object.
|
||||||
void activate();
|
void activate();
|
||||||
|
|
||||||
|
/// Write screenshot to file.
|
||||||
|
void screenshot();
|
||||||
|
|
||||||
/// Compile all scripts (excludign dialogue scripts) at startup?
|
/// Compile all scripts (excludign dialogue scripts) at startup?
|
||||||
void setCompileAll (bool all);
|
void setCompileAll (bool all);
|
||||||
|
|
||||||
|
@ -158,7 +164,7 @@ namespace OMW
|
||||||
void setAnimationVerbose(bool animverbose);
|
void setAnimationVerbose(bool animverbose);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Cfg::ConfigurationManager& mCfgMgr;
|
Files::ConfigurationManager& mCfgMgr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
#include <components/files/fileops.hpp>
|
#include <components/files/fileops.hpp>
|
||||||
#include <components/files/path.hpp>
|
#include <components/files/fixedpath.hpp>
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
|
@ -35,6 +35,23 @@
|
||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
|
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
/**
|
||||||
|
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
||||||
|
*/
|
||||||
|
#if (BOOST_VERSION <= 104600)
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string>(const std::string& arg)
|
||||||
|
{
|
||||||
|
return boost::filesystem::path(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace boost */
|
||||||
|
#endif /* (BOOST_VERSION <= 104600) */
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,7 +63,7 @@ using namespace std;
|
||||||
* \retval true - Everything goes OK
|
* \retval true - Everything goes OK
|
||||||
* \retval false - Error
|
* \retval false - Error
|
||||||
*/
|
*/
|
||||||
bool parseOptions (int argc, char** argv, OMW::Engine& engine, Cfg::ConfigurationManager& cfgMgr)
|
bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::ConfigurationManager& cfgMgr)
|
||||||
{
|
{
|
||||||
// Create a local alias for brevity
|
// Create a local alias for brevity
|
||||||
namespace bpo = boost::program_options;
|
namespace bpo = boost::program_options;
|
||||||
|
@ -164,14 +181,19 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Cfg::Configuratio
|
||||||
std::string local(variables["data-local"].as<std::string>());
|
std::string local(variables["data-local"].as<std::string>());
|
||||||
if (!local.empty())
|
if (!local.empty())
|
||||||
{
|
{
|
||||||
dataDirs.push_back(Files::PathContainer::value_type(local));
|
std::cout << "Ignoring data-local (currently not supported)" << std::endl;
|
||||||
|
// dataDirs.push_back(Files::PathContainer::value_type(local));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataDirs.empty())
|
if (dataDirs.size()>1)
|
||||||
{
|
{
|
||||||
dataDirs.push_back(cfgMgr.getLocalDataPath());
|
dataDirs.resize (1);
|
||||||
|
std::cout << "Ignoring all but the first data path (multiple data paths currently not supported)"
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfgMgr.processPaths(dataDirs);
|
||||||
|
|
||||||
engine.setDataDirs(dataDirs);
|
engine.setDataDirs(dataDirs);
|
||||||
|
|
||||||
engine.setResourceDir(variables["resources"].as<std::string>());
|
engine.setResourceDir(variables["resources"].as<std::string>());
|
||||||
|
@ -224,7 +246,7 @@ int main(int argc, char**argv)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Cfg::ConfigurationManager cfgMgr;
|
Files::ConfigurationManager cfgMgr;
|
||||||
OMW::Engine engine(cfgMgr);
|
OMW::Engine engine(cfgMgr);
|
||||||
|
|
||||||
if (parseOptions(argc, argv, engine, cfgMgr))
|
if (parseOptions(argc, argv, engine, cfgMgr))
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -59,12 +57,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Apparatus::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.appas);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Apparatus::getScript (const MWWorld::Ptr& ptr) const
|
std::string Apparatus::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -22,10 +22,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -71,12 +69,6 @@ namespace MWClass
|
||||||
return ref->base->data.health;
|
return ref->base->data.health;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Armor::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.armors);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Armor::getScript (const MWWorld::Ptr& ptr) const
|
std::string Armor::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -28,10 +28,6 @@ namespace MWClass
|
||||||
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return item max health or throw an exception, if class does not have item health
|
///< Return item max health or throw an exception, if class does not have item health
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Book::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Book::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -61,12 +59,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Book::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.books);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Book::getScript (const MWWorld::Ptr& ptr) const
|
std::string Book::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -22,10 +22,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -59,12 +57,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clothing::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.clothes);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Clothing::getScript (const MWWorld::Ptr& ptr) const
|
std::string Clothing::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -22,10 +22,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,20 @@
|
||||||
#include <components/esm_store/cell_store.hpp>
|
#include <components/esm_store/cell_store.hpp>
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.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"
|
||||||
|
|
||||||
|
#include "../mwsound/soundmanager.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct CustomData : public MWWorld::CustomData
|
struct CustomData : public MWWorld::CustomData
|
||||||
{
|
{
|
||||||
MWWorld::ContainerStore<MWWorld::RefData> mContainerStore;
|
MWWorld::ContainerStore mContainerStore;
|
||||||
|
|
||||||
virtual MWWorld::CustomData *clone() const;
|
virtual MWWorld::CustomData *clone() const;
|
||||||
};
|
};
|
||||||
|
@ -71,6 +75,38 @@ namespace MWClass
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<MWWorld::Action> Container::activate (const MWWorld::Ptr& ptr,
|
||||||
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
|
||||||
|
{
|
||||||
|
const std::string lockedSound = "LockedChest";
|
||||||
|
const std::string trapActivationSound = "Disarm Trap Fail";
|
||||||
|
|
||||||
|
if (ptr.getCellRef().lockLevel>0)
|
||||||
|
{
|
||||||
|
// TODO check for key
|
||||||
|
std::cout << "Locked container" << std::endl;
|
||||||
|
environment.mSoundManager->playSound(lockedSound, 1.0, 1.0);
|
||||||
|
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Unlocked container" << std::endl;
|
||||||
|
if(ptr.getCellRef().trap.empty())
|
||||||
|
{
|
||||||
|
// Not trapped, Inventory GUI goes here
|
||||||
|
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Trap activation goes here
|
||||||
|
std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl;
|
||||||
|
environment.mSoundManager->playSound(trapActivationSound, 1.0, 1.0);
|
||||||
|
ptr.getCellRef().trap = "";
|
||||||
|
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string Container::getName (const MWWorld::Ptr& ptr) const
|
std::string Container::getName (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
|
||||||
|
@ -79,7 +115,7 @@ namespace MWClass
|
||||||
return ref->base->name;
|
return ref->base->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& Container::getContainerStore (const MWWorld::Ptr& ptr)
|
MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
|
@ -20,8 +20,11 @@ namespace MWClass
|
||||||
///< \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 MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
|
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
||||||
const MWWorld::Ptr& ptr) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
|
///< Generate action for activation
|
||||||
|
|
||||||
|
virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return container store
|
///< Return container store
|
||||||
|
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef GAME_MWCLASS_CONTAINERUTIL_H
|
|
||||||
#define GAME_MWCLASS_CONTAINERUTIL_H
|
|
||||||
|
|
||||||
#include <components/esm_store/cell_store.hpp>
|
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
|
||||||
#include "../mwworld/containerstore.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
void insertIntoContainerStore (const MWWorld::Ptr& ptr,
|
|
||||||
ESMS::CellRefList<T, MWWorld::RefData>& containerStore)
|
|
||||||
{
|
|
||||||
if (!ptr.isEmpty())
|
|
||||||
{
|
|
||||||
// TODO check stacking
|
|
||||||
|
|
||||||
ESMS::LiveCellRef<T, MWWorld::RefData> cellRef(ptr.getCellRef(), ptr.get<T>()->base);
|
|
||||||
cellRef.mData = ptr.getRefData();
|
|
||||||
|
|
||||||
containerStore.list.push_back (cellRef);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -17,7 +17,7 @@ namespace
|
||||||
struct CustomData : public MWWorld::CustomData
|
struct CustomData : public MWWorld::CustomData
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats mCreatureStats;
|
MWMechanics::CreatureStats mCreatureStats;
|
||||||
MWWorld::ContainerStore<MWWorld::RefData> mContainerStore;
|
MWWorld::ContainerStore mContainerStore;
|
||||||
|
|
||||||
virtual MWWorld::CustomData *clone() const;
|
virtual MWWorld::CustomData *clone() const;
|
||||||
};
|
};
|
||||||
|
@ -118,7 +118,7 @@ namespace MWClass
|
||||||
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
|
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& Creature::getContainerStore (const MWWorld::Ptr& ptr)
|
MWWorld::ContainerStore& Creature::getContainerStore (const MWWorld::Ptr& ptr)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
|
virtual MWWorld::ContainerStore& getContainerStore (
|
||||||
const MWWorld::Ptr& ptr) const;
|
const MWWorld::Ptr& ptr) const;
|
||||||
///< Return container store
|
///< Return container store
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
|
#include "../mwsound/soundmanager.hpp"
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -61,15 +63,28 @@ namespace MWClass
|
||||||
ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
|
||||||
ptr.get<ESM::Door>();
|
ptr.get<ESM::Door>();
|
||||||
|
|
||||||
|
const std::string &openSound = ref->base->openSound;
|
||||||
|
//const std::string &closeSound = ref->base->closeSound;
|
||||||
|
const std::string lockedSound = "LockedDoor";
|
||||||
|
const std::string trapActivationSound = "Disarm Trap Fail";
|
||||||
|
|
||||||
if (ptr.getCellRef().lockLevel>0)
|
if (ptr.getCellRef().lockLevel>0)
|
||||||
{
|
{
|
||||||
// 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->playSound(lockedSound, 1.0, 1.0);
|
||||||
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check trap
|
if(!ptr.getCellRef().trap.empty())
|
||||||
|
{
|
||||||
|
// Trap activation
|
||||||
|
std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl;
|
||||||
|
environment.mSoundManager->playSound(trapActivationSound, 1.0, 1.0);
|
||||||
|
ptr.getCellRef().trap = "";
|
||||||
|
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||||
|
}
|
||||||
|
|
||||||
if (ref->ref.teleport)
|
if (ref->ref.teleport)
|
||||||
{
|
{
|
||||||
|
@ -77,6 +92,7 @@ namespace MWClass
|
||||||
if (environment.mWorld->getPlayer().getPlayer()==actor)
|
if (environment.mWorld->getPlayer().getPlayer()==actor)
|
||||||
{
|
{
|
||||||
// the player is using the door
|
// the player is using the door
|
||||||
|
environment.mSoundManager->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));
|
||||||
}
|
}
|
||||||
|
@ -91,6 +107,9 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
// animated door
|
// animated door
|
||||||
// TODO return action for rotating the door
|
// TODO return action for rotating the door
|
||||||
|
|
||||||
|
// This is a little pointless, but helps with testing
|
||||||
|
environment.mSoundManager->playSound(openSound, 1.0, 1.0);
|
||||||
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -57,12 +55,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ingredient::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.ingreds);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Ingredient::getScript (const MWWorld::Ptr& ptr) const
|
std::string Ingredient::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -22,10 +22,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -26,18 +24,18 @@ namespace MWClass
|
||||||
assert (ref->base != NULL);
|
assert (ref->base != NULL);
|
||||||
const std::string &model = ref->base->model;
|
const std::string &model = ref->base->model;
|
||||||
|
|
||||||
|
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||||
|
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
|
||||||
|
|
||||||
if (!model.empty())
|
if (!model.empty())
|
||||||
{
|
|
||||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
|
||||||
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
|
|
||||||
objects.insertMesh(ptr, "meshes\\" + model);
|
objects.insertMesh(ptr, "meshes\\" + model);
|
||||||
const int color = ref->base->data.color;
|
|
||||||
const float r = ((color >> 0) & 0xFF) / 255.0f;
|
const int color = ref->base->data.color;
|
||||||
const float g = ((color >> 8) & 0xFF) / 255.0f;
|
const float r = ((color >> 0) & 0xFF) / 255.0f;
|
||||||
const float b = ((color >> 16) & 0xFF) / 255.0f;
|
const float g = ((color >> 8) & 0xFF) / 255.0f;
|
||||||
const float radius = float (ref->base->data.radius);
|
const float b = ((color >> 16) & 0xFF) / 255.0f;
|
||||||
objects.insertLight (ptr, r, g, b, radius);
|
const float radius = float (ref->base->data.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, MWWorld::Environment& environment) const
|
||||||
|
@ -45,13 +43,12 @@ namespace MWClass
|
||||||
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
||||||
ptr.get<ESM::Light>();
|
ptr.get<ESM::Light>();
|
||||||
|
|
||||||
|
|
||||||
const std::string &model = ref->base->model;
|
|
||||||
assert (ref->base != NULL);
|
assert (ref->base != NULL);
|
||||||
|
const std::string &model = ref->base->model;
|
||||||
|
|
||||||
if(!model.empty()){
|
if(!model.empty()){
|
||||||
physics.insertObjectPhysics(ptr, "meshes\\" + model);
|
physics.insertObjectPhysics(ptr, "meshes\\" + model);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
|
void Light::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
|
||||||
|
@ -89,12 +86,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.lights);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Light::getScript (const MWWorld::Ptr& ptr) const
|
std::string Light::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -27,10 +27,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -60,12 +58,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lockpick::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.lockpicks);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Lockpick::getScript (const MWWorld::Ptr& ptr) const
|
std::string Lockpick::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -22,10 +22,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -59,12 +57,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Miscellaneous::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.miscItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Miscellaneous::getScript (const MWWorld::Ptr& ptr) const
|
std::string Miscellaneous::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -22,10 +22,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace
|
||||||
MWMechanics::NpcStats mNpcStats;
|
MWMechanics::NpcStats mNpcStats;
|
||||||
MWMechanics::CreatureStats mCreatureStats;
|
MWMechanics::CreatureStats mCreatureStats;
|
||||||
MWMechanics::Movement mMovement;
|
MWMechanics::Movement mMovement;
|
||||||
MWWorld::ContainerStore<MWWorld::RefData> mContainerStore;
|
MWWorld::ContainerStore mContainerStore;
|
||||||
|
|
||||||
virtual MWWorld::CustomData *clone() const;
|
virtual MWWorld::CustomData *clone() const;
|
||||||
};
|
};
|
||||||
|
@ -156,7 +156,7 @@ namespace MWClass
|
||||||
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
|
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& Npc::getContainerStore (const MWWorld::Ptr& ptr)
|
MWWorld::ContainerStore& Npc::getContainerStore (const MWWorld::Ptr& ptr)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
|
@ -35,8 +35,7 @@ namespace MWClass
|
||||||
virtual MWMechanics::NpcStats& getNpcStats (const MWWorld::Ptr& ptr) const;
|
virtual MWMechanics::NpcStats& getNpcStats (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return NPC stats
|
///< Return NPC stats
|
||||||
|
|
||||||
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
|
virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const;
|
||||||
const MWWorld::Ptr& ptr) const;
|
|
||||||
///< Return container store
|
///< Return container store
|
||||||
|
|
||||||
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -59,12 +57,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Potion::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.potions);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Potion::getScript (const MWWorld::Ptr& ptr) const
|
std::string Potion::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -22,10 +22,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include "../mwworld/actiontake.hpp"
|
#include "../mwworld/actiontake.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
|
@ -20,7 +19,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();
|
||||||
|
@ -58,12 +57,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Probe::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.probes);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Probe::getScript (const MWWorld::Ptr& ptr) const
|
std::string Probe::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -22,10 +22,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -59,12 +57,6 @@ namespace MWClass
|
||||||
new MWWorld::ActionTake (ptr));
|
new MWWorld::ActionTake (ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Repair::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.repairs);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Repair::getScript (const MWWorld::Ptr& ptr) const
|
std::string Repair::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -22,10 +22,6 @@ namespace MWClass
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
///< Generate action for activation
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace MWClass
|
||||||
if (!model.empty())
|
if (!model.empty())
|
||||||
{
|
{
|
||||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||||
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
|
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), true);
|
||||||
objects.insertMesh(ptr, "meshes\\" + model);
|
objects.insertMesh(ptr, "meshes\\" + model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,13 +30,12 @@ namespace MWClass
|
||||||
ESMS::LiveCellRef<ESM::Static, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Static, MWWorld::RefData> *ref =
|
||||||
ptr.get<ESM::Static>();
|
ptr.get<ESM::Static>();
|
||||||
|
|
||||||
|
|
||||||
const std::string &model = ref->base->model;
|
|
||||||
assert (ref->base != NULL);
|
assert (ref->base != NULL);
|
||||||
|
const std::string &model = ref->base->model;
|
||||||
|
|
||||||
if(!model.empty()){
|
if(!model.empty()){
|
||||||
physics.insertObjectPhysics(ptr, "meshes\\" + model);
|
physics.insertObjectPhysics(ptr, "meshes\\" + model);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Static::getName (const MWWorld::Ptr& ptr) const
|
std::string Static::getName (const MWWorld::Ptr& ptr) const
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Weapon::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Weapon::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -72,12 +70,6 @@ namespace MWClass
|
||||||
return ref->base->data.health;
|
return ref->base->data.health;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Weapon::insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
insertIntoContainerStore (ptr, containerStore.weapons);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Weapon::getScript (const MWWorld::Ptr& ptr) const
|
std::string Weapon::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
||||||
|
|
|
@ -28,10 +28,6 @@ namespace MWClass
|
||||||
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return item max health or throw an exception, if class does not have item health
|
///< Return item max health or throw an exception, if class does not have item health
|
||||||
|
|
||||||
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
|
|
||||||
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
|
|
||||||
///< Insert into a containe
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "../mwscript/extensions.hpp"
|
#include "../mwscript/extensions.hpp"
|
||||||
|
#include "../mwscript/scriptmanager.hpp"
|
||||||
|
|
||||||
#include <components/compiler/exception.hpp>
|
#include <components/compiler/exception.hpp>
|
||||||
#include <components/compiler/errorhandler.hpp>
|
#include <components/compiler/errorhandler.hpp>
|
||||||
#include <components/compiler/scanner.hpp>
|
#include <components/compiler/scanner.hpp>
|
||||||
|
@ -409,7 +411,7 @@ namespace MWDialogue
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogueManager::DialogueManager (MWWorld::Environment& environment) :
|
DialogueManager::DialogueManager (MWWorld::Environment& environment) :
|
||||||
mEnvironment (environment),mCompilerContext (MWScript::CompilerContext::Type_Dialgoue, environment),
|
mEnvironment (environment),mCompilerContext (MWScript::CompilerContext::Type_Dialgoue, environment),
|
||||||
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream)
|
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream)
|
||||||
{
|
{
|
||||||
|
@ -524,11 +526,21 @@ namespace MWDialogue
|
||||||
{
|
{
|
||||||
mErrorHandler.reset();
|
mErrorHandler.reset();
|
||||||
|
|
||||||
std::istringstream input (cmd);
|
std::istringstream input (cmd + "\n");
|
||||||
|
|
||||||
Compiler::Scanner scanner (mErrorHandler, input, mCompilerContext.getExtensions());
|
Compiler::Scanner scanner (mErrorHandler, input, mCompilerContext.getExtensions());
|
||||||
|
|
||||||
Compiler::ScriptParser parser(mErrorHandler,mCompilerContext,Compiler::Locals());//??????&mActor.getRefData().getLocals());
|
Compiler::Locals locals;
|
||||||
|
|
||||||
|
std::string actorScript = MWWorld::Class::get (mActor).getScript (mActor);
|
||||||
|
|
||||||
|
if (!actorScript.empty())
|
||||||
|
{
|
||||||
|
// grab local variables from actor's script, if available.
|
||||||
|
locals = mEnvironment.mScriptManager->getLocals (actorScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
Compiler::ScriptParser parser(mErrorHandler,mCompilerContext, locals);
|
||||||
|
|
||||||
scanner.scan (parser);
|
scanner.scan (parser);
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ book formatText(std::string text,book mBook,int maxLine, int lineSize)
|
||||||
mBook.pages.pop_back();
|
mBook.pages.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string::iterator wordBegin = text.begin();
|
//std::string::iterator wordBegin = text.begin();
|
||||||
std::string::iterator wordEnd;
|
//std::string::iterator wordEnd;
|
||||||
|
|
||||||
std::string cText = text;
|
std::string cText = text;
|
||||||
|
|
||||||
|
|
|
@ -83,27 +83,14 @@ namespace MWInput
|
||||||
MWGui::WindowManager &windows;
|
MWGui::WindowManager &windows;
|
||||||
OMW::Engine& mEngine;
|
OMW::Engine& mEngine;
|
||||||
|
|
||||||
// Count screenshots.
|
|
||||||
int shotCount;
|
|
||||||
|
|
||||||
|
|
||||||
/* InputImpl Methods */
|
/* InputImpl Methods */
|
||||||
|
|
||||||
// Write screenshot to file.
|
|
||||||
void screenshot()
|
void screenshot()
|
||||||
{
|
{
|
||||||
|
mEngine.screenshot();
|
||||||
// Find the first unused filename with a do-while
|
|
||||||
char buf[50];
|
|
||||||
do
|
|
||||||
{
|
|
||||||
snprintf(buf, 50, "screenshot%03d.png", shotCount++);
|
|
||||||
} while (boost::filesystem::exists(buf));
|
|
||||||
|
|
||||||
ogre.screenshot(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* toggleInventory() is called when the user presses the button to toggle the inventory screen. */
|
/* toggleInventory() is called when the user presses the button to toggle the inventory screen. */
|
||||||
void toggleInventory()
|
void toggleInventory()
|
||||||
{
|
{
|
||||||
|
@ -183,8 +170,7 @@ namespace MWInput
|
||||||
poller(input),
|
poller(input),
|
||||||
player(_player),
|
player(_player),
|
||||||
windows(_windows),
|
windows(_windows),
|
||||||
mEngine (engine),
|
mEngine (engine)
|
||||||
shotCount(0)
|
|
||||||
{
|
{
|
||||||
using namespace OEngine::Input;
|
using namespace OEngine::Input;
|
||||||
using namespace OEngine::Render;
|
using namespace OEngine::Render;
|
||||||
|
|
|
@ -99,14 +99,15 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store){
|
||||||
mRend.getScene()->destroySceneNode(base);
|
mRend.getScene()->destroySceneNode(base);
|
||||||
base = 0;
|
base = 0;
|
||||||
}
|
}
|
||||||
for(std::map<MWWorld::Ptr, Animation*>::iterator iter = mAllActors.begin(); iter != mAllActors.end(); iter++)
|
for(std::map<MWWorld::Ptr, Animation*>::iterator iter = mAllActors.begin(); iter != mAllActors.end(); )
|
||||||
{
|
{
|
||||||
if(iter->first.getCell() == store){
|
if(iter->first.getCell() == store){
|
||||||
delete iter->second;
|
delete iter->second;
|
||||||
mAllActors.erase(iter);
|
mAllActors.erase(iter++);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number){
|
void Actors::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number){
|
||||||
|
|
|
@ -101,7 +101,6 @@ namespace MWRender{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){
|
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){
|
||||||
bool useHandles = skel == creaturemodel->getSkeleton();
|
|
||||||
shapeNumber = 0;
|
shapeNumber = 0;
|
||||||
|
|
||||||
std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter;
|
std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter;
|
||||||
|
@ -112,6 +111,9 @@ namespace MWRender{
|
||||||
|
|
||||||
Nif::NiTriShapeCopy& copy = *allshapesiter;
|
Nif::NiTriShapeCopy& copy = *allshapesiter;
|
||||||
std::vector<Ogre::Vector3>* allvertices = ©.vertices;
|
std::vector<Ogre::Vector3>* allvertices = ©.vertices;
|
||||||
|
std::vector<Ogre::Vector3>* allnormals = ©.normals;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//std::set<unsigned int> vertices;
|
//std::set<unsigned int> vertices;
|
||||||
//std::set<unsigned int> normals;
|
//std::set<unsigned int> normals;
|
||||||
|
@ -121,8 +123,7 @@ namespace MWRender{
|
||||||
//std::cout << "Name " << copy.sname << "\n";
|
//std::cout << "Name " << copy.sname << "\n";
|
||||||
Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0);
|
Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0);
|
||||||
Ogre::Real* pReal = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
|
Ogre::Real* pReal = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
|
||||||
//Ogre::HardwareVertexBufferSharedPtr vbufNormal = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(1);
|
|
||||||
// Ogre::Real* pRealNormal = static_cast<Ogre::Real*>(vbufNormal->lock(Ogre::HardwareBuffer::HBL_NORMAL));
|
|
||||||
|
|
||||||
std::vector<Ogre::Vector3> initialVertices = copy.morph.getInitialVertices();
|
std::vector<Ogre::Vector3> initialVertices = copy.morph.getInitialVertices();
|
||||||
//Each shape has multiple indices
|
//Each shape has multiple indices
|
||||||
|
@ -181,146 +182,76 @@ namespace MWRender{
|
||||||
std::vector<Nif::NiSkinData::IndividualWeight> inds = iter->second;
|
std::vector<Nif::NiSkinData::IndividualWeight> inds = iter->second;
|
||||||
int verIndex = iter->first;
|
int verIndex = iter->first;
|
||||||
Ogre::Vector3 currentVertex = (*allvertices)[verIndex];
|
Ogre::Vector3 currentVertex = (*allvertices)[verIndex];
|
||||||
|
Ogre::Vector3 currentNormal = (*allnormals)[verIndex];
|
||||||
Nif::NiSkinData::BoneInfoCopy* boneinfocopy = &(allshapesiter->boneinfo[inds[0].boneinfocopyindex]);
|
Nif::NiSkinData::BoneInfoCopy* boneinfocopy = &(allshapesiter->boneinfo[inds[0].boneinfocopyindex]);
|
||||||
Ogre::Bone *bonePtr = 0;
|
Ogre::Bone *bonePtr = 0;
|
||||||
if(useHandles)
|
|
||||||
{
|
|
||||||
bonePtr = skel->getBone(boneinfocopy->bonehandle);
|
|
||||||
}
|
Ogre::Vector3 vecPos;
|
||||||
else
|
Ogre::Quaternion vecRot;
|
||||||
|
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot>::iterator result = vecRotPos.find(boneinfocopy);
|
||||||
|
|
||||||
|
if(result == vecRotPos.end()){
|
||||||
bonePtr = skel->getBone(boneinfocopy->bonename);
|
bonePtr = skel->getBone(boneinfocopy->bonename);
|
||||||
|
|
||||||
Ogre::Vector3 vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
|
|
||||||
Ogre::Quaternion vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
|
|
||||||
|
|
||||||
|
|
||||||
/*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){
|
|
||||||
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
|
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
|
||||||
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
|
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
|
||||||
|
|
||||||
if(useHandles){
|
|
||||||
PosAndRot both;
|
PosAndRot both;
|
||||||
both.vecPos = vecPos;
|
both.vecPos = vecPos;
|
||||||
both.vecRot = vecRot;
|
both.vecRot = vecRot;
|
||||||
vecPosRot[boneinfocopy->bonehandle] = both;
|
vecRotPos[boneinfocopy] = both;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
PosAndRot both = vecPosRot[boneinfocopy->bonehandle];
|
PosAndRot both = result->second;
|
||||||
vecPos = both.vecPos;
|
vecPos = both.vecPos;
|
||||||
vecRot = both.vecRot;
|
vecRot = both.vecRot;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight;
|
Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for(std::size_t i = 1; i < inds.size(); i++){
|
for(std::size_t i = 1; i < inds.size(); i++){
|
||||||
boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]);
|
boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]);
|
||||||
if(useHandles)
|
result = vecRotPos.find(boneinfocopy);
|
||||||
bonePtr = skel->getBone(boneinfocopy->bonehandle);
|
|
||||||
else
|
|
||||||
bonePtr = skel->getBone(boneinfocopy->bonename);
|
|
||||||
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
|
|
||||||
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
|
|
||||||
|
|
||||||
/*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){
|
|
||||||
|
if(result == vecRotPos.end()){
|
||||||
|
bonePtr = skel->getBone(boneinfocopy->bonename);
|
||||||
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
|
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
|
||||||
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
|
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
|
||||||
|
|
||||||
if(useHandles){
|
|
||||||
PosAndRot both;
|
PosAndRot both;
|
||||||
both.vecPos = vecPos;
|
both.vecPos = vecPos;
|
||||||
both.vecRot = vecRot;
|
both.vecRot = vecRot;
|
||||||
vecPosRot[boneinfocopy->bonehandle] = both;
|
vecRotPos[boneinfocopy] = both;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
PosAndRot both = vecPosRot[boneinfocopy->bonehandle];
|
PosAndRot both = result->second;
|
||||||
vecPos = both.vecPos;
|
vecPos = both.vecPos;
|
||||||
vecRot = both.vecRot;
|
vecRot = both.vecRot;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
|
||||||
absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight;
|
absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Ogre::Real* addr = (pReal + 3 * verIndex);
|
Ogre::Real* addr = (pReal + 3 * verIndex);
|
||||||
*addr = absVertPos.x;
|
*addr = absVertPos.x;
|
||||||
*(addr+1) = absVertPos.y;
|
*(addr+1) = absVertPos.y;
|
||||||
*(addr+2) = absVertPos.z;
|
*(addr+2) = absVertPos.z;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (unsigned int i = 0; i < boneinfovector.size(); i++)
|
|
||||||
{
|
|
||||||
Nif::NiSkinData::BoneInfoCopy boneinfo = boneinfovector[i];
|
|
||||||
if(skel->hasBone(boneinfo.bonename)){
|
|
||||||
Ogre::Bone *bonePtr = skel->getBone(boneinfo.bonename);
|
|
||||||
Ogre::Vector3 vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfo.trafo.trans;
|
|
||||||
Ogre::Quaternion vecRot = bonePtr->_getDerivedOrientation() * boneinfo.trafo.rotation;
|
|
||||||
|
|
||||||
for (unsigned int j=0; j < boneinfo.weights.size(); j++)
|
|
||||||
{
|
|
||||||
unsigned int verIndex = boneinfo.weights[j].vertex;
|
|
||||||
if(vertices.find(verIndex) == vertices.end())
|
|
||||||
{
|
|
||||||
Ogre::Vector3 absVertPos = vecPos + vecRot * allvertices[verIndex];
|
|
||||||
absVertPos = absVertPos * boneinfo.weights[j].weight;
|
|
||||||
vertices.insert(verIndex);
|
|
||||||
Ogre::Real* addr = (pReal + 3 * verIndex);
|
|
||||||
*addr = absVertPos.x;
|
|
||||||
*(addr+1) = absVertPos.y;
|
|
||||||
*(addr+2) = absVertPos.z;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
Ogre::Vector3 absVertPos = vecPos + vecRot * allvertices[verIndex];
|
|
||||||
absVertPos = absVertPos * boneinfo.weights[j].weight;
|
|
||||||
Ogre::Vector3 old = Ogre::Vector3(pReal + 3 * verIndex);
|
|
||||||
absVertPos = absVertPos + old;
|
|
||||||
Ogre::Real* addr = (pReal + 3 * verIndex);
|
|
||||||
*addr = absVertPos.x;
|
|
||||||
*(addr+1) = absVertPos.y;
|
|
||||||
*(addr+2) = absVertPos.z;
|
|
||||||
|
|
||||||
//std::cout << "Vertex" << verIndex << "Weight: " << boneinfo.weights[i].weight << "was seen twice\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(normals.find(verIndex) == normals.end())
|
|
||||||
{
|
|
||||||
Ogre::Vector3 absNormalsPos = vecRot * allnormals[verIndex];
|
|
||||||
absNormalsPos = absNormalsPos * boneinfo.weights[j].weight;
|
|
||||||
normals.insert(verIndex);
|
|
||||||
Ogre::Real* addr = (pRealNormal + 3 * verIndex);
|
|
||||||
*addr = absNormalsPos.x;
|
|
||||||
*(addr+1) = absNormalsPos.y;
|
|
||||||
*(addr+2) = absNormalsPos.z;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Ogre::Vector3 absNormalsPos = vecRot * allnormals[verIndex];
|
|
||||||
absNormalsPos = absNormalsPos * boneinfo.weights[j].weight;
|
|
||||||
Ogre::Vector3 old = Ogre::Vector3(pRealNormal + 3 * verIndex);
|
|
||||||
absNormalsPos = absNormalsPos + old;
|
|
||||||
|
|
||||||
Ogre::Real* addr = (pRealNormal + 3 * verIndex);
|
|
||||||
*addr = absNormalsPos.x;
|
|
||||||
*(addr+1) = absNormalsPos.y;
|
|
||||||
*(addr+2) = absNormalsPos.z;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
//} //Comment out
|
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -329,11 +260,13 @@ namespace MWRender{
|
||||||
Ogre::Vector3 shapetrans = copy.trafo.trans;
|
Ogre::Vector3 shapetrans = copy.trafo.trans;
|
||||||
float shapescale = copy.trafo.scale;
|
float shapescale = copy.trafo.scale;
|
||||||
std::vector<std::string> boneSequence = copy.boneSequence;
|
std::vector<std::string> boneSequence = copy.boneSequence;
|
||||||
std::vector<std::string>::iterator boneSequenceIter = boneSequence.begin();
|
|
||||||
Ogre::Vector3 transmult;
|
Ogre::Vector3 transmult;
|
||||||
Ogre::Quaternion rotmult;
|
Ogre::Quaternion rotmult;
|
||||||
float scale;
|
float scale;
|
||||||
if(skel->hasBone(*boneSequenceIter)){
|
if(boneSequence.size() > 0){
|
||||||
|
std::vector<std::string>::iterator boneSequenceIter = boneSequence.begin();
|
||||||
|
if(skel->hasBone(*boneSequenceIter)){
|
||||||
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
|
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
|
||||||
|
|
||||||
|
|
||||||
|
@ -360,6 +293,7 @@ namespace MWRender{
|
||||||
|
|
||||||
//std::cout << "Position: " << transmult << "Rotation: " << rotmult << "\n";
|
//std::cout << "Position: " << transmult << "Rotation: " << rotmult << "\n";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
transmult = shapetrans;
|
transmult = shapetrans;
|
||||||
|
@ -392,7 +326,7 @@ namespace MWRender{
|
||||||
|
|
||||||
}
|
}
|
||||||
vbuf->unlock();
|
vbuf->unlock();
|
||||||
//vbufNormal->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -465,22 +399,18 @@ namespace MWRender{
|
||||||
|
|
||||||
base->getAllAnimationStates()->_notifyDirty();
|
base->getAllAnimationStates()->_notifyDirty();
|
||||||
//base->_updateAnimation();
|
//base->_updateAnimation();
|
||||||
base->_notifyMoved();
|
//base->_notifyMoved();
|
||||||
|
|
||||||
for(unsigned int i = 0; i < entityparts.size(); i++){
|
for(unsigned int i = 0; i < entityparts.size(); i++){
|
||||||
Ogre::SkeletonInstance* skel = entityparts[i]->getSkeleton();
|
//Ogre::SkeletonInstance* skel = entityparts[i]->getSkeleton();
|
||||||
|
|
||||||
Ogre::Bone* b = skel->getRootBone();
|
Ogre::Bone* b = skel->getRootBone();
|
||||||
b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3));//This is a trick
|
b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3));//This is a trick
|
||||||
|
|
||||||
skel->_updateTransforms();
|
|
||||||
// skel->_notifyManualBonesDirty();
|
|
||||||
|
|
||||||
entityparts[i]->getAllAnimationStates()->_notifyDirty();
|
entityparts[i]->getAllAnimationStates()->_notifyDirty();
|
||||||
//entityparts[i]->_updateAnimation();
|
|
||||||
entityparts[i]->_notifyMoved();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<Nif::NiKeyframeData>::iterator iter;
|
std::vector<Nif::NiKeyframeData>::iterator iter;
|
||||||
int slot = 0;
|
int slot = 0;
|
||||||
if(transformations){
|
if(transformations){
|
||||||
|
@ -488,9 +418,7 @@ namespace MWRender{
|
||||||
if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime())
|
if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime())
|
||||||
{
|
{
|
||||||
slot++;
|
slot++;
|
||||||
//iter++;
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float x;
|
float x;
|
||||||
|
@ -511,7 +439,6 @@ namespace MWRender{
|
||||||
|
|
||||||
timeIndex(time, ttime, tindexI[slot], tindexJ, x);
|
timeIndex(time, ttime, tindexI[slot], tindexJ, x);
|
||||||
|
|
||||||
//std::cout << "X: " << x << " X2: " << x2 << "\n";
|
|
||||||
Ogre::Vector3 t;
|
Ogre::Vector3 t;
|
||||||
Ogre::Quaternion r;
|
Ogre::Quaternion r;
|
||||||
|
|
||||||
|
@ -526,7 +453,6 @@ namespace MWRender{
|
||||||
bool bQuats = quats.size() > 0;
|
bool bQuats = quats.size() > 0;
|
||||||
if(bQuats){
|
if(bQuats){
|
||||||
r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true);
|
r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true);
|
||||||
//bone->setOrientation(r);
|
|
||||||
}
|
}
|
||||||
skel = base->getSkeleton();
|
skel = base->getSkeleton();
|
||||||
if(skel->hasBone(iter->getBonename())){
|
if(skel->hasBone(iter->getBonename())){
|
||||||
|
@ -539,27 +465,10 @@ namespace MWRender{
|
||||||
|
|
||||||
|
|
||||||
skel->_updateTransforms();
|
skel->_updateTransforms();
|
||||||
//skel->_notifyManualBonesDirty();
|
|
||||||
base->getAllAnimationStates()->_notifyDirty();
|
base->getAllAnimationStates()->_notifyDirty();
|
||||||
//base->_updateAnimation();
|
|
||||||
base->_notifyMoved();
|
|
||||||
}
|
|
||||||
for(std::size_t i = 0; i < entityparts.size(); i++){
|
|
||||||
skel = entityparts[i]->getSkeleton();
|
|
||||||
if(skel->hasBone(iter->getBonename())){
|
|
||||||
Ogre::Bone* bone = skel->getBone(iter->getBonename());
|
|
||||||
if(bTrans)
|
|
||||||
bone->setPosition(t);
|
|
||||||
if(bQuats)
|
|
||||||
bone->setOrientation(r);
|
|
||||||
|
|
||||||
skel->_updateTransforms();
|
}
|
||||||
//skel->_notifyManualBonesDirty();
|
|
||||||
entityparts[i]->getAllAnimationStates()->_notifyDirty();
|
|
||||||
// entityparts[i]->_updateAnimation();
|
|
||||||
entityparts[i]->_notifyMoved();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
slot++;
|
slot++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ class Animation{
|
||||||
Ogre::SceneNode* insert;
|
Ogre::SceneNode* insert;
|
||||||
OEngine::Render::OgreRenderer &mRend;
|
OEngine::Render::OgreRenderer &mRend;
|
||||||
MWWorld::Environment& mEnvironment;
|
MWWorld::Environment& mEnvironment;
|
||||||
|
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot> vecRotPos;
|
||||||
static std::map<std::string, int> mUniqueIDs;
|
static std::map<std::string, int> mUniqueIDs;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureAnimation::runAnimation(float timepassed){
|
void CreatureAnimation::runAnimation(float timepassed){
|
||||||
|
vecRotPos.clear();
|
||||||
if(animate > 0){
|
if(animate > 0){
|
||||||
//Add the amount of time passed to time
|
//Add the amount of time passed to time
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
||||||
char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2);
|
char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2);
|
||||||
bool female = tolower(secondtolast) == 'f';
|
bool female = tolower(secondtolast) == 'f';
|
||||||
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
|
bool beast = 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){
|
||||||
std::cout << " Sex: Female" << " Height: " << race->data.height.female << "\n";
|
std::cout << " Sex: Female" << " Height: " << race->data.height.female << "\n";
|
||||||
|
@ -67,6 +68,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
||||||
//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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if((transformations = (NIFLoader::getSingletonPtr())->getAnim(smodel))){
|
if((transformations = (NIFLoader::getSingletonPtr())->getAnim(smodel))){
|
||||||
|
|
||||||
for(unsigned int init = 0; init < transformations->size(); init++){
|
for(unsigned int init = 0; init < transformations->size(); init++){
|
||||||
|
@ -177,7 +179,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
||||||
if(clavicler)
|
if(clavicler)
|
||||||
insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/
|
insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/
|
||||||
|
|
||||||
|
|
||||||
if(neck)
|
if(neck)
|
||||||
{
|
{
|
||||||
insertBoundedPart("meshes\\" + neck->model, "Neck");
|
insertBoundedPart("meshes\\" + neck->model, "Neck");
|
||||||
|
@ -213,6 +214,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
Entity* ent = mRend.getScene()->createEntity(mesh);
|
||||||
|
|
||||||
|
@ -225,15 +227,7 @@ void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suf
|
||||||
|
|
||||||
Ogre::Entity* ent = mRend.getScene()->createEntity(meshNumbered);
|
Ogre::Entity* ent = mRend.getScene()->createEntity(meshNumbered);
|
||||||
|
|
||||||
/*MaterialPtr material = ent->getSubEntity(0)->getMaterial();
|
|
||||||
material->removeAllTechniques();
|
|
||||||
|
|
||||||
Ogre::Technique* tech = material->createTechnique();
|
|
||||||
|
|
||||||
Pass* pass2 = tech->createPass();
|
|
||||||
pass2->setVertexProgram("Ogre/HardwareSkinningTwoWeights");
|
|
||||||
pass2->setColourWriteEnabled(false);
|
|
||||||
//tech->setSchemeName("blahblah");*/
|
|
||||||
|
|
||||||
|
|
||||||
insert->attachObject(ent);
|
insert->attachObject(ent);
|
||||||
|
@ -249,6 +243,7 @@ void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suf
|
||||||
|
|
||||||
|
|
||||||
void NpcAnimation::runAnimation(float timepassed){
|
void NpcAnimation::runAnimation(float 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
|
||||||
|
@ -267,22 +262,17 @@ void NpcAnimation::runAnimation(float timepassed){
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAnimationTransforms();
|
handleAnimationTransforms();
|
||||||
Ogre::Vector3 current = insert->_getWorldAABB().getCenter();
|
|
||||||
|
|
||||||
std::vector<std::vector<Nif::NiTriShapeCopy>*>::iterator shapepartsiter = shapeparts.begin();
|
std::vector<std::vector<Nif::NiTriShapeCopy>*>::iterator shapepartsiter = shapeparts.begin();
|
||||||
std::vector<Ogre::Entity*>::iterator entitypartsiter = entityparts.begin();
|
std::vector<Ogre::Entity*>::iterator entitypartsiter = entityparts.begin();
|
||||||
while(shapepartsiter != shapeparts.end())
|
while(shapepartsiter != shapeparts.end())
|
||||||
{
|
{
|
||||||
|
vecRotPos.clear();
|
||||||
std::vector<Nif::NiTriShapeCopy>* shapes = *shapepartsiter;
|
std::vector<Nif::NiTriShapeCopy>* shapes = *shapepartsiter;
|
||||||
Ogre::Entity* theentity = *entitypartsiter;
|
Ogre::Entity* theentity = *entitypartsiter;
|
||||||
/*
|
|
||||||
Pass* pass = theentity->getSubEntity(0)->getMaterial()->getBestTechnique()->getPass(0);
|
|
||||||
if (pass->hasVertexProgram() && pass->getVertexProgram()->isSkeletalAnimationIncluded())
|
|
||||||
std::cout << "It's hardware\n";
|
|
||||||
else
|
|
||||||
std::cout << "It's software\n";*/
|
|
||||||
|
|
||||||
handleShapes(shapes, theentity, theentity->getSkeleton());
|
|
||||||
|
handleShapes(shapes, theentity, base->getSkeleton());
|
||||||
shapepartsiter++;
|
shapepartsiter++;
|
||||||
entitypartsiter++;
|
entitypartsiter++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include "objects.hpp"
|
#include "objects.hpp"
|
||||||
|
|
||||||
#include <OgreSceneNode.h>
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
#include <components/nifogre/ogre_nif_loader.hpp>
|
#include <components/nifogre/ogre_nif_loader.hpp>
|
||||||
|
|
||||||
using namespace Ogre;
|
|
||||||
using namespace MWRender;
|
using namespace MWRender;
|
||||||
|
|
||||||
|
|
||||||
bool Objects::lightConst = false;
|
bool Objects::lightConst = false;
|
||||||
float Objects::lightConstValue = 0.0f;
|
float Objects::lightConstValue = 0.0f;
|
||||||
|
|
||||||
|
@ -23,10 +23,24 @@ bool Objects::lightOutQuadInLin = false;
|
||||||
|
|
||||||
int Objects::uniqueID = 0;
|
int Objects::uniqueID = 0;
|
||||||
|
|
||||||
void Objects::setMwRoot(Ogre::SceneNode* root){
|
void Objects::clearSceneNode (Ogre::SceneNode *node)
|
||||||
|
{
|
||||||
|
/// \todo This should probably be moved into OpenEngine at some point.
|
||||||
|
for (int i=node->numAttachedObjects()-1; i>=0; --i)
|
||||||
|
{
|
||||||
|
Ogre::MovableObject *object = node->getAttachedObject (i);
|
||||||
|
node->detachObject (object);
|
||||||
|
mRenderer.getScene()->destroyMovableObject (object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Objects::setMwRoot(Ogre::SceneNode* root)
|
||||||
|
{
|
||||||
mMwRoot = root;
|
mMwRoot = root;
|
||||||
}
|
}
|
||||||
void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){
|
|
||||||
|
void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
|
||||||
|
{
|
||||||
Ogre::SceneNode* root = mMwRoot;
|
Ogre::SceneNode* root = mMwRoot;
|
||||||
Ogre::SceneNode* cellnode;
|
Ogre::SceneNode* cellnode;
|
||||||
if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
|
if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
|
||||||
|
@ -49,90 +63,98 @@ void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){
|
||||||
f = ptr.getCellRef().pos.rot;
|
f = ptr.getCellRef().pos.rot;
|
||||||
|
|
||||||
// Rotate around X axis
|
// Rotate around X axis
|
||||||
Quaternion xr(Radian(-f[0]), Vector3::UNIT_X);
|
Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X);
|
||||||
|
|
||||||
// Rotate around Y axis
|
// Rotate around Y axis
|
||||||
Quaternion yr(Radian(-f[1]), Vector3::UNIT_Y);
|
Ogre::Quaternion yr(Ogre::Radian(-f[1]), Ogre::Vector3::UNIT_Y);
|
||||||
|
|
||||||
// Rotate around Z axis
|
// Rotate around Z axis
|
||||||
Quaternion zr(Radian(-f[2]), Vector3::UNIT_Z);
|
Ogre::Quaternion zr(Ogre::Radian(-f[2]), Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
// Rotates first around z, then y, then x
|
// Rotates first around z, then y, then x
|
||||||
insert->setOrientation(xr*yr*zr);
|
insert->setOrientation(xr*yr*zr);
|
||||||
|
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
insert->setVisible (false);
|
insert->setVisible (false);
|
||||||
ptr.getRefData().setBaseNode(insert);
|
ptr.getRefData().setBaseNode(insert);
|
||||||
isStatic = static_;
|
mIsStatic = static_;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh){
|
|
||||||
|
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
|
||||||
|
{
|
||||||
Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
|
Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
|
||||||
assert(insert);
|
assert(insert);
|
||||||
|
|
||||||
NifOgre::NIFLoader::load(mesh);
|
NifOgre::NIFLoader::load(mesh);
|
||||||
Entity *ent = mRend.getScene()->createEntity(mesh);
|
Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh);
|
||||||
|
|
||||||
if(!isStatic)
|
if(!mIsStatic)
|
||||||
{
|
{
|
||||||
insert->attachObject(ent);
|
insert->attachObject(ent);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Ogre::StaticGeometry* sg = 0;
|
Ogre::StaticGeometry* sg = 0;
|
||||||
if(mSG.find(ptr.getCell()) == mSG.end())
|
if(mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end())
|
||||||
{
|
{
|
||||||
uniqueID = uniqueID +1;
|
uniqueID = uniqueID +1;
|
||||||
sg = mRend.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
|
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
|
||||||
//Create the scenenode and put it in the map
|
//Create the scenenode and put it in the map
|
||||||
mSG[ptr.getCell()] = sg;
|
mStaticGeometry[ptr.getCell()] = sg;
|
||||||
|
|
||||||
|
// This specifies the size of a single batch region.
|
||||||
|
// If it is set too high:
|
||||||
|
// - there will be problems choosing the correct lights
|
||||||
|
// - the culling will be more inefficient
|
||||||
|
// If it is set too low:
|
||||||
|
// - there will be too many batches.
|
||||||
|
sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sg = mSG[ptr.getCell()];
|
sg = mStaticGeometry[ptr.getCell()];
|
||||||
}
|
}
|
||||||
|
|
||||||
sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
|
sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
|
||||||
sg->setRegionDimensions(Ogre::Vector3(100000,10000,100000));
|
|
||||||
|
|
||||||
|
mRenderer.getScene()->destroyEntity(ent);
|
||||||
mRend.getScene()->destroyEntity(ent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius){
|
|
||||||
Ogre::SceneNode* insert = mRend.getScene()->getSceneNode(ptr.getRefData().getHandle());
|
void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius)
|
||||||
|
{
|
||||||
|
Ogre::SceneNode* insert = mRenderer.getScene()->getSceneNode(ptr.getRefData().getHandle());
|
||||||
assert(insert);
|
assert(insert);
|
||||||
Ogre::Light *light = mRend.getScene()->createLight();
|
Ogre::Light *light = mRenderer.getScene()->createLight();
|
||||||
light->setDiffuseColour (r, g, b);
|
light->setDiffuseColour (r, g, b);
|
||||||
|
|
||||||
float cval=0.0f, lval=0.0f, qval=0.0f;
|
float cval=0.0f, lval=0.0f, qval=0.0f;
|
||||||
|
|
||||||
if(lightConst)
|
if(lightConst)
|
||||||
cval = lightConstValue;
|
cval = lightConstValue;
|
||||||
if(!lightOutQuadInLin)
|
|
||||||
{
|
|
||||||
if(lightLinear)
|
|
||||||
radius *= lightLinearRadiusMult;
|
|
||||||
if(lightQuadratic)
|
|
||||||
radius *= lightQuadraticRadiusMult;
|
|
||||||
|
|
||||||
if(lightLinear)
|
if(!lightOutQuadInLin)
|
||||||
lval = lightLinearValue / pow(radius, lightLinearMethod);
|
{
|
||||||
if(lightQuadratic)
|
if(lightLinear)
|
||||||
qval = lightQuadraticValue / pow(radius, lightQuadraticMethod);
|
radius *= lightLinearRadiusMult;
|
||||||
}
|
if(lightQuadratic)
|
||||||
else
|
radius *= lightQuadraticRadiusMult;
|
||||||
{
|
|
||||||
// FIXME:
|
|
||||||
// Do quadratic or linear, depending if we're in an exterior or interior
|
|
||||||
// cell, respectively. Ignore lightLinear and lightQuadratic.
|
|
||||||
}
|
|
||||||
|
|
||||||
light->setAttenuation(10*radius, cval, lval, qval);
|
if(lightLinear)
|
||||||
|
lval = lightLinearValue / pow(radius, lightLinearMethod);
|
||||||
|
if(lightQuadratic)
|
||||||
|
qval = lightQuadraticValue / pow(radius, lightQuadraticMethod);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// FIXME:
|
||||||
|
// Do quadratic or linear, depending if we're in an exterior or interior
|
||||||
|
// cell, respectively. Ignore lightLinear and lightQuadratic.
|
||||||
|
}
|
||||||
|
|
||||||
insert->attachObject(light);
|
light->setAttenuation(10*radius, cval, lval, qval);
|
||||||
|
|
||||||
|
insert->attachObject(light);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Objects::deleteObject (const MWWorld::Ptr& ptr)
|
bool Objects::deleteObject (const MWWorld::Ptr& ptr)
|
||||||
|
@ -145,8 +167,9 @@ bool Objects::deleteObject (const MWWorld::Ptr& ptr)
|
||||||
mCellSceneNodes.begin()); iter!=mCellSceneNodes.end(); ++iter)
|
mCellSceneNodes.begin()); iter!=mCellSceneNodes.end(); ++iter)
|
||||||
if (iter->second==parent)
|
if (iter->second==parent)
|
||||||
{
|
{
|
||||||
|
clearSceneNode (base);
|
||||||
base->removeAndDestroyAllChildren();
|
base->removeAndDestroyAllChildren();
|
||||||
mRend.getScene()->destroySceneNode (base);
|
mRenderer.getScene()->destroySceneNode (base);
|
||||||
ptr.getRefData().setBaseNode (0);
|
ptr.getRefData().setBaseNode (0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -157,29 +180,35 @@ bool Objects::deleteObject (const MWWorld::Ptr& ptr)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Objects::removeCell(MWWorld::Ptr::CellStore* store){
|
void Objects::removeCell(MWWorld::Ptr::CellStore* store)
|
||||||
|
{
|
||||||
if(mCellSceneNodes.find(store) != mCellSceneNodes.end())
|
if(mCellSceneNodes.find(store) != mCellSceneNodes.end())
|
||||||
{
|
{
|
||||||
Ogre::SceneNode* base = mCellSceneNodes[store];
|
Ogre::SceneNode* base = mCellSceneNodes[store];
|
||||||
|
|
||||||
|
for (int i=0; i<base->numChildren(); ++i)
|
||||||
|
clearSceneNode (static_cast<Ogre::SceneNode *> (base->getChild (i)));
|
||||||
|
|
||||||
base->removeAndDestroyAllChildren();
|
base->removeAndDestroyAllChildren();
|
||||||
mCellSceneNodes.erase(store);
|
mCellSceneNodes.erase(store);
|
||||||
mRend.getScene()->destroySceneNode(base);
|
mRenderer.getScene()->destroySceneNode(base);
|
||||||
base = 0;
|
base = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mStaticGeometry.find(store) != mStaticGeometry.end())
|
||||||
if(mSG.find(store) != mSG.end())
|
|
||||||
{
|
{
|
||||||
Ogre::StaticGeometry* sg = mSG[store];
|
Ogre::StaticGeometry* sg = mStaticGeometry[store];
|
||||||
mSG.erase(store);
|
mStaticGeometry.erase(store);
|
||||||
mRend.getScene()->destroyStaticGeometry (sg);
|
mRenderer.getScene()->destroyStaticGeometry (sg);
|
||||||
sg = 0;
|
sg = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Objects::buildStaticGeometry(ESMS::CellStore<MWWorld::RefData>& cell){
|
|
||||||
if(mSG.find(&cell) != mSG.end())
|
void Objects::buildStaticGeometry(ESMS::CellStore<MWWorld::RefData>& cell)
|
||||||
|
{
|
||||||
|
if(mStaticGeometry.find(&cell) != mStaticGeometry.end())
|
||||||
{
|
{
|
||||||
Ogre::StaticGeometry* sg = mSG[&cell];
|
Ogre::StaticGeometry* sg = mStaticGeometry[&cell];
|
||||||
sg->build();
|
sg->build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
#ifndef _GAME_RENDER_OBJECTS_H
|
#ifndef _GAME_RENDER_OBJECTS_H
|
||||||
#define _GAME_RENDER_OBJECTS_H
|
#define _GAME_RENDER_OBJECTS_H
|
||||||
|
|
||||||
#include "components/esm_store/cell_store.hpp"
|
#include <openengine/ogre/renderer.hpp>
|
||||||
|
|
||||||
|
#include <components/esm_store/cell_store.hpp>
|
||||||
|
|
||||||
#include "../mwworld/refdata.hpp"
|
#include "../mwworld/refdata.hpp"
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include <openengine/ogre/renderer.hpp>
|
|
||||||
|
|
||||||
namespace MWRender{
|
namespace MWRender{
|
||||||
|
|
||||||
class Objects{
|
class Objects{
|
||||||
OEngine::Render::OgreRenderer &mRend;
|
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*> mSG;
|
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry;
|
||||||
Ogre::SceneNode* mMwRoot;
|
Ogre::SceneNode* mMwRoot;
|
||||||
bool isStatic;
|
bool mIsStatic;
|
||||||
static int uniqueID;
|
static int uniqueID;
|
||||||
static bool lightConst;
|
static bool lightConst;
|
||||||
static float lightConstValue;
|
static float lightConstValue;
|
||||||
|
@ -30,8 +31,12 @@ class Objects{
|
||||||
static float lightQuadraticRadiusMult;
|
static float lightQuadraticRadiusMult;
|
||||||
|
|
||||||
static bool lightOutQuadInLin;
|
static bool lightOutQuadInLin;
|
||||||
|
|
||||||
|
void clearSceneNode (Ogre::SceneNode *node);
|
||||||
|
///< Remove all movable objects from \a node.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Objects(OEngine::Render::OgreRenderer& _rend): mRend(_rend){}
|
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);
|
||||||
|
|
|
@ -20,10 +20,9 @@ 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, MWWorld::Environment& environment)
|
||||||
:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mDebugging(engine)
|
:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0), mDebugging(engine)
|
||||||
{
|
{
|
||||||
mRendering.createScene("PlayerCam", 55, 5);
|
mRendering.createScene("PlayerCam", 55, 5);
|
||||||
mSkyManager = MWRender::SkyManager::create(mRendering.getWindow(), mRendering.getCamera(), resDir);
|
|
||||||
|
|
||||||
// Set default mipmap level (NB some APIs ignore this)
|
// Set default mipmap level (NB some APIs ignore this)
|
||||||
TextureManager::getSingleton().setDefaultNumMipmaps(5);
|
TextureManager::getSingleton().setDefaultNumMipmaps(5);
|
||||||
|
@ -41,7 +40,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
||||||
mMwRoot->pitch(Degree(-90));
|
mMwRoot->pitch(Degree(-90));
|
||||||
mObjects.setMwRoot(mMwRoot);
|
mObjects.setMwRoot(mMwRoot);
|
||||||
mActors.setMwRoot(mMwRoot);
|
mActors.setMwRoot(mMwRoot);
|
||||||
|
|
||||||
//used to obtain ingame information of ogre objects (which are faced or selected)
|
//used to obtain ingame information of ogre objects (which are faced or selected)
|
||||||
mRaySceneQuery = mRendering.getScene()->createRayQuery(Ray());
|
mRaySceneQuery = mRendering.getScene()->createRayQuery(Ray());
|
||||||
|
|
||||||
|
@ -50,6 +49,9 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
||||||
Ogre::SceneNode *cameraYawNode = playerNode->createChildSceneNode();
|
Ogre::SceneNode *cameraYawNode = playerNode->createChildSceneNode();
|
||||||
Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode();
|
Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode();
|
||||||
cameraPitchNode->attachObject(mRendering.getCamera());
|
cameraPitchNode->attachObject(mRendering.getCamera());
|
||||||
|
|
||||||
|
//mSkyManager = 0;
|
||||||
|
mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera());
|
||||||
|
|
||||||
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
|
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
|
||||||
mSun = 0;
|
mSun = 0;
|
||||||
|
@ -62,6 +64,10 @@ RenderingManager::~RenderingManager ()
|
||||||
delete mSkyManager;
|
delete mSkyManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWRender::SkyManager* RenderingManager::getSkyManager()
|
||||||
|
{
|
||||||
|
return mSkyManager;
|
||||||
|
}
|
||||||
|
|
||||||
MWRender::Objects& RenderingManager::getObjects(){
|
MWRender::Objects& RenderingManager::getObjects(){
|
||||||
return mObjects;
|
return mObjects;
|
||||||
|
@ -74,6 +80,11 @@ MWRender::Player& RenderingManager::getPlayer(){
|
||||||
return (*mPlayer);
|
return (*mPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OEngine::Render::Fader* RenderingManager::getFader()
|
||||||
|
{
|
||||||
|
return mRendering.getFader();
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store){
|
void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store){
|
||||||
mObjects.removeCell(store);
|
mObjects.removeCell(store);
|
||||||
mActors.removeCell(store);
|
mActors.removeCell(store);
|
||||||
|
@ -122,31 +133,40 @@ 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);
|
||||||
|
|
||||||
|
mSkyManager->update(duration);
|
||||||
|
|
||||||
|
mRendering.update(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::skyEnable ()
|
void RenderingManager::skyEnable ()
|
||||||
{
|
{
|
||||||
|
if(mSkyManager)
|
||||||
mSkyManager->enable();
|
mSkyManager->enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::skyDisable ()
|
void RenderingManager::skyDisable ()
|
||||||
{
|
{
|
||||||
mSkyManager->disable();
|
if(mSkyManager)
|
||||||
|
mSkyManager->disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::skySetHour (double hour)
|
void RenderingManager::skySetHour (double hour)
|
||||||
{
|
{
|
||||||
mSkyManager->setHour(hour);
|
if(mSkyManager)
|
||||||
|
mSkyManager->setHour(hour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderingManager::skySetDate (int day, int month)
|
void RenderingManager::skySetDate (int day, int month)
|
||||||
{
|
{
|
||||||
mSkyManager->setDate(day, month);
|
if(mSkyManager)
|
||||||
|
mSkyManager->setDate(day, month);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RenderingManager::skyGetMasserPhase() const
|
int RenderingManager::skyGetMasserPhase() const
|
||||||
{
|
{
|
||||||
|
|
||||||
return mSkyManager->getMasserPhase();
|
return mSkyManager->getMasserPhase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,12 +175,28 @@ int RenderingManager::skyGetSecundaPhase() const
|
||||||
return mSkyManager->getSecundaPhase();
|
return mSkyManager->getSecundaPhase();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::skySetMoonColour (bool red)
|
void RenderingManager::skySetMoonColour (bool red){
|
||||||
{
|
if(mSkyManager)
|
||||||
mSkyManager->setMoonColour(red);
|
mSkyManager->setMoonColour(red);
|
||||||
}
|
}
|
||||||
bool RenderingManager::toggleRenderMode(int mode){
|
|
||||||
return mDebugging.toggleRenderMode(mode);
|
bool RenderingManager::toggleRenderMode(int mode)
|
||||||
|
{
|
||||||
|
if (mode == MWWorld::World::Render_CollisionDebug)
|
||||||
|
return mDebugging.toggleRenderMode(mode);
|
||||||
|
else // if (mode == MWWorld::World::Render_Wireframe)
|
||||||
|
{
|
||||||
|
if (mRendering.getCamera()->getPolygonMode() == PM_SOLID)
|
||||||
|
{
|
||||||
|
mRendering.getCamera()->setPolygonMode(PM_WIREFRAME);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mRendering.getCamera()->setPolygonMode(PM_SOLID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
|
void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
|
||||||
|
@ -168,14 +204,22 @@ 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);
|
||||||
|
|
||||||
float high = 4500 + 9000 * (1-mCell.cell->ambi.fogDensity);
|
configureFog(mCell.cell->ambi.fogDensity, color);
|
||||||
float low = 200;
|
|
||||||
|
|
||||||
mRendering.getScene()->setFog (FOG_LINEAR, color, 0, low, high);
|
|
||||||
mRendering.getCamera()->setFarClipDistance (high + 10);
|
|
||||||
mRendering.getViewport()->setBackgroundColour (color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
|
||||||
|
{
|
||||||
|
/// \todo make the viewing distance and fog start/end configurable
|
||||||
|
float low = 3000 / density;
|
||||||
|
float high = 6200 / density;
|
||||||
|
|
||||||
|
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
|
||||||
|
|
||||||
|
mRendering.getCamera()->setFarClipDistance ( high );
|
||||||
|
mRendering.getViewport()->setBackgroundColour (colour);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderingManager::setAmbientMode()
|
void RenderingManager::setAmbientMode()
|
||||||
{
|
{
|
||||||
switch (mAmbientMode)
|
switch (mAmbientMode)
|
||||||
|
@ -244,4 +288,38 @@ void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr)
|
||||||
mActors.skipAnimation(ptr);
|
mActors.skipAnimation(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingManager::setSunColour(const Ogre::ColourValue& colour)
|
||||||
|
{
|
||||||
|
mSun->setDiffuseColour(colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour)
|
||||||
|
{
|
||||||
|
mRendering.getScene()->setAmbientLight(colour);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingManager::sunEnable()
|
||||||
|
{
|
||||||
|
if (mSun) mSun->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingManager::sunDisable()
|
||||||
|
{
|
||||||
|
if (mSun) mSun->setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingManager::setSunDirection(const Ogre::Vector3& direction)
|
||||||
|
{
|
||||||
|
// direction * -1 (because 'direction' is camera to sun vector and not sun to camera),
|
||||||
|
// then convert from MW to ogre coordinates (swap y,z and make y negative)
|
||||||
|
if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.z, direction.y));
|
||||||
|
|
||||||
|
mSkyManager->setSunDirection(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingManager::setGlare(bool glare)
|
||||||
|
{
|
||||||
|
mSkyManager->setGlare(glare);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <openengine/ogre/renderer.hpp>
|
#include <openengine/ogre/renderer.hpp>
|
||||||
|
#include <openengine/ogre/fader.hpp>
|
||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -61,8 +62,12 @@ class RenderingManager: private RenderingInterface {
|
||||||
/// MWWorld::Player has been rewritten to not need access
|
/// MWWorld::Player has been rewritten to not need access
|
||||||
/// to internal details of the rendering system anymore
|
/// to internal details of the rendering system anymore
|
||||||
|
|
||||||
|
SkyManager* getSkyManager();
|
||||||
|
|
||||||
void toggleLight();
|
void toggleLight();
|
||||||
bool toggleRenderMode(int mode);
|
bool toggleRenderMode(int mode);
|
||||||
|
|
||||||
|
OEngine::Render::Fader* getFader();
|
||||||
|
|
||||||
void removeCell (MWWorld::Ptr::CellStore *store);
|
void removeCell (MWWorld::Ptr::CellStore *store);
|
||||||
|
|
||||||
|
@ -81,7 +86,14 @@ class RenderingManager: private RenderingInterface {
|
||||||
void moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Vector3& position, MWWorld::Ptr::CellStore *store);
|
void moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Vector3& position, MWWorld::Ptr::CellStore *store);
|
||||||
|
|
||||||
void update (float duration);
|
void update (float duration);
|
||||||
|
|
||||||
|
void setAmbientColour(const Ogre::ColourValue& colour);
|
||||||
|
void setSunColour(const Ogre::ColourValue& colour);
|
||||||
|
void setSunDirection(const Ogre::Vector3& direction);
|
||||||
|
void sunEnable();
|
||||||
|
void sunDisable();
|
||||||
|
|
||||||
|
void setGlare(bool glare);
|
||||||
void skyEnable ();
|
void skyEnable ();
|
||||||
void skyDisable ();
|
void skyDisable ();
|
||||||
void skySetHour (double hour);
|
void skySetHour (double hour);
|
||||||
|
@ -90,9 +102,13 @@ class RenderingManager: private RenderingInterface {
|
||||||
int skyGetSecundaPhase() const;
|
int skyGetSecundaPhase() const;
|
||||||
void skySetMoonColour (bool red);
|
void skySetMoonColour (bool red);
|
||||||
void configureAmbient(ESMS::CellStore<MWWorld::RefData> &mCell);
|
void configureAmbient(ESMS::CellStore<MWWorld::RefData> &mCell);
|
||||||
|
|
||||||
/// configure fog according to cell
|
/// configure fog according to cell
|
||||||
void configureFog(ESMS::CellStore<MWWorld::RefData> &mCell);
|
void configureFog(ESMS::CellStore<MWWorld::RefData> &mCell);
|
||||||
|
|
||||||
|
/// configure fog manually
|
||||||
|
void configureFog(const float density, const Ogre::ColourValue& colour);
|
||||||
|
|
||||||
void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode,
|
void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode,
|
||||||
int number = 1);
|
int number = 1);
|
||||||
///< Run animation for a MW-reference. Calls to this function for references that are currently not
|
///< Run animation for a MW-reference. Calls to this function for references that are currently not
|
||||||
|
@ -108,7 +124,9 @@ class RenderingManager: private RenderingInterface {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void setAmbientMode();
|
void setAmbientMode();
|
||||||
|
|
||||||
SkyManager* mSkyManager;
|
SkyManager* mSkyManager;
|
||||||
|
|
||||||
OEngine::Render::OgreRenderer &mRendering;
|
OEngine::Render::OgreRenderer &mRendering;
|
||||||
|
|
||||||
MWRender::Objects mObjects;
|
MWRender::Objects mObjects;
|
||||||
|
|
|
@ -1,116 +1,764 @@
|
||||||
#include "sky.hpp"
|
#include "sky.hpp"
|
||||||
#include "Caelum.h"
|
|
||||||
|
|
||||||
namespace MWRender
|
#include <OgreCamera.h>
|
||||||
|
#include <OgreRenderWindow.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
#include <OgreMesh.h>
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
#include <OgreHardwareVertexBuffer.h>
|
||||||
|
#include <OgreHighLevelGpuProgramManager.h>
|
||||||
|
|
||||||
|
#include <components/nifogre/ogre_nif_loader.hpp>
|
||||||
|
|
||||||
|
using namespace MWRender;
|
||||||
|
using namespace Ogre;
|
||||||
|
|
||||||
|
// the speed at which the clouds are animated
|
||||||
|
#define CLOUD_SPEED 0.001
|
||||||
|
|
||||||
|
// this distance has to be set accordingly so that the
|
||||||
|
// celestial bodies are behind the clouds, but in front of the atmosphere
|
||||||
|
#define CELESTIAL_BODY_DISTANCE 1000.f
|
||||||
|
|
||||||
|
BillboardObject::BillboardObject( const String& textureName,
|
||||||
|
const float initialSize,
|
||||||
|
const Vector3& position,
|
||||||
|
SceneNode* rootNode)
|
||||||
{
|
{
|
||||||
//
|
init(textureName, initialSize, position, rootNode);
|
||||||
// Implements a Caelum sky with default settings.
|
}
|
||||||
//
|
|
||||||
// Note: this is intended as a temporary solution to provide some form of
|
BillboardObject::BillboardObject()
|
||||||
// sky rendering. This code will obviously need significant tailoring to
|
{
|
||||||
// support fidelity with Morrowind's rendering. Before doing major work
|
}
|
||||||
// on this class, more research should be done to determine whether
|
|
||||||
// Caelum or another plug-in such as SkyX would be best for the long-term.
|
void BillboardObject::setVisible(const bool visible)
|
||||||
//
|
{
|
||||||
class CaelumManager : public SkyManager
|
mNode->setVisible(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BillboardObject::setSize(const float size)
|
||||||
|
{
|
||||||
|
mNode->setScale(size, size, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BillboardObject::setVisibility(const float visibility)
|
||||||
|
{
|
||||||
|
mMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, visibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BillboardObject::setPosition(const Vector3& pPosition)
|
||||||
|
{
|
||||||
|
Vector3 normalised = pPosition.normalisedCopy();
|
||||||
|
Vector3 finalPosition = normalised * CELESTIAL_BODY_DISTANCE;
|
||||||
|
|
||||||
|
mBBSet->setCommonDirection( -normalised );
|
||||||
|
|
||||||
|
mNode->setPosition(finalPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 BillboardObject::getPosition() const
|
||||||
|
{
|
||||||
|
return mNode->getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BillboardObject::setColour(const ColourValue& pColour)
|
||||||
|
{
|
||||||
|
mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(pColour);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BillboardObject::setRenderQueue(unsigned int id)
|
||||||
|
{
|
||||||
|
mBBSet->setRenderQueueGroup(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneNode* BillboardObject::getNode()
|
||||||
|
{
|
||||||
|
return mNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BillboardObject::init(const String& textureName,
|
||||||
|
const float initialSize,
|
||||||
|
const Vector3& position,
|
||||||
|
SceneNode* rootNode)
|
||||||
|
{
|
||||||
|
SceneManager* sceneMgr = rootNode->getCreator();
|
||||||
|
|
||||||
|
Vector3 finalPosition = position.normalisedCopy() * CELESTIAL_BODY_DISTANCE;
|
||||||
|
|
||||||
|
static unsigned int bodyCount=0;
|
||||||
|
|
||||||
|
/// \todo These billboards are not 100% correct, might want to revisit them later
|
||||||
|
mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1);
|
||||||
|
mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
|
||||||
|
mBBSet->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+2);
|
||||||
|
mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON);
|
||||||
|
mBBSet->setCommonDirection( -position.normalisedCopy() );
|
||||||
|
mNode = rootNode->createChildSceneNode();
|
||||||
|
mNode->setPosition(finalPosition);
|
||||||
|
mNode->attachObject(mBBSet);
|
||||||
|
mBBSet->createBillboard(0,0,0);
|
||||||
|
|
||||||
|
mMaterial = MaterialManager::getSingleton().create("BillboardMaterial"+StringConverter::toString(bodyCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||||
|
mMaterial->removeAllTechniques();
|
||||||
|
Pass* p = mMaterial->createTechnique()->createPass();
|
||||||
|
p->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
||||||
|
p->setDepthCheckEnabled(false);
|
||||||
|
p->setDepthWriteEnabled(false);
|
||||||
|
p->setSelfIllumination(1.0,1.0,1.0);
|
||||||
|
p->setDiffuse(0.0,0.0,0.0,1.0);
|
||||||
|
p->setAmbient(0.0,0.0,0.0);
|
||||||
|
p->createTextureUnitState(textureName);
|
||||||
|
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
|
||||||
|
|
||||||
|
bodyCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Moon::Moon( const String& textureName,
|
||||||
|
const float initialSize,
|
||||||
|
const Vector3& position,
|
||||||
|
SceneNode* rootNode)
|
||||||
|
{
|
||||||
|
init(textureName, initialSize, position, rootNode);
|
||||||
|
|
||||||
|
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
||||||
|
HighLevelGpuProgramPtr vshader;
|
||||||
|
if (mgr.resourceExists("Moon_VP"))
|
||||||
|
vshader = mgr.getByName("Moon_VP");
|
||||||
|
else
|
||||||
|
vshader = mgr.createProgram("Moon_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("Moon_FP"))
|
||||||
|
fshader = mgr.getByName("Moon_FP");
|
||||||
|
else
|
||||||
|
fshader = mgr.createProgram("Moon_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"
|
||||||
|
" 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) * tex2D(texture, uv) * float4(1,1,1,diffuse.a); \n"
|
||||||
|
" float bump = pow((1-diffuse.a),4); \n"
|
||||||
|
" oColor.rgb += float3(bump, bump, bump)*0.5; \n"
|
||||||
|
"}";
|
||||||
|
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());
|
||||||
|
|
||||||
|
setVisibility(1.0);
|
||||||
|
|
||||||
|
mPhase = Moon::Phase_Full;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Moon::setType(const Moon::Type& type)
|
||||||
|
{
|
||||||
|
mType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \todo the moon phase rendering is not correct - the dark part of the moon does not occlude the stars
|
||||||
|
void Moon::setPhase(const Moon::Phase& phase)
|
||||||
|
{
|
||||||
|
Ogre::String textureName = "textures\\tx_";
|
||||||
|
|
||||||
|
if (mType == Moon::Type_Secunda) textureName += "secunda_";
|
||||||
|
else textureName += "masser_";
|
||||||
|
|
||||||
|
if (phase == Moon::Phase_New) textureName += "new";
|
||||||
|
else if (phase == Moon::Phase_WaxingCrescent) textureName += "one_wax";
|
||||||
|
else if (phase == Moon::Phase_WaxingHalf) textureName += "half_wax";
|
||||||
|
else if (phase == Moon::Phase_WaxingGibbous) textureName += "three_wax";
|
||||||
|
else if (phase == Moon::Phase_WaningCrescent) textureName += "one_wan";
|
||||||
|
else if (phase == Moon::Phase_WaningHalf) textureName += "half_wan";
|
||||||
|
else if (phase == Moon::Phase_WaningGibbous) textureName += "three_wan";
|
||||||
|
else if (phase == Moon::Phase_Full) textureName += "full";
|
||||||
|
|
||||||
|
textureName += ".dds";
|
||||||
|
|
||||||
|
mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(textureName);
|
||||||
|
|
||||||
|
mPhase = phase;
|
||||||
|
}
|
||||||
|
|
||||||
|
Moon::Phase Moon::getPhase() const
|
||||||
|
{
|
||||||
|
return mPhase;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Moon::getPhaseInt() const
|
||||||
|
{
|
||||||
|
if (mPhase == Moon::Phase_New) return 0;
|
||||||
|
else if (mPhase == Moon::Phase_WaxingCrescent) return 1;
|
||||||
|
else if (mPhase == Moon::Phase_WaningCrescent) return 1;
|
||||||
|
else if (mPhase == Moon::Phase_WaxingHalf) return 2;
|
||||||
|
else if (mPhase == Moon::Phase_WaningHalf) return 2;
|
||||||
|
else if (mPhase == Moon::Phase_WaxingGibbous) return 3;
|
||||||
|
else if (mPhase == Moon::Phase_WaningGibbous) return 3;
|
||||||
|
else if (mPhase == Moon::Phase_Full) return 4;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
|
||||||
|
{
|
||||||
|
// Get the vertex colour buffer of this mesh
|
||||||
|
const Ogre::VertexElement* ves_diffuse = ent->getMesh()->getSubMesh(0)->vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_DIFFUSE );
|
||||||
|
HardwareVertexBufferSharedPtr colourBuffer = ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource());
|
||||||
|
|
||||||
|
// Lock
|
||||||
|
void* pData = colourBuffer->lock(HardwareBuffer::HBL_NORMAL);
|
||||||
|
|
||||||
|
// Iterate over all vertices
|
||||||
|
int vertex_size = colourBuffer->getVertexSize();
|
||||||
|
float * currentVertex = NULL;
|
||||||
|
for (unsigned int i=0; i<colourBuffer->getNumVertices(); ++i)
|
||||||
{
|
{
|
||||||
protected:
|
// Get a pointer to the vertex colour
|
||||||
Caelum::CaelumSystem* mpCaelumSystem;
|
ves_diffuse->baseVertexPointerToElement( pData, ¤tVertex );
|
||||||
|
|
||||||
public:
|
unsigned char alpha;
|
||||||
CaelumManager (Ogre::RenderWindow* pRenderWindow,
|
if (meshType == 0) alpha = i%2 ? 0 : 255; // this is a cylinder, so every second vertex belongs to the bottom-most row
|
||||||
Ogre::Camera* pCamera,
|
else if (meshType == 1)
|
||||||
const boost::filesystem::path& resDir);
|
|
||||||
virtual ~CaelumManager ();
|
|
||||||
|
|
||||||
virtual void enable() {}
|
|
||||||
|
|
||||||
virtual void disable() {}
|
|
||||||
|
|
||||||
virtual void setHour (double hour) {}
|
|
||||||
///< will be called even when sky is disabled.
|
|
||||||
|
|
||||||
virtual void setDate (int day, int month) {}
|
|
||||||
///< will be called even when sky is disabled.
|
|
||||||
|
|
||||||
virtual int getMasserPhase() const { return 0; }
|
|
||||||
///< 0 new moon, 1 waxing or waning cresecent, 2 waxing or waning half,
|
|
||||||
/// 3 waxing or waning gibbous, 4 full moon
|
|
||||||
|
|
||||||
virtual int getSecundaPhase() const { return 0; }
|
|
||||||
///< 0 new moon, 1 waxing or waning cresecent, 2 waxing or waning half,
|
|
||||||
/// 3 waxing or waning gibbous, 4 full moon
|
|
||||||
|
|
||||||
virtual void setMoonColour (bool red) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
CaelumManager::CaelumManager (Ogre::RenderWindow* pRenderWindow,
|
|
||||||
Ogre::Camera* pCamera,
|
|
||||||
const boost::filesystem::path& resDir)
|
|
||||||
: mpCaelumSystem (NULL)
|
|
||||||
{
|
|
||||||
using namespace Ogre;
|
|
||||||
using namespace Caelum;
|
|
||||||
|
|
||||||
assert(pCamera);
|
|
||||||
assert(pRenderWindow);
|
|
||||||
|
|
||||||
// Load the Caelum resources
|
|
||||||
//
|
|
||||||
ResourceGroupManager::getSingleton().addResourceLocation((resDir / "caelum").string(), "FileSystem", "Caelum");
|
|
||||||
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
|
||||||
|
|
||||||
// Load the Caelum resources
|
|
||||||
//
|
|
||||||
Ogre::SceneManager* pScene = pCamera->getSceneManager();
|
|
||||||
Caelum::CaelumSystem::CaelumComponent componentMask = CaelumSystem::CAELUM_COMPONENTS_DEFAULT;
|
|
||||||
mpCaelumSystem = new Caelum::CaelumSystem (Root::getSingletonPtr(), pScene, componentMask);
|
|
||||||
|
|
||||||
// Set time acceleration.
|
|
||||||
mpCaelumSystem->getUniversalClock()->setTimeScale(128);
|
|
||||||
|
|
||||||
// Disable fog since OpenMW is handling OGRE fog elsewhere
|
|
||||||
mpCaelumSystem->setManageSceneFog(false);
|
|
||||||
|
|
||||||
// Change the camera far distance to make sure the sky is not clipped
|
|
||||||
pCamera->setFarClipDistance(50000);
|
|
||||||
|
|
||||||
// Register Caelum as an OGRE listener
|
|
||||||
pRenderWindow->addListener(mpCaelumSystem);
|
|
||||||
Root::getSingletonPtr()->addFrameListener(mpCaelumSystem);
|
|
||||||
}
|
|
||||||
|
|
||||||
CaelumManager::~CaelumManager()
|
|
||||||
{
|
|
||||||
if (mpCaelumSystem)
|
|
||||||
mpCaelumSystem->shutdown (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates and connects the sky rendering component to OGRE.
|
|
||||||
///
|
|
||||||
/// \return NULL on failure.
|
|
||||||
///
|
|
||||||
SkyManager* SkyManager::create (Ogre::RenderWindow* pRenderWindow,
|
|
||||||
Ogre::Camera* pCamera,
|
|
||||||
const boost::filesystem::path& resDir)
|
|
||||||
{
|
|
||||||
SkyManager* pSkyManager = NULL;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
pSkyManager = new CaelumManager(pRenderWindow, pCamera, resDir);
|
if (i>= 49 && i <= 64) alpha = 0; // bottom-most row
|
||||||
}
|
else if (i>= 33 && i <= 48) alpha = 64; // second bottom-most row
|
||||||
catch (Ogre::Exception& e)
|
else alpha = 255;
|
||||||
{
|
|
||||||
std::cout << "\nOGRE Exception when attempting to add sky: "
|
|
||||||
<< e.getFullDescription().c_str() << std::endl;
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
std::cout << "\nException when attempting to add sky: "
|
|
||||||
<< e.what() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pSkyManager;
|
uint8 tmpR = static_cast<uint8>(255);
|
||||||
|
uint8 tmpG = static_cast<uint8>(255);
|
||||||
|
uint8 tmpB = static_cast<uint8>(255);
|
||||||
|
uint8 tmpA = static_cast<uint8>(alpha);
|
||||||
|
|
||||||
|
// This does not matter since R and B are always 1.
|
||||||
|
/*VertexElementType format = Root::getSingleton().getRenderSystem()->getColourVertexElementType();
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case VET_COLOUR_ARGB:
|
||||||
|
std::swap(tmpR, tmpB);
|
||||||
|
break;
|
||||||
|
case VET_COLOUR_ABGR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Modify
|
||||||
|
*((uint32*)currentVertex) = tmpR | (tmpG << 8) | (tmpB << 16) | (tmpA << 24);
|
||||||
|
|
||||||
|
// Move to the next vertex
|
||||||
|
pData = static_cast<unsigned char *> (pData) + vertex_size;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Unlock
|
||||||
|
ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) :
|
||||||
|
mGlareFade(0), mGlareEnabled(false)
|
||||||
|
{
|
||||||
|
mViewport = pCamera->getViewport();
|
||||||
|
mSceneMgr = pMwRoot->getCreator();
|
||||||
|
mRootNode = pCamera->getParentSceneNode()->createChildSceneNode();
|
||||||
|
mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates
|
||||||
|
mRootNode->setInheritOrientation(false);
|
||||||
|
|
||||||
|
/// \todo preload all the textures and meshes that are used for sky rendering
|
||||||
|
|
||||||
|
// Create overlay used for thunderstorm
|
||||||
|
MaterialPtr material = MaterialManager::getSingleton().create( "ThunderMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
|
||||||
|
Pass* pass = material->getTechnique(0)->getPass(0);
|
||||||
|
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
||||||
|
mThunderTextureUnit = pass->createTextureUnitState();
|
||||||
|
mThunderTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(1.f, 1.f, 1.f)); // always black colour
|
||||||
|
mThunderTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f);
|
||||||
|
OverlayManager& ovm = OverlayManager::getSingleton();
|
||||||
|
mThunderOverlay = ovm.create( "ThunderOverlay" );
|
||||||
|
OverlayContainer* overlay_panel;
|
||||||
|
overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", "ThunderPanel");
|
||||||
|
overlay_panel->_setPosition(0, 0);
|
||||||
|
overlay_panel->_setDimensions(1, 1);
|
||||||
|
overlay_panel->setMaterialName( "ThunderMaterial" );
|
||||||
|
overlay_panel->show();
|
||||||
|
mThunderOverlay->add2D(overlay_panel);
|
||||||
|
mThunderOverlay->hide();
|
||||||
|
|
||||||
|
mSecunda = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode);
|
||||||
|
mSecunda->setType(Moon::Type_Secunda);
|
||||||
|
mSecunda->setRenderQueue(RENDER_QUEUE_SKIES_EARLY+4);
|
||||||
|
|
||||||
|
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->setType(Moon::Type_Masser);
|
||||||
|
|
||||||
|
mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, 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);
|
||||||
|
|
||||||
|
|
||||||
|
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
||||||
|
|
||||||
|
// Stars
|
||||||
|
/// \todo sky_night_02.nif (available in Bloodmoon)
|
||||||
|
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
|
||||||
|
Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
|
||||||
|
night1_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+1);
|
||||||
|
|
||||||
|
mAtmosphereNight = mRootNode->createChildSceneNode();
|
||||||
|
mAtmosphereNight->attachObject(night1_ent);
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<night1_ent->getNumSubEntities(); ++i)
|
||||||
|
{
|
||||||
|
MaterialPtr mp = night1_ent->getSubEntity(i)->getMaterial();
|
||||||
|
mp->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
|
||||||
|
mp->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
|
||||||
|
mp->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 1.0);
|
||||||
|
mp->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
|
||||||
|
mp->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
|
||||||
|
mp->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
||||||
|
|
||||||
|
mStarsMaterials[i] = mp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stars vertex shader
|
||||||
|
HighLevelGpuProgramPtr vshader3 = mgr.createProgram("Stars_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||||
|
"cg", GPT_VERTEX_PROGRAM);
|
||||||
|
vshader3->setParameter("profiles", "vs_2_x arbvp1");
|
||||||
|
vshader3->setParameter("entry_point", "main_vp");
|
||||||
|
StringUtil::StrStreamType outStream4;
|
||||||
|
outStream4 <<
|
||||||
|
"void main_vp( \n"
|
||||||
|
" float4 position : POSITION, \n"
|
||||||
|
" in float2 uv : TEXCOORD0, \n"
|
||||||
|
" out float2 oUV : TEXCOORD0, \n"
|
||||||
|
" out float oFade : TEXCOORD1, \n"
|
||||||
|
" out float4 oPosition : POSITION, \n"
|
||||||
|
" uniform float4x4 worldViewProj \n"
|
||||||
|
") \n"
|
||||||
|
"{ \n"
|
||||||
|
" oUV = uv; \n"
|
||||||
|
" oFade = (position.z > 50) ? 1.f : 0.f; \n"
|
||||||
|
" oPosition = mul( worldViewProj, position ); \n"
|
||||||
|
"}";
|
||||||
|
vshader3->setSource(outStream4.str());
|
||||||
|
vshader3->load();
|
||||||
|
vshader3->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
||||||
|
night1_ent->getSubEntity(3)->getMaterial()->getTechnique(0)->getPass(0)->setVertexProgram(vshader3->getName());
|
||||||
|
|
||||||
|
// Stars fragment shader
|
||||||
|
HighLevelGpuProgramPtr stars_fp = mgr.createProgram("Stars_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||||
|
"cg", GPT_FRAGMENT_PROGRAM);
|
||||||
|
stars_fp->setParameter("profiles", "ps_2_x arbfp1");
|
||||||
|
stars_fp->setParameter("entry_point", "main_fp");
|
||||||
|
StringUtil::StrStreamType outStream5;
|
||||||
|
outStream5 <<
|
||||||
|
"void main_fp( \n"
|
||||||
|
" in float2 uv : TEXCOORD0, \n"
|
||||||
|
" out float4 oColor : COLOR, \n"
|
||||||
|
" in float fade : TEXCOORD1, \n"
|
||||||
|
" uniform sampler2D texture : TEXUNIT0, \n"
|
||||||
|
" uniform float opacity, \n"
|
||||||
|
" uniform float4 diffuse, \n"
|
||||||
|
" uniform float4 emissive \n"
|
||||||
|
") \n"
|
||||||
|
"{ \n"
|
||||||
|
" oColor = tex2D(texture, uv) * float4(emissive.xyz, 1) * float4(1,1,1,fade*diffuse.a); \n"
|
||||||
|
"}";
|
||||||
|
stars_fp->setSource(outStream5.str());
|
||||||
|
stars_fp->load();
|
||||||
|
stars_fp->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
||||||
|
stars_fp->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
|
||||||
|
night1_ent->getSubEntity(3)->getMaterial()->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName());
|
||||||
|
|
||||||
|
// Atmosphere (day)
|
||||||
|
mesh = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif");
|
||||||
|
Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif");
|
||||||
|
|
||||||
|
ModVertexAlpha(atmosphere_ent, 0);
|
||||||
|
|
||||||
|
atmosphere_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY);
|
||||||
|
mAtmosphereDay = mRootNode->createChildSceneNode();
|
||||||
|
mAtmosphereDay->attachObject(atmosphere_ent);
|
||||||
|
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
|
||||||
|
|
||||||
|
// Atmosphere shader
|
||||||
|
HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_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 float4 color : COLOR, \n"
|
||||||
|
" out float4 oPosition : POSITION, \n"
|
||||||
|
" out float4 oColor : COLOR, \n"
|
||||||
|
" uniform float4 emissive, \n"
|
||||||
|
" uniform float4x4 worldViewProj \n"
|
||||||
|
") \n"
|
||||||
|
"{ \n"
|
||||||
|
" oPosition = mul( worldViewProj, position ); \n"
|
||||||
|
" oColor = color * emissive; \n"
|
||||||
|
"}";
|
||||||
|
vshader->setSource(outStream.str());
|
||||||
|
vshader->load();
|
||||||
|
|
||||||
|
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
||||||
|
vshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
||||||
|
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
|
||||||
|
|
||||||
|
// Clouds
|
||||||
|
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
|
||||||
|
Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif");
|
||||||
|
clouds_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+5);
|
||||||
|
SceneNode* clouds_node = mRootNode->createChildSceneNode();
|
||||||
|
clouds_node->attachObject(clouds_ent);
|
||||||
|
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
|
||||||
|
|
||||||
|
// Clouds vertex shader
|
||||||
|
HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||||
|
"cg", GPT_VERTEX_PROGRAM);
|
||||||
|
vshader2->setParameter("profiles", "vs_2_x arbvp1");
|
||||||
|
vshader2->setParameter("entry_point", "main_vp");
|
||||||
|
StringUtil::StrStreamType outStream3;
|
||||||
|
outStream3 <<
|
||||||
|
"void main_vp( \n"
|
||||||
|
" float4 position : POSITION, \n"
|
||||||
|
" in float4 color : COLOR, \n"
|
||||||
|
" out float4 oColor : TEXCOORD1, \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"
|
||||||
|
" oColor = color; \n"
|
||||||
|
" oPosition = mul( worldViewProj, position ); \n"
|
||||||
|
"}";
|
||||||
|
vshader2->setSource(outStream3.str());
|
||||||
|
vshader2->load();
|
||||||
|
vshader2->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader2->getName());
|
||||||
|
|
||||||
|
// Clouds fragment shader
|
||||||
|
mCloudFragmentShader = mgr.createProgram("Clouds_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||||
|
"cg", GPT_FRAGMENT_PROGRAM);
|
||||||
|
mCloudFragmentShader->setParameter("profiles", "ps_2_x arbfp1");
|
||||||
|
mCloudFragmentShader->setParameter("entry_point", "main_fp");
|
||||||
|
StringUtil::StrStreamType outStream2;
|
||||||
|
outStream2 <<
|
||||||
|
"void main_fp( \n"
|
||||||
|
" in float2 uv : TEXCOORD0, \n"
|
||||||
|
" out float4 oColor : COLOR, \n"
|
||||||
|
" in float4 color : TEXCOORD1, \n"
|
||||||
|
" uniform sampler2D texture : TEXUNIT0, \n"
|
||||||
|
" uniform sampler2D secondTexture : TEXUNIT1, \n"
|
||||||
|
" uniform float transitionFactor, \n"
|
||||||
|
" uniform float time, \n"
|
||||||
|
" uniform float speed, \n"
|
||||||
|
" uniform float opacity, \n"
|
||||||
|
" uniform float4 emissive \n"
|
||||||
|
") \n"
|
||||||
|
"{ \n"
|
||||||
|
" uv += float2(1,1) * time * speed * "<<CLOUD_SPEED<<"; \n" // Scroll in x,y direction
|
||||||
|
" float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n"
|
||||||
|
" oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n"
|
||||||
|
"}";
|
||||||
|
mCloudFragmentShader->setSource(outStream2.str());
|
||||||
|
mCloudFragmentShader->load();
|
||||||
|
mCloudFragmentShader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(mCloudFragmentShader->getName());
|
||||||
|
setCloudsOpacity(0.75);
|
||||||
|
|
||||||
|
ModVertexAlpha(clouds_ent, 1);
|
||||||
|
|
||||||
|
// I'm not sure if the materials are being used by any other objects
|
||||||
|
// Make a unique "modifiable" copy of the materials to be sure
|
||||||
|
mCloudMaterial = mCloudMaterial->clone("Clouds");
|
||||||
|
clouds_ent->getSubEntity(0)->setMaterial(mCloudMaterial);
|
||||||
|
mAtmosphereMaterial = mAtmosphereMaterial->clone("Atmosphere");
|
||||||
|
atmosphere_ent->getSubEntity(0)->setMaterial(mAtmosphereMaterial);
|
||||||
|
|
||||||
|
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
|
||||||
|
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 0.0);
|
||||||
|
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
|
||||||
|
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
|
||||||
|
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
||||||
|
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("");
|
||||||
|
}
|
||||||
|
|
||||||
|
SkyManager::~SkyManager()
|
||||||
|
{
|
||||||
|
delete mSun;
|
||||||
|
delete mSunGlare;
|
||||||
|
delete mMasser;
|
||||||
|
delete mSecunda;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SkyManager::getMasserPhase() const
|
||||||
|
{
|
||||||
|
return mMasser->getPhaseInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SkyManager::getSecundaPhase() const
|
||||||
|
{
|
||||||
|
return mSecunda->getPhaseInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::update(float duration)
|
||||||
|
{
|
||||||
|
if (!mEnabled) return;
|
||||||
|
|
||||||
|
// UV Scroll the clouds
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", 1);
|
||||||
|
|
||||||
|
/// \todo improve this
|
||||||
|
mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
|
||||||
|
mSecunda->setPhase ( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
|
||||||
|
|
||||||
|
// increase the strength of the sun glare effect depending
|
||||||
|
// on how directly the player is looking at the sun
|
||||||
|
if (mSunEnabled)
|
||||||
|
{
|
||||||
|
Vector3 sun = mSunGlare->getPosition();
|
||||||
|
sun = Vector3(sun.x, sun.z, -sun.y);
|
||||||
|
Vector3 cam = mViewport->getCamera()->getRealDirection();
|
||||||
|
const Degree angle = sun.angleBetween( cam );
|
||||||
|
float val = 1- (angle.valueDegrees() / 180.f);
|
||||||
|
val = (val*val*val*val)*2;
|
||||||
|
|
||||||
|
if (mGlareEnabled)
|
||||||
|
{
|
||||||
|
mGlareFade += duration*3;
|
||||||
|
if (mGlareFade > 1) mGlareFade = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mGlareFade -= duration*3;
|
||||||
|
if (mGlareFade < 0.3) mGlareFade = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSunGlare->setSize(val * (mGlareFade));
|
||||||
|
}
|
||||||
|
|
||||||
|
mSunGlare->setVisible(mGlareFade>0 && mSunEnabled);
|
||||||
|
mSun->setVisible(mSunEnabled);
|
||||||
|
mMasser->setVisible(mMasserEnabled);
|
||||||
|
mSecunda->setVisible(mSecundaEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::enable()
|
||||||
|
{
|
||||||
|
mRootNode->setVisible(true);
|
||||||
|
mEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::disable()
|
||||||
|
{
|
||||||
|
mRootNode->setVisible(false);
|
||||||
|
mEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setMoonColour (bool red)
|
||||||
|
{
|
||||||
|
mSecunda->setColour( red ? ColourValue(1.0, 0.0784, 0.0784)
|
||||||
|
: ColourValue(1.0, 1.0, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setCloudsOpacity(float opacity)
|
||||||
|
{
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
|
||||||
|
{
|
||||||
|
if (mClouds != weather.mCloudTexture)
|
||||||
|
{
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("textures\\"+weather.mCloudTexture);
|
||||||
|
mClouds = weather.mCloudTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNextClouds != weather.mNextCloudTexture)
|
||||||
|
{
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("textures\\"+weather.mNextCloudTexture);
|
||||||
|
mNextClouds = weather.mNextCloudTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCloudBlendFactor != weather.mCloudBlendFactor)
|
||||||
|
{
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("transitionFactor", Real(weather.mCloudBlendFactor));
|
||||||
|
mCloudBlendFactor = weather.mCloudBlendFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCloudOpacity != weather.mCloudOpacity)
|
||||||
|
{
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(weather.mCloudOpacity));
|
||||||
|
mCloudOpacity = weather.mCloudOpacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCloudColour != weather.mSunColor)
|
||||||
|
{
|
||||||
|
ColourValue clr( weather.mSunColor.r*0.7 + weather.mAmbientColor.r*0.7,
|
||||||
|
weather.mSunColor.g*0.7 + weather.mAmbientColor.g*0.7,
|
||||||
|
weather.mSunColor.b*0.7 + weather.mAmbientColor.b*0.7);
|
||||||
|
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(clr);
|
||||||
|
mCloudColour = weather.mSunColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSkyColour != weather.mSkyColor)
|
||||||
|
{
|
||||||
|
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(weather.mSkyColor);
|
||||||
|
mSkyColour = weather.mSkyColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCloudSpeed != weather.mCloudSpeed)
|
||||||
|
{
|
||||||
|
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("speed", Real(weather.mCloudSpeed));
|
||||||
|
mCloudSpeed = weather.mCloudSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weather.mNight && mStarsOpacity != weather.mNightFade)
|
||||||
|
{
|
||||||
|
for (int i=0; i<7; ++i)
|
||||||
|
mStarsMaterials[i]->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, weather.mNightFade);
|
||||||
|
mStarsOpacity = weather.mNightFade;
|
||||||
|
}
|
||||||
|
|
||||||
|
float strength;
|
||||||
|
float timeofday_angle = std::abs(mSunGlare->getPosition().z/mSunGlare->getPosition().length());
|
||||||
|
if (timeofday_angle <= 0.44)
|
||||||
|
strength = timeofday_angle/0.44f;
|
||||||
|
else
|
||||||
|
strength = 1.f;
|
||||||
|
|
||||||
|
mSunGlare->setVisibility(weather.mGlareView * strength);
|
||||||
|
|
||||||
|
mAtmosphereNight->setVisible(weather.mNight && mEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setGlare(bool glare)
|
||||||
|
{
|
||||||
|
mGlareEnabled = glare;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 SkyManager::getRealSunPos()
|
||||||
|
{
|
||||||
|
return mSun->getNode()->_getDerivedPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::sunEnable()
|
||||||
|
{
|
||||||
|
mSunEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::sunDisable()
|
||||||
|
{
|
||||||
|
mSunEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setSunDirection(const Vector3& direction)
|
||||||
|
{
|
||||||
|
mSun->setPosition(direction);
|
||||||
|
mSunGlare->setPosition(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setMasserDirection(const Vector3& direction)
|
||||||
|
{
|
||||||
|
mMasser->setPosition(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setSecundaDirection(const Vector3& direction)
|
||||||
|
{
|
||||||
|
mSecunda->setPosition(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::masserEnable()
|
||||||
|
{
|
||||||
|
mMasserEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::secundaEnable()
|
||||||
|
{
|
||||||
|
mSecundaEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::masserDisable()
|
||||||
|
{
|
||||||
|
mMasserEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::secundaDisable()
|
||||||
|
{
|
||||||
|
mSecundaEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setThunder(const float factor)
|
||||||
|
{
|
||||||
|
if (factor > 0.f)
|
||||||
|
{
|
||||||
|
mThunderOverlay->show();
|
||||||
|
mThunderTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, factor*0.6);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mThunderOverlay->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setMasserFade(const float fade)
|
||||||
|
{
|
||||||
|
mMasser->setVisibility(fade);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setSecundaFade(const float fade)
|
||||||
|
{
|
||||||
|
mSecunda->setVisibility(fade);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setHour(double hour)
|
||||||
|
{
|
||||||
|
mHour = hour;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setDate(int day, int month)
|
||||||
|
{
|
||||||
|
mDay = day;
|
||||||
|
mMonth = month;
|
||||||
|
}
|
||||||
|
|
|
@ -1,40 +1,211 @@
|
||||||
#ifndef _GAME_RENDER_SKY_H
|
#ifndef _GAME_RENDER_SKY_H
|
||||||
#define _GAME_RENDER_SKY_H
|
#define _GAME_RENDER_SKY_H
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <OgreVector3.h>
|
||||||
|
#include <OgreString.h>
|
||||||
|
#include <OgreMaterial.h>
|
||||||
|
#include <OgreColourValue.h>
|
||||||
|
#include <OgreHighLevelGpuProgram.h>
|
||||||
|
|
||||||
|
#include "sky.hpp"
|
||||||
|
#include "../mwworld/weather.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class RenderWindow;
|
class RenderWindow;
|
||||||
|
class SceneNode;
|
||||||
class Camera;
|
class Camera;
|
||||||
|
class Viewport;
|
||||||
|
class SceneManager;
|
||||||
|
class Entity;
|
||||||
|
class BillboardSet;
|
||||||
|
class TextureUnitState;
|
||||||
|
class Overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
///
|
class BillboardObject
|
||||||
/// Interface for the sky rendering system
|
{
|
||||||
///
|
public:
|
||||||
|
BillboardObject( const Ogre::String& textureName,
|
||||||
|
const float size,
|
||||||
|
const Ogre::Vector3& position,
|
||||||
|
Ogre::SceneNode* rootNode
|
||||||
|
);
|
||||||
|
BillboardObject();
|
||||||
|
|
||||||
|
void setColour(const Ogre::ColourValue& pColour);
|
||||||
|
void setPosition(const Ogre::Vector3& pPosition);
|
||||||
|
void setVisible(const bool visible);
|
||||||
|
void setRenderQueue(unsigned int id);
|
||||||
|
void setSize(const float size);
|
||||||
|
Ogre::Vector3 getPosition() const;
|
||||||
|
|
||||||
|
void setVisibility(const float visibility);
|
||||||
|
|
||||||
|
Ogre::SceneNode* getNode();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void init(const Ogre::String& textureName,
|
||||||
|
const float size,
|
||||||
|
const Ogre::Vector3& position,
|
||||||
|
Ogre::SceneNode* rootNode);
|
||||||
|
|
||||||
|
Ogre::SceneNode* mNode;
|
||||||
|
Ogre::MaterialPtr mMaterial;
|
||||||
|
Ogre::BillboardSet* mBBSet;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The moons need a seperate class because of their shader (which allows them to be partially transparent)
|
||||||
|
*/
|
||||||
|
class Moon : public BillboardObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Moon( const Ogre::String& textureName,
|
||||||
|
const float size,
|
||||||
|
const Ogre::Vector3& position,
|
||||||
|
Ogre::SceneNode* rootNode
|
||||||
|
);
|
||||||
|
|
||||||
|
enum Phase
|
||||||
|
{
|
||||||
|
Phase_New = 0,
|
||||||
|
Phase_WaxingCrescent,
|
||||||
|
Phase_WaxingHalf,
|
||||||
|
Phase_WaxingGibbous,
|
||||||
|
Phase_Full,
|
||||||
|
Phase_WaningGibbous,
|
||||||
|
Phase_WaningHalf,
|
||||||
|
Phase_WaningCrescent
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
Type_Masser = 0,
|
||||||
|
Type_Secunda
|
||||||
|
};
|
||||||
|
|
||||||
|
void setPhase(const Phase& phase);
|
||||||
|
void setType(const Type& type);
|
||||||
|
|
||||||
|
Phase getPhase() const;
|
||||||
|
unsigned int getPhaseInt() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type mType;
|
||||||
|
Phase mPhase;
|
||||||
|
};
|
||||||
|
|
||||||
class SkyManager
|
class SkyManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static SkyManager* create (Ogre::RenderWindow* pRenderWindow,
|
SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera);
|
||||||
Ogre::Camera* pCamera,
|
~SkyManager();
|
||||||
const boost::filesystem::path& resDir);
|
|
||||||
virtual ~SkyManager() {}
|
|
||||||
|
|
||||||
virtual void enable() = 0;
|
void update(float duration);
|
||||||
|
|
||||||
virtual void disable() = 0;
|
void enable();
|
||||||
|
|
||||||
virtual void setHour (double hour) = 0;
|
void disable();
|
||||||
|
|
||||||
virtual void setDate (int day, int month) = 0;
|
void setHour (double hour);
|
||||||
|
///< will be called even when sky is disabled.
|
||||||
|
|
||||||
virtual int getMasserPhase() const = 0;
|
void setDate (int day, int month);
|
||||||
|
///< will be called even when sky is disabled.
|
||||||
|
|
||||||
virtual int getSecundaPhase() const = 0;
|
int getMasserPhase() const;
|
||||||
|
///< 0 new moon, 1 waxing or waning cresecent, 2 waxing or waning half,
|
||||||
|
/// 3 waxing or waning gibbous, 4 full moon
|
||||||
|
|
||||||
virtual void setMoonColour (bool red) = 0;
|
int getSecundaPhase() const;
|
||||||
|
///< 0 new moon, 1 waxing or waning cresecent, 2 waxing or waning half,
|
||||||
|
/// 3 waxing or waning gibbous, 4 full moon
|
||||||
|
|
||||||
|
void setMoonColour (bool red);
|
||||||
|
///< change Secunda colour to red
|
||||||
|
|
||||||
|
void setCloudsOpacity(float opacity);
|
||||||
|
///< change opacity of the clouds
|
||||||
|
|
||||||
|
void setWeather(const MWWorld::WeatherResult& weather);
|
||||||
|
|
||||||
|
void sunEnable();
|
||||||
|
|
||||||
|
void sunDisable();
|
||||||
|
|
||||||
|
void setSunDirection(const Ogre::Vector3& direction);
|
||||||
|
|
||||||
|
void setMasserDirection(const Ogre::Vector3& direction);
|
||||||
|
|
||||||
|
void setSecundaDirection(const Ogre::Vector3& direction);
|
||||||
|
|
||||||
|
void setMasserFade(const float fade);
|
||||||
|
|
||||||
|
void setSecundaFade(const float fade);
|
||||||
|
|
||||||
|
void masserEnable();
|
||||||
|
void masserDisable();
|
||||||
|
|
||||||
|
void secundaEnable();
|
||||||
|
void secundaDisable();
|
||||||
|
|
||||||
|
void setThunder(const float factor);
|
||||||
|
|
||||||
|
void setGlare(bool glare);
|
||||||
|
Ogre::Vector3 getRealSunPos();
|
||||||
|
|
||||||
|
private:
|
||||||
|
float mHour;
|
||||||
|
int mDay;
|
||||||
|
int mMonth;
|
||||||
|
|
||||||
|
BillboardObject* mSun;
|
||||||
|
BillboardObject* mSunGlare;
|
||||||
|
Moon* mMasser;
|
||||||
|
Moon* mSecunda;
|
||||||
|
|
||||||
|
Ogre::Viewport* mViewport;
|
||||||
|
Ogre::SceneNode* mRootNode;
|
||||||
|
Ogre::SceneManager* mSceneMgr;
|
||||||
|
|
||||||
|
Ogre::SceneNode* mAtmosphereDay;
|
||||||
|
Ogre::SceneNode* mAtmosphereNight;
|
||||||
|
|
||||||
|
Ogre::MaterialPtr mCloudMaterial;
|
||||||
|
Ogre::MaterialPtr mAtmosphereMaterial;
|
||||||
|
|
||||||
|
Ogre::MaterialPtr mStarsMaterials[7];
|
||||||
|
|
||||||
|
Ogre::HighLevelGpuProgramPtr mCloudFragmentShader;
|
||||||
|
|
||||||
|
// remember some settings so we don't have to apply them again if they didnt change
|
||||||
|
Ogre::String mClouds;
|
||||||
|
Ogre::String mNextClouds;
|
||||||
|
float mCloudBlendFactor;
|
||||||
|
float mCloudOpacity;
|
||||||
|
float mCloudSpeed;
|
||||||
|
float mStarsOpacity;
|
||||||
|
Ogre::ColourValue mCloudColour;
|
||||||
|
Ogre::ColourValue mSkyColour;
|
||||||
|
|
||||||
|
Ogre::Overlay* mThunderOverlay;
|
||||||
|
Ogre::TextureUnitState* mThunderTextureUnit;
|
||||||
|
|
||||||
|
float mRemainingTransitionTime;
|
||||||
|
|
||||||
|
float mGlareFade;
|
||||||
|
|
||||||
|
void ModVertexAlpha(Ogre::Entity* ent, unsigned int meshType);
|
||||||
|
|
||||||
|
bool mEnabled;
|
||||||
|
bool mGlareEnabled;
|
||||||
|
bool mSunEnabled;
|
||||||
|
bool mMasserEnabled;
|
||||||
|
bool mSecundaEnabled;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "../mwworld/manualref.hpp"
|
#include "../mwworld/manualref.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/containerutil.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "interpretercontext.hpp"
|
#include "interpretercontext.hpp"
|
||||||
#include "ref.hpp"
|
#include "ref.hpp"
|
||||||
|
@ -45,8 +45,7 @@ namespace MWScript
|
||||||
|
|
||||||
ref.getPtr().getRefData().setCount (count);
|
ref.getPtr().getRefData().setCount (count);
|
||||||
|
|
||||||
MWWorld::Class::get (ref.getPtr()).insertIntoContainer (ref.getPtr(),
|
MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr());
|
||||||
MWWorld::Class::get (ptr).getContainerStore (ptr));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,25 +58,16 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
MWScript::InterpreterContext& context
|
|
||||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
|
||||||
|
|
||||||
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
|
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
std::vector<MWWorld::Ptr> list;
|
MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);
|
||||||
|
|
||||||
MWWorld::listItemsInContainer (item,
|
|
||||||
MWWorld::Class::get (ptr).getContainerStore (ptr),
|
|
||||||
context.getWorld().getStore(), list);
|
|
||||||
|
|
||||||
Interpreter::Type_Integer sum = 0;
|
Interpreter::Type_Integer sum = 0;
|
||||||
|
|
||||||
for (std::vector<MWWorld::Ptr>::iterator iter (list.begin()); iter!=list.end();
|
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
|
||||||
++iter)
|
if (iter->getCellRef().refID==item)
|
||||||
{
|
sum += iter->getRefData().getCount();
|
||||||
sum += iter->getRefData().getCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
runtime.push (sum);
|
runtime.push (sum);
|
||||||
}
|
}
|
||||||
|
@ -92,9 +82,6 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
MWScript::InterpreterContext& context
|
|
||||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
|
||||||
|
|
||||||
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
|
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
|
@ -104,25 +91,23 @@ namespace MWScript
|
||||||
if (count<0)
|
if (count<0)
|
||||||
throw std::runtime_error ("second argument for RemoveItem must be non-negative");
|
throw std::runtime_error ("second argument for RemoveItem must be non-negative");
|
||||||
|
|
||||||
std::vector<MWWorld::Ptr> list;
|
MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);
|
||||||
|
|
||||||
MWWorld::listItemsInContainer (item,
|
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end() && count;
|
||||||
MWWorld::Class::get (ptr).getContainerStore (ptr),
|
|
||||||
context.getWorld().getStore(), list);
|
|
||||||
|
|
||||||
for (std::vector<MWWorld::Ptr>::iterator iter (list.begin());
|
|
||||||
iter!=list.end() && count;
|
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
if (iter->getRefData().getCount()<=count)
|
if (iter->getCellRef().refID==item)
|
||||||
{
|
{
|
||||||
count -= iter->getRefData().getCount();
|
if (iter->getRefData().getCount()<=count)
|
||||||
iter->getRefData().setCount (0);
|
{
|
||||||
}
|
count -= iter->getRefData().getCount();
|
||||||
else
|
iter->getRefData().setCount (0);
|
||||||
{
|
}
|
||||||
iter->getRefData().setCount (iter->getRefData().getCount()-count);
|
else
|
||||||
count = 0;
|
{
|
||||||
|
iter->getRefData().setCount (iter->getRefData().getCount()-count);
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,4 +116,10 @@ op 0x2000137: GetButtonPressed
|
||||||
op 0x2000138: SkipAnim
|
op 0x2000138: SkipAnim
|
||||||
op 0x2000139: SkipAnim, expplicit reference
|
op 0x2000139: SkipAnim, expplicit reference
|
||||||
op 0x200013a: AddTopic
|
op 0x200013a: AddTopic
|
||||||
opcodes 0x200013b-0x3ffffff unused
|
op 0x200013b: twf
|
||||||
|
op 0x200013c: FadeIn
|
||||||
|
op 0x200013d: FadeOut
|
||||||
|
op 0x200013e: FadeTo
|
||||||
|
op 0x200013f: GetCurrentWeather
|
||||||
|
op 0x2000140: ChangeWeather
|
||||||
|
opcodes 0x2000141-0x3ffffff unused
|
||||||
|
|
|
@ -103,7 +103,75 @@ namespace MWScript
|
||||||
context.getWorld().toggleRenderMode (MWWorld::World::Render_CollisionDebug);
|
context.getWorld().toggleRenderMode (MWWorld::World::Render_CollisionDebug);
|
||||||
|
|
||||||
context.report (enabled ?
|
context.report (enabled ?
|
||||||
"Collsion Mesh Rendering -> On" : "Collision Mesh Rendering -> Off");
|
"Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpToggleWireframe : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
InterpreterContext& context =
|
||||||
|
static_cast<InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
|
bool enabled =
|
||||||
|
context.getWorld().toggleRenderMode (MWWorld::World::Render_Wireframe);
|
||||||
|
|
||||||
|
context.report (enabled ?
|
||||||
|
"Wireframe Rendering -> On" : "Wireframe Rendering -> Off");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpFadeIn : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
InterpreterContext& context =
|
||||||
|
static_cast<InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
|
Interpreter::Type_Float time = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
context.getWorld().getFader()->fadeIn(time);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpFadeOut : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
InterpreterContext& context =
|
||||||
|
static_cast<InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
|
Interpreter::Type_Float time = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
context.getWorld().getFader()->fadeOut(time);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpFadeTo : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
InterpreterContext& context =
|
||||||
|
static_cast<InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
|
Interpreter::Type_Float alpha = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
Interpreter::Type_Float time = runtime[0].mFloat;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
context.getWorld().getFader()->fadeTo(alpha, time);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,6 +183,10 @@ namespace MWScript
|
||||||
const int opcodeUnlock = 0x200008c;
|
const int opcodeUnlock = 0x200008c;
|
||||||
const int opcodeUnlockExplicit = 0x200008d;
|
const int opcodeUnlockExplicit = 0x200008d;
|
||||||
const int opcodeToggleCollisionDebug = 0x2000132;
|
const int opcodeToggleCollisionDebug = 0x2000132;
|
||||||
|
const int opcodeToggleWireframe = 0x200013b;
|
||||||
|
const int opcodeFadeIn = 0x200013c;
|
||||||
|
const int opcodeFadeOut = 0x200013d;
|
||||||
|
const int opcodeFadeTo = 0x200013e;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
@ -127,6 +199,11 @@ namespace MWScript
|
||||||
extensions.registerInstruction ("togglecollisiongrid", "", opcodeToggleCollisionDebug);
|
extensions.registerInstruction ("togglecollisiongrid", "", opcodeToggleCollisionDebug);
|
||||||
extensions.registerInstruction ("tcb", "", opcodeToggleCollisionDebug);
|
extensions.registerInstruction ("tcb", "", opcodeToggleCollisionDebug);
|
||||||
extensions.registerInstruction ("tcg", "", opcodeToggleCollisionDebug);
|
extensions.registerInstruction ("tcg", "", opcodeToggleCollisionDebug);
|
||||||
|
extensions.registerInstruction ("twf", "", opcodeToggleWireframe);
|
||||||
|
extensions.registerInstruction ("togglewireframe", "", opcodeToggleWireframe);
|
||||||
|
extensions.registerInstruction ("fadein", "f", opcodeFadeIn);
|
||||||
|
extensions.registerInstruction ("fadeout", "f", opcodeFadeOut);
|
||||||
|
extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -139,6 +216,10 @@ namespace MWScript
|
||||||
interpreter.installSegment5 (opcodeUnlock, new OpUnlock<ImplicitRef>);
|
interpreter.installSegment5 (opcodeUnlock, new OpUnlock<ImplicitRef>);
|
||||||
interpreter.installSegment5 (opcodeUnlockExplicit, new OpUnlock<ExplicitRef>);
|
interpreter.installSegment5 (opcodeUnlockExplicit, new OpUnlock<ExplicitRef>);
|
||||||
interpreter.installSegment5 (opcodeToggleCollisionDebug, new OpToggleCollisionDebug);
|
interpreter.installSegment5 (opcodeToggleCollisionDebug, new OpToggleCollisionDebug);
|
||||||
|
interpreter.installSegment5 (opcodeToggleWireframe, new OpToggleWireframe);
|
||||||
|
interpreter.installSegment5 (opcodeFadeIn, new OpFadeIn);
|
||||||
|
interpreter.installSegment5 (opcodeFadeOut, new OpFadeOut);
|
||||||
|
interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
std::vector<Interpreter::Type_Code> code;
|
std::vector<Interpreter::Type_Code> code;
|
||||||
mParser.getCode (code);
|
mParser.getCode (code);
|
||||||
mScripts.insert (std::make_pair (name, code));
|
mScripts.insert (std::make_pair (name, std::make_pair (code, mParser.getLocals())));
|
||||||
|
|
||||||
// TODO sanity check on generated locals
|
// TODO sanity check on generated locals
|
||||||
|
|
||||||
|
@ -77,8 +77,7 @@ namespace MWScript
|
||||||
void ScriptManager::run (const std::string& name, Interpreter::Context& interpreterContext)
|
void ScriptManager::run (const std::string& name, Interpreter::Context& interpreterContext)
|
||||||
{
|
{
|
||||||
// compile script
|
// compile script
|
||||||
std::map<std::string, std::vector<Interpreter::Type_Code> >::iterator iter =
|
ScriptCollection::iterator iter = mScripts.find (name);
|
||||||
mScripts.find (name);
|
|
||||||
|
|
||||||
if (iter==mScripts.end())
|
if (iter==mScripts.end())
|
||||||
{
|
{
|
||||||
|
@ -86,7 +85,7 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
// failed -> ignore script from now on.
|
// failed -> ignore script from now on.
|
||||||
std::vector<Interpreter::Type_Code> empty;
|
std::vector<Interpreter::Type_Code> empty;
|
||||||
mScripts.insert (std::make_pair (name, empty));
|
mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +94,7 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute script
|
// execute script
|
||||||
if (!iter->second.empty())
|
if (!iter->second.first.empty())
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!mOpcodesInstalled)
|
if (!mOpcodesInstalled)
|
||||||
|
@ -104,7 +103,7 @@ namespace MWScript
|
||||||
mOpcodesInstalled = true;
|
mOpcodesInstalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInterpreter.run (&iter->second[0], iter->second.size(), interpreterContext);
|
mInterpreter.run (&iter->second.first[0], iter->second.first.size(), interpreterContext);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -113,7 +112,7 @@ namespace MWScript
|
||||||
if (mVerbose)
|
if (mVerbose)
|
||||||
std::cerr << "(" << e.what() << ")" << std::endl;
|
std::cerr << "(" << e.what() << ")" << std::endl;
|
||||||
|
|
||||||
iter->second.clear(); // don't execute again.
|
iter->second.first.clear(); // don't execute again.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,4 +131,24 @@ namespace MWScript
|
||||||
|
|
||||||
return std::make_pair (count, success);
|
return std::make_pair (count, success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Compiler::Locals& ScriptManager::getLocals (const std::string& name)
|
||||||
|
{
|
||||||
|
ScriptCollection::iterator iter = mScripts.find (name);
|
||||||
|
|
||||||
|
if (iter==mScripts.end())
|
||||||
|
{
|
||||||
|
if (!compile (name))
|
||||||
|
{
|
||||||
|
// failed -> ignore script from now on.
|
||||||
|
std::vector<Interpreter::Type_Code> empty;
|
||||||
|
mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));
|
||||||
|
throw std::runtime_error ("failed to compile script " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = mScripts.find (name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return iter->second.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,11 @@ namespace MWScript
|
||||||
Interpreter::Interpreter mInterpreter;
|
Interpreter::Interpreter mInterpreter;
|
||||||
bool mOpcodesInstalled;
|
bool mOpcodesInstalled;
|
||||||
|
|
||||||
std::map<std::string, std::vector<Interpreter::Type_Code> > mScripts;
|
typedef std::pair<std::vector<Interpreter::Type_Code>, Compiler::Locals> CompiledScript;
|
||||||
|
typedef std::map<std::string, CompiledScript> ScriptCollection;
|
||||||
|
|
||||||
|
|
||||||
|
ScriptCollection mScripts;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -56,6 +60,9 @@ namespace MWScript
|
||||||
std::pair<int, int> compileAll();
|
std::pair<int, int> compileAll();
|
||||||
///< Compile all scripts
|
///< Compile all scripts
|
||||||
/// \return count, success
|
/// \return count, success
|
||||||
|
|
||||||
|
Compiler::Locals& getLocals (const std::string& name);
|
||||||
|
///< Return locals for script \a name.
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -79,12 +79,46 @@ namespace MWScript
|
||||||
runtime.push (context.getWorld().getSecundaPhase());
|
runtime.push (context.getWorld().getSecundaPhase());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OpGetCurrentWeather : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
InterpreterContext& context =
|
||||||
|
static_cast<InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
|
runtime.push (context.getWorld().getCurrentWeather());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpChangeWeather : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
InterpreterContext& context =
|
||||||
|
static_cast<InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
|
std::string region = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
Interpreter::Type_Integer id = runtime[0].mInteger;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
context.getWorld().changeWeather(region, id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const int opcodeToggleSky = 0x2000021;
|
const int opcodeToggleSky = 0x2000021;
|
||||||
const int opcodeTurnMoonWhite = 0x2000022;
|
const int opcodeTurnMoonWhite = 0x2000022;
|
||||||
const int opcodeTurnMoonRed = 0x2000023;
|
const int opcodeTurnMoonRed = 0x2000023;
|
||||||
const int opcodeGetMasserPhase = 0x2000024;
|
const int opcodeGetMasserPhase = 0x2000024;
|
||||||
const int opcodeGetSecundaPhase = 0x2000025;
|
const int opcodeGetSecundaPhase = 0x2000025;
|
||||||
|
const int opcodeGetCurrentWeather = 0x200013f;
|
||||||
|
const int opcodeChangeWeather = 0x2000140;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
@ -92,8 +126,10 @@ namespace MWScript
|
||||||
extensions.registerInstruction ("ts", "", opcodeToggleSky);
|
extensions.registerInstruction ("ts", "", opcodeToggleSky);
|
||||||
extensions.registerInstruction ("turnmoonwhite", "", opcodeTurnMoonWhite);
|
extensions.registerInstruction ("turnmoonwhite", "", opcodeTurnMoonWhite);
|
||||||
extensions.registerInstruction ("turnmoonred", "", opcodeTurnMoonRed);
|
extensions.registerInstruction ("turnmoonred", "", opcodeTurnMoonRed);
|
||||||
|
extensions.registerInstruction ("changeweather", "Sl", opcodeChangeWeather);
|
||||||
extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase);
|
extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase);
|
||||||
extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase);
|
extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase);
|
||||||
|
extensions.registerFunction ("getcurrentweather", 'l', "", opcodeGetCurrentWeather);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -103,6 +139,8 @@ namespace MWScript
|
||||||
interpreter.installSegment5 (opcodeTurnMoonRed, new OpTurnMoonRed);
|
interpreter.installSegment5 (opcodeTurnMoonRed, new OpTurnMoonRed);
|
||||||
interpreter.installSegment5 (opcodeGetMasserPhase, new OpGetMasserPhase);
|
interpreter.installSegment5 (opcodeGetMasserPhase, new OpGetMasserPhase);
|
||||||
interpreter.installSegment5 (opcodeGetSecundaPhase, new OpGetSecundaPhase);
|
interpreter.installSegment5 (opcodeGetSecundaPhase, new OpGetSecundaPhase);
|
||||||
|
interpreter.installSegment5 (opcodeGetCurrentWeather, new OpGetCurrentWeather);
|
||||||
|
interpreter.installSegment5 (opcodeChangeWeather, new OpChangeWeather);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
#include <openengine/sound/sndmanager.hpp>
|
#include <openengine/sound/sndmanager.hpp>
|
||||||
|
@ -15,6 +13,7 @@ using namespace std;
|
||||||
#include <components/file_finder/file_finder.hpp>
|
#include <components/file_finder/file_finder.hpp>
|
||||||
#include <components/esm_store/store.hpp>
|
#include <components/esm_store/store.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include "../mwworld/environment.hpp"
|
#include "../mwworld/environment.hpp"
|
||||||
#include "../mwworld/world.hpp"
|
#include "../mwworld/world.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/player.hpp"
|
||||||
|
@ -90,24 +89,28 @@ namespace MWSound
|
||||||
// relative to the sound dir, and translates them into full paths
|
// relative to the sound dir, and translates them into full paths
|
||||||
// of existing files in the filesystem, if they exist.
|
// of existing files in the filesystem, if they exist.
|
||||||
bool FSstrict;
|
bool FSstrict;
|
||||||
FileFinder::FileFinder files;
|
FileFinder::LessTreeFileFinder files;
|
||||||
FileFinder::FileFinderStrict strict;
|
FileFinder::StrictTreeFileFinder strict;
|
||||||
FileFinder::FileFinder musicpath;
|
FileFinder::LessTreeFileFinder musicpath;
|
||||||
FileFinder::FileFinderStrict musicpathStrict;
|
FileFinder::StrictTreeFileFinder musicpathStrict;
|
||||||
|
|
||||||
SoundImpl(Ogre::Root *root, Ogre::Camera *camera,
|
SoundImpl(Ogre::Root *root, Ogre::Camera *camera, const ESMS::ESMStore &str,
|
||||||
const ESMS::ESMStore &str,
|
const Files::PathContainer& soundDir,
|
||||||
const std::string &soundDir, const std::string &musicDir, bool fsstrict)
|
const Files::PathContainer& musicDir,
|
||||||
|
bool fsstrict)
|
||||||
: mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY)))
|
: mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY)))
|
||||||
, updater(mgr)
|
, updater(mgr)
|
||||||
, cameraTracker(mgr)
|
, cameraTracker(mgr)
|
||||||
, store(str)
|
, store(str)
|
||||||
, files(soundDir), strict(soundDir)
|
, FSstrict(fsstrict)
|
||||||
,musicpath(musicDir), musicpathStrict(musicDir)
|
, files(soundDir)
|
||||||
|
, strict(soundDir)
|
||||||
|
, musicpath(musicDir)
|
||||||
|
, musicpathStrict(musicDir)
|
||||||
{
|
{
|
||||||
FSstrict = fsstrict;
|
|
||||||
cout << "Sound output: " << SOUND_OUT << endl;
|
std::cout << "Sound output: " << SOUND_OUT << std::endl;
|
||||||
cout << "Sound decoder: " << SOUND_IN << endl;
|
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
|
||||||
// Attach the camera to the camera tracker
|
// Attach the camera to the camera tracker
|
||||||
cameraTracker.followCamera(camera);
|
cameraTracker.followCamera(camera);
|
||||||
|
|
||||||
|
@ -136,36 +139,49 @@ namespace MWSound
|
||||||
|
|
||||||
bool hasFile(const std::string &str, bool music = false)
|
bool hasFile(const std::string &str, bool music = false)
|
||||||
{
|
{
|
||||||
if(FSstrict == false)
|
bool found = false;
|
||||||
|
if(!FSstrict)
|
||||||
{
|
{
|
||||||
if(music)
|
if(music)
|
||||||
{
|
{
|
||||||
if(musicpath.has(str)) return true;
|
found = musicpath.has(str);
|
||||||
|
|
||||||
// Not found? Try with .mp3
|
// Not found? Try with .mp3
|
||||||
return musicpath.has(toMp3(str));
|
if (!found)
|
||||||
|
{
|
||||||
|
found = musicpath.has(toMp3(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(files.has(str)) return true;
|
found = files.has(str);
|
||||||
return files.has(toMp3(str));
|
if (!found)
|
||||||
|
{
|
||||||
|
found = files.has(toMp3(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(music)
|
if(music)
|
||||||
{
|
{
|
||||||
if(musicpathStrict.has(str)) return true;
|
found = musicpathStrict.has(str);
|
||||||
|
|
||||||
// Not found? Try with .mp3
|
// Not found? Try with .mp3
|
||||||
return musicpathStrict.has(toMp3(str));
|
if (!found)
|
||||||
|
{
|
||||||
|
found = musicpathStrict.has(toMp3(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(strict.has(str)) return true;
|
found = strict.has(str);
|
||||||
return strict.has(toMp3(str));
|
if (!found)
|
||||||
|
{
|
||||||
|
found = strict.has(toMp3(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a Morrowind sound path (eg. Fx\funny.wav) to full path
|
// Convert a Morrowind sound path (eg. Fx\funny.wav) to full path
|
||||||
|
@ -258,13 +274,13 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
cout << "Error loading " << file << ", skipping.\n";
|
std::cout << "Error loading " << file << ", skipping.\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clears all the sub-elements of a given iterator, and then
|
// Clears all the sub-elements of a given iterator, and then
|
||||||
// removes it from 'sounds'.
|
// removes it from 'sounds'.
|
||||||
void clearAll(PtrMap::iterator it)
|
void clearAll(PtrMap::iterator& it)
|
||||||
{
|
{
|
||||||
IDMap::iterator sit = it->second.begin();
|
IDMap::iterator sit = it->second.begin();
|
||||||
|
|
||||||
|
@ -362,9 +378,9 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}; /* SoundImpl */
|
||||||
|
|
||||||
void SoundManager::streamMusicFull (const std::string& filename)
|
void SoundManager::streamMusicFull(const std::string& filename)
|
||||||
{
|
{
|
||||||
if(!mData) return;
|
if(!mData) return;
|
||||||
|
|
||||||
|
@ -381,20 +397,24 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera,
|
SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera,
|
||||||
const ESMS::ESMStore &store,
|
const ESMS::ESMStore &store, const Files::PathContainer& dataDirs,
|
||||||
boost::filesystem::path dataDir,
|
bool useSound, bool fsstrict, MWWorld::Environment& environment)
|
||||||
bool useSound, bool fsstrict, MWWorld::Environment& environment)
|
: mData(NULL)
|
||||||
: mData(NULL), fsStrict (fsstrict), mEnvironment (environment)
|
, fsStrict(fsstrict)
|
||||||
|
, mEnvironment(environment)
|
||||||
{
|
{
|
||||||
MP3Lookup(dataDir / "Music/Explore/");
|
for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it)
|
||||||
if(useSound)
|
{
|
||||||
mData = new SoundImpl(root, camera, store, (dataDir / "Sound").string(), (dataDir / "Music").string(), fsstrict);
|
MP3Lookup((*it) / "Music/Explore/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(useSound)
|
||||||
|
{
|
||||||
|
mData = new SoundImpl(root, camera, store, dataDirs /* Sound */, dataDirs /* Music */, fsstrict);
|
||||||
|
}
|
||||||
|
|
||||||
test.name = "";
|
test.name = "";
|
||||||
total = 0;
|
total = 0;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundManager::~SoundManager()
|
SoundManager::~SoundManager()
|
||||||
|
@ -407,14 +427,12 @@ namespace MWSound
|
||||||
{
|
{
|
||||||
if(mData->hasFile(filename, true))
|
if(mData->hasFile(filename, true))
|
||||||
{
|
{
|
||||||
std::string fullpath = mData->convertPath(filename, true);
|
streamMusicFull(mData->convertPath(filename, true));
|
||||||
streamMusicFull(fullpath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundManager::MP3Lookup(const boost::filesystem::path& dir)
|
||||||
void SoundManager::MP3Lookup(boost::filesystem::path dir)
|
{
|
||||||
{
|
|
||||||
boost::filesystem::directory_iterator dir_iter(dir), dir_end;
|
boost::filesystem::directory_iterator dir_iter(dir), dir_end;
|
||||||
|
|
||||||
std::string mp3extension = ".mp3";
|
std::string mp3extension = ".mp3";
|
||||||
|
@ -425,35 +443,30 @@ namespace MWSound
|
||||||
files.push_back(*dir_iter);
|
files.push_back(*dir_iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::startRandomTitle()
|
void SoundManager::startRandomTitle()
|
||||||
{
|
{
|
||||||
std::vector<boost::filesystem::path>::iterator fileIter;
|
if(!files.empty())
|
||||||
|
|
||||||
if(files.size() > 0)
|
|
||||||
{
|
{
|
||||||
fileIter = files.begin();
|
Files::PathContainer::iterator fileIter = files.begin();
|
||||||
srand ( time(NULL) );
|
srand( time(NULL) );
|
||||||
int r = rand() % files.size() + 1; //old random code
|
int r = rand() % files.size() + 1; //old random code
|
||||||
|
|
||||||
for(int i = 1; i < r; i++)
|
std::advance(fileIter, r - 1);
|
||||||
{
|
|
||||||
fileIter++;
|
|
||||||
}
|
|
||||||
std::string music = fileIter->string();
|
std::string music = fileIter->string();
|
||||||
|
std::cout << "Playing " << music << "\n";
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::cout << "Playing " << music << "\n";
|
|
||||||
streamMusicFull(music);
|
streamMusicFull(music);
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch (std::exception &e)
|
||||||
{
|
{
|
||||||
std::cout << " Music Error: " << e.what() << "\n";
|
std::cout << " Music Error: " << e.what() << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SoundManager::isMusicPlaying()
|
bool SoundManager::isMusicPlaying()
|
||||||
{
|
{
|
||||||
|
@ -465,14 +478,12 @@ namespace MWSound
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundManager::SoundImpl SoundManager::getMData()
|
SoundManager::SoundImpl SoundManager::getMData()
|
||||||
{
|
{
|
||||||
// bool test = mData->music->isPlaying();
|
// bool test = mData->music->isPlaying();
|
||||||
return *mData;
|
return *mData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SoundManager::say (MWWorld::Ptr ptr, const std::string& filename)
|
void SoundManager::say (MWWorld::Ptr ptr, const std::string& filename)
|
||||||
{
|
{
|
||||||
// The range values are not tested
|
// The range values are not tested
|
||||||
|
@ -480,7 +491,7 @@ namespace MWSound
|
||||||
if(mData->hasFile(filename))
|
if(mData->hasFile(filename))
|
||||||
mData->add(mData->convertPath(filename), ptr, "_say_sound", 1, 1, 100, 20000, false);
|
mData->add(mData->convertPath(filename), ptr, "_say_sound", 1, 1, 100, 20000, false);
|
||||||
else
|
else
|
||||||
cout << "Sound file " << filename << " not found, skipping.\n";
|
std::cout << "Sound file " << filename << " not found, skipping.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundManager::sayDone (MWWorld::Ptr ptr) const
|
bool SoundManager::sayDone (MWWorld::Ptr ptr) const
|
||||||
|
@ -490,20 +501,20 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SoundManager::playSound (const std::string& soundId, float volume, float pitch)
|
void SoundManager::playSound(const std::string& soundId, float volume, float pitch)
|
||||||
{
|
{
|
||||||
if(!mData) return;
|
if(!mData) return;
|
||||||
// Play and forget
|
// Play and forget
|
||||||
float min, max;
|
float min, max;
|
||||||
const std::string &file = mData->lookup(soundId, volume, min, max);
|
const std::string &file = mData->lookup(soundId, volume, min, max);
|
||||||
if(file != "")
|
if (file != "")
|
||||||
{
|
{
|
||||||
SoundPtr snd = mData->mgr->load(file);
|
SoundPtr snd = mData->mgr->load(file);
|
||||||
snd->setVolume(volume);
|
snd->setVolume(volume);
|
||||||
snd->setRange(min,max);
|
snd->setRange(min,max);
|
||||||
snd->setPitch(pitch);
|
snd->setPitch(pitch);
|
||||||
snd->play();
|
snd->play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::playSound3D (MWWorld::Ptr ptr, const std::string& soundId,
|
void SoundManager::playSound3D (MWWorld::Ptr ptr, const std::string& soundId,
|
||||||
|
@ -514,7 +525,7 @@ namespace MWSound
|
||||||
// Look up the sound in the ESM data
|
// Look up the sound in the ESM data
|
||||||
float min, max;
|
float min, max;
|
||||||
const std::string &file = mData->lookup(soundId, volume, min, max);
|
const std::string &file = mData->lookup(soundId, volume, min, max);
|
||||||
if(file != "")
|
if (file != "")
|
||||||
mData->add(file, ptr, soundId, volume, pitch, min, max, loop);
|
mData->add(file, ptr, soundId, volume, pitch, min, max, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,18 +552,19 @@ namespace MWSound
|
||||||
|
|
||||||
void SoundManager::updateObject(MWWorld::Ptr ptr)
|
void SoundManager::updateObject(MWWorld::Ptr ptr)
|
||||||
{
|
{
|
||||||
if(!mData) return;
|
if (mData != NULL)
|
||||||
mData->updatePositions(ptr);
|
{
|
||||||
|
mData->updatePositions(ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::update (float duration)
|
void SoundManager::update (float duration)
|
||||||
{
|
{
|
||||||
std::string effect;
|
|
||||||
|
|
||||||
MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell();
|
MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell();
|
||||||
|
|
||||||
//If the region has changed
|
//If the region has changed
|
||||||
if(!(current->cell->data.flags & current->cell->Interior) && timer.elapsed() >= 10){
|
if(!(current->cell->data.flags & current->cell->Interior) && timer.elapsed() >= 10)
|
||||||
|
{
|
||||||
timer.restart();
|
timer.restart();
|
||||||
if (test.name != current->cell->region)
|
if (test.name != current->cell->region)
|
||||||
{
|
{
|
||||||
|
@ -564,11 +576,12 @@ namespace MWSound
|
||||||
{
|
{
|
||||||
std::vector<ESM::Region::SoundRef>::iterator soundIter = test.soundList.begin();
|
std::vector<ESM::Region::SoundRef>::iterator soundIter = test.soundList.begin();
|
||||||
//mEnvironment.mSoundManager
|
//mEnvironment.mSoundManager
|
||||||
if(total == 0){
|
if(total == 0)
|
||||||
while (!(soundIter == test.soundList.end()))
|
{
|
||||||
|
while (soundIter != test.soundList.end())
|
||||||
{
|
{
|
||||||
ESM::NAME32 go = soundIter->sound;
|
|
||||||
int chance = (int) soundIter->chance;
|
int chance = (int) soundIter->chance;
|
||||||
|
//ESM::NAME32 go = soundIter->sound;
|
||||||
//std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n";
|
//std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n";
|
||||||
soundIter++;
|
soundIter++;
|
||||||
total += chance;
|
total += chance;
|
||||||
|
@ -578,7 +591,7 @@ namespace MWSound
|
||||||
int r = rand() % total; //old random code
|
int r = rand() % total; //old random code
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
soundIter = test.soundList.begin();
|
soundIter = test.soundList.begin();
|
||||||
while (!(soundIter == test.soundList.end()))
|
while (soundIter != test.soundList.end())
|
||||||
{
|
{
|
||||||
const ESM::NAME32 go = soundIter->sound;
|
const ESM::NAME32 go = soundIter->sound;
|
||||||
int chance = (int) soundIter->chance;
|
int chance = (int) soundIter->chance;
|
||||||
|
@ -586,13 +599,11 @@ namespace MWSound
|
||||||
soundIter++;
|
soundIter++;
|
||||||
if( r - pos < chance)
|
if( r - pos < chance)
|
||||||
{
|
{
|
||||||
effect = go.name;
|
|
||||||
//play sound
|
//play sound
|
||||||
std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n";
|
std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n";
|
||||||
mEnvironment.mSoundManager->playSound(effect, 20.0, 1.0);
|
mEnvironment.mSoundManager->playSound(go.name, 20.0, 1.0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
pos += chance;
|
pos += chance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
#define GAME_SOUND_SOUNDMANAGER_H
|
#define GAME_SOUND_SOUNDMANAGER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/timer.hpp>
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include <openengine/sound/sndmanager.hpp>
|
#include <openengine/sound/sndmanager.hpp>
|
||||||
|
#include <components/files/multidircollection.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <boost/timer.hpp>
|
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
|
@ -37,7 +38,7 @@ namespace MWSound
|
||||||
struct SoundImpl;
|
struct SoundImpl;
|
||||||
|
|
||||||
SoundImpl *mData;
|
SoundImpl *mData;
|
||||||
std::vector<boost::filesystem::path> files;
|
Files::PathContainer files;
|
||||||
bool fsStrict;
|
bool fsStrict;
|
||||||
MWWorld::Environment& mEnvironment;
|
MWWorld::Environment& mEnvironment;
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ namespace MWSound
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SoundManager(Ogre::Root*, Ogre::Camera*, const ESMS::ESMStore &store,
|
SoundManager(Ogre::Root*, Ogre::Camera*, const ESMS::ESMStore &store,
|
||||||
boost::filesystem::path dataDir, bool useSound, bool fsstrict,
|
const Files::PathContainer& dataDir, bool useSound, bool fsstrict,
|
||||||
MWWorld::Environment& environment);
|
MWWorld::Environment& environment);
|
||||||
~SoundManager();
|
~SoundManager();
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ namespace MWSound
|
||||||
/// \param filename name of a sound file in "Music/" in the data directory.
|
/// \param filename name of a sound file in "Music/" in the data directory.
|
||||||
|
|
||||||
void startRandomTitle();
|
void startRandomTitle();
|
||||||
void MP3Lookup(boost::filesystem::path dir);
|
void MP3Lookup(const boost::filesystem::path& dir);
|
||||||
|
|
||||||
bool isMusicPlaying();
|
bool isMusicPlaying();
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
#include "environment.hpp"
|
#include "environment.hpp"
|
||||||
#include "world.hpp"
|
#include "world.hpp"
|
||||||
|
#include "containerstore.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -14,8 +15,7 @@ namespace MWWorld
|
||||||
// insert into player's inventory
|
// insert into player's inventory
|
||||||
MWWorld::Ptr player = environment.mWorld->getPtr ("player", true);
|
MWWorld::Ptr player = environment.mWorld->getPtr ("player", true);
|
||||||
|
|
||||||
MWWorld::Class::get (mObject).insertIntoContainer (mObject,
|
MWWorld::Class::get (player).getContainerStore (player).add (mObject);
|
||||||
MWWorld::Class::get (player).getContainerStore (player));
|
|
||||||
|
|
||||||
// remove from world
|
// remove from world
|
||||||
environment.mWorld->deleteObject (mObject);
|
environment.mWorld->deleteObject (mObject);
|
||||||
|
|
|
@ -63,10 +63,11 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getExterior (int x, int y)
|
||||||
|
|
||||||
result = mExteriors.insert (std::make_pair (
|
result = mExteriors.insert (std::make_pair (
|
||||||
std::make_pair (x, y), Ptr::CellStore (cell))).first;
|
std::make_pair (x, y), Ptr::CellStore (cell))).first;
|
||||||
|
|
||||||
result->second.load (mStore, mReader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result->second.mState!=Ptr::CellStore::State_Loaded)
|
||||||
|
result->second.load (mStore, mReader);
|
||||||
|
|
||||||
return &result->second;
|
return &result->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +80,11 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getInterior (const std::string& name)
|
||||||
const ESM::Cell *cell = mStore.cells.findInt (name);
|
const ESM::Cell *cell = mStore.cells.findInt (name);
|
||||||
|
|
||||||
result = mInteriors.insert (std::make_pair (name, Ptr::CellStore (cell))).first;
|
result = mInteriors.insert (std::make_pair (name, Ptr::CellStore (cell))).first;
|
||||||
|
|
||||||
result->second.load (mStore, mReader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result->second.mState!=Ptr::CellStore::State_Loaded)
|
||||||
|
result->second.load (mStore, mReader);
|
||||||
|
|
||||||
return &result->second;
|
return &result->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "ptr.hpp"
|
#include "ptr.hpp"
|
||||||
#include "nullaction.hpp"
|
#include "nullaction.hpp"
|
||||||
|
#include "containerstore.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -71,16 +72,11 @@ namespace MWWorld
|
||||||
return boost::shared_ptr<Action> (new NullAction);
|
return boost::shared_ptr<Action> (new NullAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
ContainerStore<RefData>& Class::getContainerStore (const Ptr& ptr) const
|
ContainerStore& Class::getContainerStore (const Ptr& ptr) const
|
||||||
{
|
{
|
||||||
throw std::runtime_error ("class does not have a container store");
|
throw std::runtime_error ("class does not have a container store");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Class::insertIntoContainer (const Ptr& ptr, ContainerStore<RefData>& containerStore) const
|
|
||||||
{
|
|
||||||
throw std::runtime_error ("class does not support inserting into a container");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Class::lock (const Ptr& ptr, int lockLevel) const
|
void Class::lock (const Ptr& ptr, int lockLevel) const
|
||||||
{
|
{
|
||||||
throw std::runtime_error ("class does not support locking");
|
throw std::runtime_error ("class does not support locking");
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include "action.hpp"
|
#include "action.hpp"
|
||||||
#include "containerstore.hpp"
|
|
||||||
#include "refdata.hpp"
|
#include "refdata.hpp"
|
||||||
#include "../mwrender/renderinginterface.hpp"
|
|
||||||
#include "physicssystem.hpp"
|
#include "physicssystem.hpp"
|
||||||
|
|
||||||
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class Vector3;
|
class Vector3;
|
||||||
|
@ -33,6 +33,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
class Ptr;
|
class Ptr;
|
||||||
class Environment;
|
class Environment;
|
||||||
|
class ContainerStore;
|
||||||
|
|
||||||
/// \brief Base class for referenceable esm records
|
/// \brief Base class for referenceable esm records
|
||||||
class Class
|
class Class
|
||||||
|
@ -61,8 +62,6 @@ namespace MWWorld
|
||||||
///< Return ID of \a ptr or throw an exception, if class does not support ID retrieval
|
///< Return ID of \a ptr or throw an exception, if class does not support ID retrieval
|
||||||
/// (default implementation: throw an exception)
|
/// (default implementation: throw an exception)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
virtual void insertObjectRendering (const Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
virtual void insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
|
virtual void insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
|
||||||
///< Add reference into a cell for rendering (default implementation: don't render anything).
|
///< Add reference into a cell for rendering (default implementation: don't render anything).
|
||||||
|
@ -105,15 +104,10 @@ namespace MWWorld
|
||||||
///< Generate action for using via inventory menu (default implementation: return a
|
///< Generate action for using via inventory menu (default implementation: return a
|
||||||
/// null action).
|
/// null action).
|
||||||
|
|
||||||
virtual ContainerStore<RefData>& getContainerStore (const Ptr& ptr) const;
|
virtual ContainerStore& getContainerStore (const Ptr& ptr) const;
|
||||||
///< Return container store or throw an exception, if class does not have a
|
///< Return container store or throw an exception, if class does not have a
|
||||||
/// container store (default implementation: throw an exceoption)
|
/// container store (default implementation: throw an exceoption)
|
||||||
|
|
||||||
virtual void insertIntoContainer (const Ptr& ptr, ContainerStore<RefData>& containerStore)
|
|
||||||
const;
|
|
||||||
///< Insert into a container or throw an exception, if class does not support inserting into
|
|
||||||
/// a container.
|
|
||||||
|
|
||||||
virtual void lock (const Ptr& ptr, int lockLevel) const;
|
virtual void lock (const Ptr& ptr, int lockLevel) const;
|
||||||
///< Lock object (default implementation: throw an exception)
|
///< Lock object (default implementation: throw an exception)
|
||||||
|
|
||||||
|
|
342
apps/openmw/mwworld/containerstore.cpp
Normal file
342
apps/openmw/mwworld/containerstore.cpp
Normal file
|
@ -0,0 +1,342 @@
|
||||||
|
|
||||||
|
#include "containerstore.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::begin (int mask)
|
||||||
|
{
|
||||||
|
return ContainerStoreIterator (mask, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end()
|
||||||
|
{
|
||||||
|
return ContainerStoreIterator (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::ContainerStore::add (const Ptr& ptr)
|
||||||
|
{
|
||||||
|
/// \todo implement item stocking
|
||||||
|
|
||||||
|
switch (getType (ptr))
|
||||||
|
{
|
||||||
|
case Type_Potion: potions.list.push_back (*ptr.get<ESM::Potion>()); break;
|
||||||
|
case Type_Apparatus: appas.list.push_back (*ptr.get<ESM::Apparatus>()); break;
|
||||||
|
case Type_Armor: armors.list.push_back (*ptr.get<ESM::Armor>()); break;
|
||||||
|
case Type_Book: books.list.push_back (*ptr.get<ESM::Book>()); break;
|
||||||
|
case Type_Clothing: clothes.list.push_back (*ptr.get<ESM::Clothing>()); break;
|
||||||
|
case Type_Ingredient: ingreds.list.push_back (*ptr.get<ESM::Ingredient>()); break;
|
||||||
|
case Type_Light: lights.list.push_back (*ptr.get<ESM::Light>()); break;
|
||||||
|
case Type_Lockpick: lockpicks.list.push_back (*ptr.get<ESM::Tool>()); break;
|
||||||
|
case Type_Miscellaneous: miscItems.list.push_back (*ptr.get<ESM::Miscellaneous>()); break;
|
||||||
|
case Type_Probe: probes.list.push_back (*ptr.get<ESM::Probe>()); break;
|
||||||
|
case Type_Repair: repairs.list.push_back (*ptr.get<ESM::Repair>()); break;
|
||||||
|
case Type_Weapon: weapons.list.push_back (*ptr.get<ESM::Weapon>()); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MWWorld::ContainerStore::getType (const Ptr& ptr)
|
||||||
|
{
|
||||||
|
if (ptr.isEmpty())
|
||||||
|
throw std::runtime_error ("can't put a non-existent object into a container");
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Potion).name())
|
||||||
|
return Type_Potion;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Apparatus).name())
|
||||||
|
return Type_Apparatus;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Armor).name())
|
||||||
|
return Type_Armor;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Book).name())
|
||||||
|
return Type_Book;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Clothing).name())
|
||||||
|
return Type_Clothing;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Ingredient).name())
|
||||||
|
return Type_Ingredient;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Light).name())
|
||||||
|
return Type_Light;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Tool).name())
|
||||||
|
return Type_Lockpick;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Miscellaneous).name())
|
||||||
|
return Type_Miscellaneous;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Probe).name())
|
||||||
|
return Type_Probe;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Repair).name())
|
||||||
|
return Type_Repair;
|
||||||
|
|
||||||
|
if (ptr.getTypeName()==typeid (ESM::Weapon).name())
|
||||||
|
return Type_Weapon;
|
||||||
|
|
||||||
|
throw std::runtime_error (
|
||||||
|
"Object of type " + ptr.getTypeName() + " can not be placed into a container");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container)
|
||||||
|
: mType (-1), mMask (0), mContainer (container)
|
||||||
|
{}
|
||||||
|
|
||||||
|
MWWorld::ContainerStoreIterator::ContainerStoreIterator (int mask, ContainerStore *container)
|
||||||
|
: mType (0), mMask (mask), mContainer (container)
|
||||||
|
{
|
||||||
|
nextType();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::ContainerStoreIterator::incType()
|
||||||
|
{
|
||||||
|
if (mType==0)
|
||||||
|
mType = 1;
|
||||||
|
else if (mType!=-1)
|
||||||
|
{
|
||||||
|
mType <<= 1;
|
||||||
|
|
||||||
|
if (mType>ContainerStore::Type_Last)
|
||||||
|
mType = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::ContainerStoreIterator::nextType()
|
||||||
|
{
|
||||||
|
while (mType!=-1)
|
||||||
|
{
|
||||||
|
incType();
|
||||||
|
|
||||||
|
if (mType & mMask)
|
||||||
|
if (resetIterator())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MWWorld::ContainerStoreIterator::resetIterator()
|
||||||
|
{
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case ContainerStore::Type_Potion:
|
||||||
|
|
||||||
|
mPotion = mContainer->potions.list.begin();
|
||||||
|
return mPotion!=mContainer->potions.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Apparatus:
|
||||||
|
|
||||||
|
mApparatus = mContainer->appas.list.begin();
|
||||||
|
return mApparatus!=mContainer->appas.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Armor:
|
||||||
|
|
||||||
|
mArmor = mContainer->armors.list.begin();
|
||||||
|
return mArmor!=mContainer->armors.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Book:
|
||||||
|
|
||||||
|
mBook = mContainer->books.list.begin();
|
||||||
|
return mBook!=mContainer->books.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Clothing:
|
||||||
|
|
||||||
|
mClothing = mContainer->clothes.list.begin();
|
||||||
|
return mClothing!=mContainer->clothes.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Ingredient:
|
||||||
|
|
||||||
|
mIngredient = mContainer->ingreds.list.begin();
|
||||||
|
return mIngredient!=mContainer->ingreds.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Light:
|
||||||
|
|
||||||
|
mLight = mContainer->lights.list.begin();
|
||||||
|
return mLight!=mContainer->lights.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Lockpick:
|
||||||
|
|
||||||
|
mLockpick = mContainer->lockpicks.list.begin();
|
||||||
|
return mLockpick!=mContainer->lockpicks.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Miscellaneous:
|
||||||
|
|
||||||
|
mMiscellaneous = mContainer->miscItems.list.begin();
|
||||||
|
return mMiscellaneous!=mContainer->miscItems.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Probe:
|
||||||
|
|
||||||
|
mProbe = mContainer->probes.list.begin();
|
||||||
|
return mProbe!=mContainer->probes.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Repair:
|
||||||
|
|
||||||
|
mRepair = mContainer->repairs.list.begin();
|
||||||
|
return mRepair!=mContainer->repairs.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Weapon:
|
||||||
|
|
||||||
|
mWeapon = mContainer->weapons.list.begin();
|
||||||
|
return mWeapon!=mContainer->weapons.list.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MWWorld::ContainerStoreIterator::incIterator()
|
||||||
|
{
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case ContainerStore::Type_Potion:
|
||||||
|
|
||||||
|
++mPotion;
|
||||||
|
return mPotion==mContainer->potions.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Apparatus:
|
||||||
|
|
||||||
|
++mApparatus;
|
||||||
|
return mApparatus==mContainer->appas.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Armor:
|
||||||
|
|
||||||
|
++mArmor;
|
||||||
|
return mArmor==mContainer->armors.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Book:
|
||||||
|
|
||||||
|
++mBook;
|
||||||
|
return mBook==mContainer->books.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Clothing:
|
||||||
|
|
||||||
|
++mClothing;
|
||||||
|
return mClothing==mContainer->clothes.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Ingredient:
|
||||||
|
|
||||||
|
++mIngredient;
|
||||||
|
return mIngredient==mContainer->ingreds.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Light:
|
||||||
|
|
||||||
|
++mLight;
|
||||||
|
return mLight==mContainer->lights.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Lockpick:
|
||||||
|
|
||||||
|
++mLockpick;
|
||||||
|
return mLockpick==mContainer->lockpicks.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Miscellaneous:
|
||||||
|
|
||||||
|
++mMiscellaneous;
|
||||||
|
return mMiscellaneous==mContainer->miscItems.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Probe:
|
||||||
|
|
||||||
|
++mProbe;
|
||||||
|
return mProbe==mContainer->probes.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Repair:
|
||||||
|
|
||||||
|
++mRepair;
|
||||||
|
return mRepair==mContainer->repairs.list.end();
|
||||||
|
|
||||||
|
case ContainerStore::Type_Weapon:
|
||||||
|
|
||||||
|
++mWeapon;
|
||||||
|
return mWeapon==mContainer->weapons.list.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MWWorld::Ptr *MWWorld::ContainerStoreIterator::operator->() const
|
||||||
|
{
|
||||||
|
mPtr = **this;
|
||||||
|
return &mPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
MWWorld::Ptr MWWorld::ContainerStoreIterator::operator*() const
|
||||||
|
{
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case ContainerStore::Type_Potion: return MWWorld::Ptr (&*mPotion, 0);
|
||||||
|
case ContainerStore::Type_Apparatus: return MWWorld::Ptr (&*mApparatus, 0);
|
||||||
|
case ContainerStore::Type_Armor: return MWWorld::Ptr (&*mArmor, 0);
|
||||||
|
case ContainerStore::Type_Book: return MWWorld::Ptr (&*mBook, 0);
|
||||||
|
case ContainerStore::Type_Clothing: return MWWorld::Ptr (&*mClothing, 0);
|
||||||
|
case ContainerStore::Type_Ingredient: return MWWorld::Ptr (&*mIngredient, 0);
|
||||||
|
case ContainerStore::Type_Light: return MWWorld::Ptr (&*mLight, 0);
|
||||||
|
case ContainerStore::Type_Lockpick: return MWWorld::Ptr (&*mLockpick, 0);
|
||||||
|
case ContainerStore::Type_Miscellaneous: return MWWorld::Ptr (&*mMiscellaneous, 0);
|
||||||
|
case ContainerStore::Type_Probe: return MWWorld::Ptr (&*mProbe, 0);
|
||||||
|
case ContainerStore::Type_Repair: return MWWorld::Ptr (&*mRepair, 0);
|
||||||
|
case ContainerStore::Type_Weapon: return MWWorld::Ptr (&*mWeapon, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error ("invalid pointer");
|
||||||
|
}
|
||||||
|
|
||||||
|
MWWorld::ContainerStoreIterator& MWWorld::ContainerStoreIterator::operator++()
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (incIterator())
|
||||||
|
nextType();
|
||||||
|
}
|
||||||
|
while (mType!=-1 && !(**this).getRefData().getCount());
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStoreIterator::operator++ (int)
|
||||||
|
{
|
||||||
|
ContainerStoreIterator iter (*this);
|
||||||
|
++*this;
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MWWorld::ContainerStoreIterator::isEqual (const ContainerStoreIterator& iter) const
|
||||||
|
{
|
||||||
|
assert (mContainer==iter.mContainer);
|
||||||
|
|
||||||
|
if (mType!=iter.mType)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case ContainerStore::Type_Potion: return mPotion==iter.mPotion;
|
||||||
|
case ContainerStore::Type_Apparatus: return mApparatus==iter.mApparatus;
|
||||||
|
case ContainerStore::Type_Armor: return mArmor==iter.mArmor;
|
||||||
|
case ContainerStore::Type_Book: return mBook==iter.mBook;
|
||||||
|
case ContainerStore::Type_Clothing: return mClothing==iter.mClothing;
|
||||||
|
case ContainerStore::Type_Ingredient: return mIngredient==iter.mIngredient;
|
||||||
|
case ContainerStore::Type_Light: return mLight==iter.mLight;
|
||||||
|
case ContainerStore::Type_Lockpick: return mLockpick==iter.mLockpick;
|
||||||
|
case ContainerStore::Type_Miscellaneous: return mMiscellaneous==iter.mMiscellaneous;
|
||||||
|
case ContainerStore::Type_Probe: return mProbe==iter.mProbe;
|
||||||
|
case ContainerStore::Type_Repair: return mRepair==iter.mRepair;
|
||||||
|
case ContainerStore::Type_Weapon: return mWeapon==iter.mWeapon;
|
||||||
|
case -1: return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MWWorld::ContainerStoreIterator::getType() const
|
||||||
|
{
|
||||||
|
return mType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MWWorld::operator== (const ContainerStoreIterator& left, const ContainerStoreIterator& right)
|
||||||
|
{
|
||||||
|
return left.isEqual (right);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MWWorld::operator!= (const ContainerStoreIterator& left, const ContainerStoreIterator& right)
|
||||||
|
{
|
||||||
|
return !(left==right);
|
||||||
|
}
|
|
@ -3,24 +3,134 @@
|
||||||
|
|
||||||
#include <components/esm_store/cell_store.hpp>
|
#include <components/esm_store/cell_store.hpp>
|
||||||
|
|
||||||
|
#include "refdata.hpp"
|
||||||
|
#include "ptr.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
template<typename D>
|
class ContainerStoreIterator;
|
||||||
struct ContainerStore
|
|
||||||
|
class ContainerStore
|
||||||
{
|
{
|
||||||
ESMS::CellRefList<ESM::Potion, D> potions;
|
public:
|
||||||
ESMS::CellRefList<ESM::Apparatus, D> appas;
|
|
||||||
ESMS::CellRefList<ESM::Armor, D> armors;
|
static const int Type_Potion = 0x0001;
|
||||||
ESMS::CellRefList<ESM::Book, D> books;
|
static const int Type_Apparatus = 0x0002;
|
||||||
ESMS::CellRefList<ESM::Clothing, D> clothes;
|
static const int Type_Armor = 0x0004;
|
||||||
ESMS::CellRefList<ESM::Ingredient, D> ingreds;
|
static const int Type_Book = 0x0008;
|
||||||
ESMS::CellRefList<ESM::Light, D> lights;
|
static const int Type_Clothing = 0x0010;
|
||||||
ESMS::CellRefList<ESM::Tool, D> lockpicks;
|
static const int Type_Ingredient = 0x0020;
|
||||||
ESMS::CellRefList<ESM::Miscellaneous, D> miscItems;
|
static const int Type_Light = 0x0040;
|
||||||
ESMS::CellRefList<ESM::Probe, D> probes;
|
static const int Type_Lockpick = 0x0080;
|
||||||
ESMS::CellRefList<ESM::Repair, D> repairs;
|
static const int Type_Miscellaneous = 0x0100;
|
||||||
ESMS::CellRefList<ESM::Weapon, D> weapons;
|
static const int Type_Probe = 0x0200;
|
||||||
|
static const int Type_Repair = 0x0400;
|
||||||
|
static const int Type_Weapon = 0x0800;
|
||||||
|
|
||||||
|
static const int Type_Last = Type_Weapon;
|
||||||
|
|
||||||
|
static const int Type_All = 0xffff;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ESMS::CellRefList<ESM::Potion, RefData> potions;
|
||||||
|
ESMS::CellRefList<ESM::Apparatus, RefData> appas;
|
||||||
|
ESMS::CellRefList<ESM::Armor, RefData> armors;
|
||||||
|
ESMS::CellRefList<ESM::Book, RefData> books;
|
||||||
|
ESMS::CellRefList<ESM::Clothing, RefData> clothes;
|
||||||
|
ESMS::CellRefList<ESM::Ingredient, RefData> ingreds;
|
||||||
|
ESMS::CellRefList<ESM::Light, RefData> lights;
|
||||||
|
ESMS::CellRefList<ESM::Tool, RefData> lockpicks;
|
||||||
|
ESMS::CellRefList<ESM::Miscellaneous, RefData> miscItems;
|
||||||
|
ESMS::CellRefList<ESM::Probe, RefData> probes;
|
||||||
|
ESMS::CellRefList<ESM::Repair, RefData> repairs;
|
||||||
|
ESMS::CellRefList<ESM::Weapon, RefData> weapons;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ContainerStoreIterator begin (int mask = Type_All);
|
||||||
|
|
||||||
|
ContainerStoreIterator end();
|
||||||
|
|
||||||
|
void add (const Ptr& ptr);
|
||||||
|
///< Add the item pointed to by \a ptr to this container.
|
||||||
|
///
|
||||||
|
/// \note The item pointed to is not required to exist beyond this function call.
|
||||||
|
///
|
||||||
|
/// \attention Do not add items to an existing stack by increasing the count instead of
|
||||||
|
/// calling this function!
|
||||||
|
|
||||||
|
static int getType (const Ptr& ptr);
|
||||||
|
///< This function throws an exception, if ptr does not point to an object, that can be
|
||||||
|
/// put into a container.
|
||||||
|
|
||||||
|
friend class ContainerStoreIterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief Iteration over a subset of objects in a ContainerStore
|
||||||
|
///
|
||||||
|
/// \note The iterator will automatically skip over deleted objects.
|
||||||
|
class ContainerStoreIterator
|
||||||
|
{
|
||||||
|
int mType;
|
||||||
|
int mMask;
|
||||||
|
ContainerStore *mContainer;
|
||||||
|
mutable Ptr mPtr;
|
||||||
|
|
||||||
|
ESMS::CellRefList<ESM::Potion, RefData>::List::iterator mPotion;
|
||||||
|
ESMS::CellRefList<ESM::Apparatus, RefData>::List::iterator mApparatus;
|
||||||
|
ESMS::CellRefList<ESM::Armor, RefData>::List::iterator mArmor;
|
||||||
|
ESMS::CellRefList<ESM::Book, RefData>::List::iterator mBook;
|
||||||
|
ESMS::CellRefList<ESM::Clothing, RefData>::List::iterator mClothing;
|
||||||
|
ESMS::CellRefList<ESM::Ingredient, RefData>::List::iterator mIngredient;
|
||||||
|
ESMS::CellRefList<ESM::Light, RefData>::List::iterator mLight;
|
||||||
|
ESMS::CellRefList<ESM::Tool, RefData>::List::iterator mLockpick;
|
||||||
|
ESMS::CellRefList<ESM::Miscellaneous, RefData>::List::iterator mMiscellaneous;
|
||||||
|
ESMS::CellRefList<ESM::Probe, RefData>::List::iterator mProbe;
|
||||||
|
ESMS::CellRefList<ESM::Repair, RefData>::List::iterator mRepair;
|
||||||
|
ESMS::CellRefList<ESM::Weapon, RefData>::List::iterator mWeapon;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ContainerStoreIterator (ContainerStore *container);
|
||||||
|
///< End-iterator
|
||||||
|
|
||||||
|
ContainerStoreIterator (int mask, ContainerStore *container);
|
||||||
|
///< Begin-iterator
|
||||||
|
|
||||||
|
void incType();
|
||||||
|
|
||||||
|
void nextType();
|
||||||
|
|
||||||
|
bool resetIterator();
|
||||||
|
///< Reset iterator for selected type.
|
||||||
|
///
|
||||||
|
/// \return Type not empty?
|
||||||
|
|
||||||
|
bool incIterator();
|
||||||
|
///< Increment iterator for selected type.
|
||||||
|
///
|
||||||
|
/// \return reached the end?
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Ptr *operator->() const;
|
||||||
|
|
||||||
|
Ptr operator*() const;
|
||||||
|
|
||||||
|
ContainerStoreIterator& operator++();
|
||||||
|
|
||||||
|
ContainerStoreIterator operator++ (int);
|
||||||
|
|
||||||
|
bool isEqual (const ContainerStoreIterator& iter) const;
|
||||||
|
|
||||||
|
int getType() const;
|
||||||
|
|
||||||
|
friend class ContainerStore;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator== (const ContainerStoreIterator& left, const ContainerStoreIterator& right);
|
||||||
|
bool operator!= (const ContainerStoreIterator& left, const ContainerStoreIterator& right);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
|
|
||||||
#include "containerutil.hpp"
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
void listItemsInContainerImp (const std::string& id,
|
|
||||||
ESMS::CellRefList<T, MWWorld::RefData>& containerStore,
|
|
||||||
const ESMS::RecListT<T>& store, std::vector<MWWorld::Ptr>& list)
|
|
||||||
{
|
|
||||||
if (const T *record = store.search (id))
|
|
||||||
{
|
|
||||||
for (typename ESMS::CellRefList<T, MWWorld::RefData>::List::iterator iter
|
|
||||||
(containerStore.list.begin());
|
|
||||||
iter!=containerStore.list.end(); ++iter)
|
|
||||||
{
|
|
||||||
if (iter->base==record)
|
|
||||||
list.push_back (MWWorld::Ptr (&*iter, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MWWorld
|
|
||||||
{
|
|
||||||
void listItemsInContainer (const std::string& id,
|
|
||||||
ContainerStore<MWWorld::RefData>& containerStore,
|
|
||||||
const ESMS::ESMStore& store, std::vector<Ptr>& list)
|
|
||||||
{
|
|
||||||
listItemsInContainerImp (id, containerStore.potions, store.potions, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.appas, store.appas, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.armors, store.armors, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.books, store.books, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.clothes, store.clothes, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.ingreds, store.ingreds, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.lights, store.lights, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.lockpicks, store.lockpicks, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.miscItems, store.miscItems, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.probes, store.probes, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.repairs, store.repairs, list);
|
|
||||||
listItemsInContainerImp (id, containerStore.weapons, store.weapons, list);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef GAME_MWWORLD_CONTAINERUTIL_H
|
|
||||||
#define GAME_MWWORLD_CONTAINERUTIL_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <components/esm_store/store.hpp>
|
|
||||||
|
|
||||||
#include "containerstore.hpp"
|
|
||||||
#include "ptr.hpp"
|
|
||||||
#include "refdata.hpp"
|
|
||||||
|
|
||||||
namespace MWWorld
|
|
||||||
{
|
|
||||||
void listItemsInContainer (const std::string& id, ContainerStore<MWWorld::RefData>& containerStore,
|
|
||||||
const ESMS::ESMStore& store, std::vector<Ptr>& list);
|
|
||||||
///< append all references with the given id to list.
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -9,6 +9,7 @@ namespace MWSound
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
{
|
{
|
||||||
class GlobalScripts;
|
class GlobalScripts;
|
||||||
|
class ScriptManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
|
@ -41,7 +42,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Environment()
|
Environment()
|
||||||
: mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0),
|
: mWorld (0), mSoundManager (0), mGlobalScripts (0), mScriptManager (0), mWindowManager (0),
|
||||||
mMechanicsManager (0), mDialogueManager (0), mJournal (0), mFrameDuration (0),
|
mMechanicsManager (0), mDialogueManager (0), mJournal (0), mFrameDuration (0),
|
||||||
mInputManager (0)
|
mInputManager (0)
|
||||||
{}
|
{}
|
||||||
|
@ -49,6 +50,7 @@ namespace MWWorld
|
||||||
World *mWorld;
|
World *mWorld;
|
||||||
MWSound::SoundManager *mSoundManager;
|
MWSound::SoundManager *mSoundManager;
|
||||||
MWScript::GlobalScripts *mGlobalScripts;
|
MWScript::GlobalScripts *mGlobalScripts;
|
||||||
|
MWScript::ScriptManager *mScriptManager;
|
||||||
MWGui::WindowManager *mWindowManager;
|
MWGui::WindowManager *mWindowManager;
|
||||||
MWMechanics::MechanicsManager *mMechanicsManager;
|
MWMechanics::MechanicsManager *mMechanicsManager;
|
||||||
MWDialogue::DialogueManager *mDialogueManager;
|
MWDialogue::DialogueManager *mDialogueManager;
|
||||||
|
|
|
@ -82,6 +82,7 @@ namespace MWWorld
|
||||||
|
|
||||||
// initialise
|
// initialise
|
||||||
ESM::CellRef& cellRef = mPtr.getCellRef();
|
ESM::CellRef& cellRef = mPtr.getCellRef();
|
||||||
|
cellRef.refID = name;
|
||||||
cellRef.refnum = -1;
|
cellRef.refnum = -1;
|
||||||
cellRef.scale = 1;
|
cellRef.scale = 1;
|
||||||
cellRef.factIndex = 0;
|
cellRef.factIndex = 0;
|
||||||
|
|
|
@ -50,6 +50,17 @@ namespace MWWorld
|
||||||
|
|
||||||
return mEngine->rayTest(from,to);
|
return mEngine->rayTest(from,to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
|
||||||
|
{
|
||||||
|
btVector3 _from, _to;
|
||||||
|
_from = btVector3(from.x, from.y, from.z);
|
||||||
|
_to = btVector3(to.x, to.y, to.z);
|
||||||
|
|
||||||
|
std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
|
||||||
|
|
||||||
|
return !(result.first == "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysics (float duration,
|
std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysics (float duration,
|
||||||
|
@ -109,7 +120,7 @@ namespace MWWorld
|
||||||
void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
|
void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
|
||||||
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
|
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
|
||||||
{
|
{
|
||||||
OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle);
|
OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale);
|
||||||
mEngine->addRigidBody(body);
|
mEngine->addRigidBody(body);
|
||||||
btTransform tr;
|
btTransform tr;
|
||||||
tr.setOrigin(btVector3(position.x,position.y,position.z));
|
tr.setOrigin(btVector3(position.x,position.y,position.z));
|
||||||
|
|
|
@ -33,11 +33,15 @@ namespace MWWorld
|
||||||
void scaleObject (const std::string& handle, float scale);
|
void scaleObject (const std::string& handle, float scale);
|
||||||
|
|
||||||
bool toggleCollisionMode();
|
bool toggleCollisionMode();
|
||||||
std::pair<std::string, float> getFacedHandle (MWWorld::World& world);
|
|
||||||
|
std::pair<std::string, float> getFacedHandle (MWWorld::World& world);
|
||||||
|
|
||||||
|
// cast ray, return true if it hit something
|
||||||
|
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to);
|
||||||
|
|
||||||
void insertObjectPhysics(const MWWorld::Ptr& ptr, std::string model);
|
void insertObjectPhysics(const MWWorld::Ptr& ptr, std::string model);
|
||||||
|
|
||||||
void insertActorPhysics(const MWWorld::Ptr&, std::string model);
|
void insertActorPhysics(const MWWorld::Ptr&, std::string model);
|
||||||
|
|
||||||
OEngine::Physic::PhysicEngine* getEngine();
|
OEngine::Physic::PhysicEngine* getEngine();
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,12 @@ namespace MWWorld
|
||||||
std::cout << "Unloading cell\n";
|
std::cout << "Unloading cell\n";
|
||||||
ListHandles functor;
|
ListHandles functor;
|
||||||
|
|
||||||
MWWorld::Ptr::CellStore* active = *iter;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
active->forEach<ListHandles>(functor);
|
|
||||||
|
(*iter)->forEach<ListHandles>(functor);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -77,13 +77,15 @@ namespace MWWorld
|
||||||
mPhysics->removeObject (node->getName());
|
mPhysics->removeObject (node->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mRendering.removeCell(active);
|
mRendering.removeCell(*iter);
|
||||||
//mPhysics->removeObject("Unnamed_43");
|
//mPhysics->removeObject("Unnamed_43");
|
||||||
mWorld->getLocalScripts().clearCell (active);
|
|
||||||
mEnvironment.mMechanicsManager->dropActors (active);
|
|
||||||
mEnvironment.mSoundManager->stopSound (active);
|
|
||||||
mActiveCells.erase(active);
|
|
||||||
|
|
||||||
|
mWorld->getLocalScripts().clearCell (*iter);
|
||||||
|
mEnvironment.mMechanicsManager->dropActors (*iter);
|
||||||
|
mEnvironment.mSoundManager->stopSound (*iter);
|
||||||
|
mActiveCells.erase(*iter);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::loadCell (Ptr::CellStore *cell)
|
void Scene::loadCell (Ptr::CellStore *cell)
|
||||||
|
@ -233,6 +235,9 @@ namespace MWWorld
|
||||||
// adjust player
|
// adjust player
|
||||||
mCurrentCell = cell;
|
mCurrentCell = cell;
|
||||||
playerCellChange (cell, position);
|
playerCellChange (cell, position);
|
||||||
|
|
||||||
|
// adjust fog
|
||||||
|
mRendering.configureFog(*cell);
|
||||||
|
|
||||||
// Sky system
|
// Sky system
|
||||||
mWorld->adjustSky();
|
mWorld->adjustSky();
|
||||||
|
|
803
apps/openmw/mwworld/weather.cpp
Normal file
803
apps/openmw/mwworld/weather.cpp
Normal file
|
@ -0,0 +1,803 @@
|
||||||
|
#include "weather.hpp"
|
||||||
|
#include "world.hpp"
|
||||||
|
#include "player.hpp"
|
||||||
|
|
||||||
|
#include "../mwrender/renderingmanager.hpp"
|
||||||
|
#include "../mwsound/soundmanager.hpp"
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
using namespace Ogre;
|
||||||
|
using namespace MWWorld;
|
||||||
|
using namespace MWSound;
|
||||||
|
|
||||||
|
#define lerp(x, y) (x * (1-factor) + y * factor)
|
||||||
|
|
||||||
|
const std::string WeatherGlobals::mThunderSoundID0 = "Thunder0";
|
||||||
|
const std::string WeatherGlobals::mThunderSoundID1 = "Thunder1";
|
||||||
|
const std::string WeatherGlobals::mThunderSoundID2 = "Thunder2";
|
||||||
|
const std::string WeatherGlobals::mThunderSoundID3 = "Thunder3";
|
||||||
|
|
||||||
|
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) :
|
||||||
|
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
|
||||||
|
mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0)
|
||||||
|
{
|
||||||
|
mRendering = rendering;
|
||||||
|
mEnvironment = env;
|
||||||
|
|
||||||
|
#define clr(r,g,b) ColourValue(r/255.f, g/255.f, b/255.f)
|
||||||
|
|
||||||
|
/// \todo read these from Morrowind.ini
|
||||||
|
Weather clear;
|
||||||
|
clear.mCloudTexture = "tx_sky_clear.dds";
|
||||||
|
clear.mCloudsMaximumPercent = 1.0;
|
||||||
|
clear.mTransitionDelta = 0.015;
|
||||||
|
clear.mSkySunriseColor = clr(118, 141, 164);
|
||||||
|
clear.mSkyDayColor = clr(95, 135, 203);
|
||||||
|
clear.mSkySunsetColor = clr(56, 89, 129);
|
||||||
|
clear.mSkyNightColor = clr(9, 10, 11);
|
||||||
|
clear.mFogSunriseColor = clr(255, 189, 157);
|
||||||
|
clear.mFogDayColor = clr(206, 227, 255);
|
||||||
|
clear.mFogSunsetColor = clr(255, 189, 157);
|
||||||
|
clear.mFogNightColor = clr(9, 10, 11);
|
||||||
|
clear.mAmbientSunriseColor = clr(47, 66, 96);
|
||||||
|
clear.mAmbientDayColor = clr(137, 140, 160);
|
||||||
|
clear.mAmbientSunsetColor = clr(68, 75, 96);
|
||||||
|
clear.mAmbientNightColor = clr(32, 35, 42);
|
||||||
|
clear.mSunSunriseColor = clr(242, 159, 99);
|
||||||
|
clear.mSunDayColor = clr(255, 252, 238);
|
||||||
|
clear.mSunSunsetColor = clr(255, 115, 79);
|
||||||
|
clear.mSunNightColor = clr(59, 97, 176);
|
||||||
|
clear.mSunDiscSunsetColor = clr(255, 189, 157);
|
||||||
|
clear.mLandFogDayDepth = 0.69;
|
||||||
|
clear.mLandFogNightDepth = 0.69;
|
||||||
|
clear.mWindSpeed = 0.1;
|
||||||
|
clear.mCloudSpeed = 1.25;
|
||||||
|
clear.mGlareView = 1.0;
|
||||||
|
mWeatherSettings["clear"] = clear;
|
||||||
|
|
||||||
|
Weather cloudy;
|
||||||
|
cloudy.mCloudTexture = "tx_sky_cloudy.dds";
|
||||||
|
cloudy.mCloudsMaximumPercent = 1.0;
|
||||||
|
cloudy.mTransitionDelta = 0.015;
|
||||||
|
cloudy.mSkySunriseColor = clr(126, 158, 173);
|
||||||
|
cloudy.mSkyDayColor = clr(117, 160, 215);
|
||||||
|
cloudy.mSkySunsetColor = clr(111, 114, 159);
|
||||||
|
cloudy.mSkyNightColor = clr(9, 10, 11);
|
||||||
|
cloudy.mFogSunriseColor = clr(255, 207, 149);
|
||||||
|
cloudy.mFogDayColor = clr(245, 235, 224);
|
||||||
|
cloudy.mFogSunsetColor = clr(255, 155, 106);
|
||||||
|
cloudy.mFogNightColor = clr(9, 10, 11);
|
||||||
|
cloudy.mAmbientSunriseColor = clr(66, 74, 87);
|
||||||
|
cloudy.mAmbientDayColor = clr(137, 145, 160);
|
||||||
|
cloudy.mAmbientSunsetColor = clr(71, 80, 92);
|
||||||
|
cloudy.mAmbientNightColor = clr(32, 39, 54);
|
||||||
|
cloudy.mSunSunriseColor = clr(241, 177, 99);
|
||||||
|
cloudy.mSunDayColor = clr(255, 236, 221);
|
||||||
|
cloudy.mSunSunsetColor = clr(255, 89, 00);
|
||||||
|
cloudy.mSunNightColor = clr(77, 91, 124);
|
||||||
|
cloudy.mSunDiscSunsetColor = clr(255, 202, 179);
|
||||||
|
cloudy.mLandFogDayDepth = 0.72;
|
||||||
|
cloudy.mLandFogNightDepth = 0.72;
|
||||||
|
cloudy.mWindSpeed = 0.2;
|
||||||
|
cloudy.mCloudSpeed = 2;
|
||||||
|
cloudy.mGlareView = 1.0;
|
||||||
|
mWeatherSettings["cloudy"] = cloudy;
|
||||||
|
|
||||||
|
Weather foggy;
|
||||||
|
foggy.mCloudTexture = "tx_sky_foggy.dds";
|
||||||
|
foggy.mCloudsMaximumPercent = 1.0;
|
||||||
|
foggy.mTransitionDelta = 0.015;
|
||||||
|
foggy.mSkySunriseColor = clr(197, 190, 180);
|
||||||
|
foggy.mSkyDayColor = clr(184, 211, 228);
|
||||||
|
foggy.mSkySunsetColor = clr(142, 159, 176);
|
||||||
|
foggy.mSkyNightColor = clr(18, 23, 28);
|
||||||
|
foggy.mFogSunriseColor = clr(173, 164, 148);
|
||||||
|
foggy.mFogDayColor = clr(150, 187, 209);
|
||||||
|
foggy.mFogSunsetColor = clr(113, 135, 157);
|
||||||
|
foggy.mFogNightColor = clr(19, 24, 29);
|
||||||
|
foggy.mAmbientSunriseColor = clr(48, 43, 37);
|
||||||
|
foggy.mAmbientDayColor = clr(92, 109, 120);
|
||||||
|
foggy.mAmbientSunsetColor = clr(28, 33, 39);
|
||||||
|
foggy.mAmbientNightColor = clr(28, 33, 39);
|
||||||
|
foggy.mSunSunriseColor = clr(177, 162, 137);
|
||||||
|
foggy.mSunDayColor = clr(111, 131, 151);
|
||||||
|
foggy.mSunSunsetColor = clr(125, 157, 189);
|
||||||
|
foggy.mSunNightColor = clr(81, 100, 119);
|
||||||
|
foggy.mSunDiscSunsetColor = clr(223, 223, 223);
|
||||||
|
foggy.mLandFogDayDepth = 1.0;
|
||||||
|
foggy.mLandFogNightDepth = 1.9;
|
||||||
|
foggy.mWindSpeed = 0;
|
||||||
|
foggy.mCloudSpeed = 1.25;
|
||||||
|
foggy.mGlareView = 0.25;
|
||||||
|
mWeatherSettings["foggy"] = foggy;
|
||||||
|
|
||||||
|
Weather thunderstorm;
|
||||||
|
thunderstorm.mCloudTexture = "tx_sky_thunder.dds";
|
||||||
|
thunderstorm.mCloudsMaximumPercent = 0.66;
|
||||||
|
thunderstorm.mTransitionDelta = 0.03;
|
||||||
|
thunderstorm.mSkySunriseColor = clr(35, 36, 39);
|
||||||
|
thunderstorm.mSkyDayColor = clr(97, 104, 115);
|
||||||
|
thunderstorm.mSkySunsetColor = clr(35, 36, 39);
|
||||||
|
thunderstorm.mSkyNightColor = clr(19, 20, 22);
|
||||||
|
thunderstorm.mFogSunriseColor = clr(70, 74, 85);
|
||||||
|
thunderstorm.mFogDayColor = clr(97, 104, 115);
|
||||||
|
thunderstorm.mFogSunsetColor = clr(70, 74, 85);
|
||||||
|
thunderstorm.mFogNightColor = clr(19, 20, 22);
|
||||||
|
thunderstorm.mAmbientSunriseColor = clr(54, 54, 54);
|
||||||
|
thunderstorm.mAmbientDayColor = clr(90, 90, 90);
|
||||||
|
thunderstorm.mAmbientSunsetColor = clr(54, 54, 54);
|
||||||
|
thunderstorm.mAmbientNightColor = clr(49, 51, 54);
|
||||||
|
thunderstorm.mSunSunriseColor = clr(91, 99, 122);
|
||||||
|
thunderstorm.mSunDayColor = clr(138, 144, 155);
|
||||||
|
thunderstorm.mSunSunsetColor = clr(96, 101, 117);
|
||||||
|
thunderstorm.mSunNightColor = clr(55, 76, 110);
|
||||||
|
thunderstorm.mSunDiscSunsetColor = clr(128, 128, 128);
|
||||||
|
thunderstorm.mLandFogDayDepth = 1;
|
||||||
|
thunderstorm.mLandFogNightDepth = 1.15;
|
||||||
|
thunderstorm.mWindSpeed = 0.5;
|
||||||
|
thunderstorm.mCloudSpeed = 3;
|
||||||
|
thunderstorm.mGlareView = 0;
|
||||||
|
thunderstorm.mRainLoopSoundID = "rain heavy";
|
||||||
|
mWeatherSettings["thunderstorm"] = thunderstorm;
|
||||||
|
|
||||||
|
Weather rain;
|
||||||
|
rain.mCloudTexture = "tx_sky_rainy.dds";
|
||||||
|
rain.mCloudsMaximumPercent = 0.66;
|
||||||
|
rain.mTransitionDelta = 0.015;
|
||||||
|
rain.mSkySunriseColor = clr(71, 74, 75);
|
||||||
|
rain.mSkyDayColor = clr(116, 120, 122);
|
||||||
|
rain.mSkySunsetColor = clr(73, 73, 73);
|
||||||
|
rain.mSkyNightColor = clr(24, 25, 26);
|
||||||
|
rain.mFogSunriseColor = clr(71, 74, 75);
|
||||||
|
rain.mFogDayColor = clr(116, 120, 122);
|
||||||
|
rain.mFogSunsetColor = clr(73, 73, 73);
|
||||||
|
rain.mFogNightColor = clr(24, 25, 26);
|
||||||
|
rain.mAmbientSunriseColor = clr(97, 90, 88);
|
||||||
|
rain.mAmbientDayColor = clr(105, 110, 113);
|
||||||
|
rain.mAmbientSunsetColor = clr(88, 97, 97);
|
||||||
|
rain.mAmbientNightColor = clr(50, 55, 67);
|
||||||
|
rain.mSunSunriseColor = clr(131, 122, 120);
|
||||||
|
rain.mSunDayColor = clr(149, 157, 170);
|
||||||
|
rain.mSunSunsetColor = clr(120, 126, 131);
|
||||||
|
rain.mSunNightColor = clr(50, 62, 101);
|
||||||
|
rain.mSunDiscSunsetColor = clr(128, 128, 128);
|
||||||
|
rain.mLandFogDayDepth = 0.8;
|
||||||
|
rain.mLandFogNightDepth = 0.8;
|
||||||
|
rain.mWindSpeed = 0.3;
|
||||||
|
rain.mCloudSpeed = 2;
|
||||||
|
rain.mGlareView = 0;
|
||||||
|
rain.mRainLoopSoundID = "rain";
|
||||||
|
mWeatherSettings["rain"] = rain;
|
||||||
|
|
||||||
|
Weather overcast;
|
||||||
|
overcast.mCloudTexture = "tx_sky_overcast.dds";
|
||||||
|
overcast.mCloudsMaximumPercent = 1.0;
|
||||||
|
overcast.mTransitionDelta = 0.015;
|
||||||
|
overcast.mSkySunriseColor = clr(91, 99, 106);
|
||||||
|
overcast.mSkyDayColor = clr(143, 146, 149);
|
||||||
|
overcast.mSkySunsetColor = clr(108, 115, 121);
|
||||||
|
overcast.mSkyNightColor = clr(19, 22, 25);
|
||||||
|
overcast.mFogSunriseColor = clr(91, 99, 106);
|
||||||
|
overcast.mFogDayColor = clr(143, 146, 149);
|
||||||
|
overcast.mFogSunsetColor = clr(108, 115, 121);
|
||||||
|
overcast.mFogNightColor = clr(19, 22, 25);
|
||||||
|
overcast.mAmbientSunriseColor = clr(84, 88, 92);
|
||||||
|
overcast.mAmbientDayColor = clr(93, 96, 105);
|
||||||
|
overcast.mAmbientSunsetColor = clr(83, 77, 75);
|
||||||
|
overcast.mAmbientNightColor = clr(57, 60, 66);
|
||||||
|
overcast.mSunSunriseColor = clr(87, 125, 163);
|
||||||
|
overcast.mSunDayColor = clr(163, 169, 183);
|
||||||
|
overcast.mSunSunsetColor = clr(85, 103, 157);
|
||||||
|
overcast.mSunNightColor = clr(32, 54, 100);
|
||||||
|
overcast.mSunDiscSunsetColor = clr(128, 128, 128);
|
||||||
|
overcast.mLandFogDayDepth = 0.7;
|
||||||
|
overcast.mLandFogNightDepth = 0.7;
|
||||||
|
overcast.mWindSpeed = 0.2;
|
||||||
|
overcast.mCloudSpeed = 1.5;
|
||||||
|
overcast.mGlareView = 0;
|
||||||
|
mWeatherSettings["overcast"] = overcast;
|
||||||
|
|
||||||
|
Weather ashstorm;
|
||||||
|
ashstorm.mCloudTexture = "tx_sky_ashstorm.dds";
|
||||||
|
ashstorm.mCloudsMaximumPercent = 1.0;
|
||||||
|
ashstorm.mTransitionDelta = 0.035;
|
||||||
|
ashstorm.mSkySunriseColor = clr(91, 56, 51);
|
||||||
|
ashstorm.mSkyDayColor = clr(124, 73, 58);
|
||||||
|
ashstorm.mSkySunsetColor = clr(106, 55, 40);
|
||||||
|
ashstorm.mSkyNightColor = clr(20, 21, 22);
|
||||||
|
ashstorm.mFogSunriseColor = clr(91, 56, 51);
|
||||||
|
ashstorm.mFogDayColor = clr(124, 73, 58);
|
||||||
|
ashstorm.mFogSunsetColor = clr(106, 55, 40);
|
||||||
|
ashstorm.mFogNightColor = clr(20, 21, 22);
|
||||||
|
ashstorm.mAmbientSunriseColor = clr(52, 42, 37);
|
||||||
|
ashstorm.mAmbientDayColor = clr(75, 49, 41);
|
||||||
|
ashstorm.mAmbientSunsetColor = clr(48, 39, 35);
|
||||||
|
ashstorm.mAmbientNightColor = clr(36, 42, 49);
|
||||||
|
ashstorm.mSunSunriseColor = clr(184, 91, 71);
|
||||||
|
ashstorm.mSunDayColor = clr(228, 139, 114);
|
||||||
|
ashstorm.mSunSunsetColor = clr(185, 86, 57);
|
||||||
|
ashstorm.mSunNightColor = clr(54, 66, 74);
|
||||||
|
ashstorm.mSunDiscSunsetColor = clr(128, 128, 128);
|
||||||
|
ashstorm.mLandFogDayDepth = 1.1;
|
||||||
|
ashstorm.mLandFogNightDepth = 1.2;
|
||||||
|
ashstorm.mWindSpeed = 0.8;
|
||||||
|
ashstorm.mCloudSpeed = 7;
|
||||||
|
ashstorm.mGlareView = 0;
|
||||||
|
ashstorm.mAmbientLoopSoundID = "ashstorm";
|
||||||
|
mWeatherSettings["ashstorm"] = ashstorm;
|
||||||
|
|
||||||
|
Weather blight;
|
||||||
|
blight.mCloudTexture = "tx_sky_blight.dds";
|
||||||
|
blight.mCloudsMaximumPercent = 1.0;
|
||||||
|
blight.mTransitionDelta = 0.04;
|
||||||
|
blight.mSkySunriseColor = clr(90, 35, 35);
|
||||||
|
blight.mSkyDayColor = clr(90, 35, 35);
|
||||||
|
blight.mSkySunsetColor = clr(92, 33, 33);
|
||||||
|
blight.mSkyNightColor = clr(44, 14, 14);
|
||||||
|
blight.mFogSunriseColor = clr(90, 35, 35);
|
||||||
|
blight.mFogDayColor = clr(128, 19, 19);
|
||||||
|
blight.mFogSunsetColor = clr(92, 33, 33);
|
||||||
|
blight.mFogNightColor = clr(44, 14, 14);
|
||||||
|
blight.mAmbientSunriseColor = clr(61, 40, 40);
|
||||||
|
blight.mAmbientDayColor = clr(79, 54, 54);
|
||||||
|
blight.mAmbientSunsetColor = clr(61, 40, 40);
|
||||||
|
blight.mAmbientNightColor = clr(56, 58, 62);
|
||||||
|
blight.mSunSunriseColor = clr(180, 78, 78);
|
||||||
|
blight.mSunDayColor = clr(224, 84, 84);
|
||||||
|
blight.mSunSunsetColor = clr(180, 78, 78);
|
||||||
|
blight.mSunNightColor = clr(61, 91, 143);
|
||||||
|
blight.mSunDiscSunsetColor = clr(128, 128, 128);
|
||||||
|
blight.mLandFogDayDepth = 1.1;
|
||||||
|
blight.mLandFogNightDepth = 1.2;
|
||||||
|
blight.mWindSpeed = 0.9;
|
||||||
|
blight.mCloudSpeed = 9;
|
||||||
|
blight.mGlareView = 0;
|
||||||
|
blight.mAmbientLoopSoundID = "blight";
|
||||||
|
mWeatherSettings["blight"] = blight;
|
||||||
|
|
||||||
|
Weather snow;
|
||||||
|
snow.mCloudTexture = "tx_bm_sky_snow.dds";
|
||||||
|
snow.mCloudsMaximumPercent = 1.0;
|
||||||
|
snow.mTransitionDelta = 0.014;
|
||||||
|
snow.mSkySunriseColor = clr(196, 91, 91);
|
||||||
|
snow.mSkyDayColor = clr(153, 158, 166);
|
||||||
|
snow.mSkySunsetColor = clr(96, 115, 134);
|
||||||
|
snow.mSkyNightColor = clr(31, 35, 39);
|
||||||
|
snow.mFogSunriseColor = clr(106, 91, 91);
|
||||||
|
snow.mFogDayColor = clr(153, 158, 166);
|
||||||
|
snow.mFogSunsetColor = clr(96, 115, 134);
|
||||||
|
snow.mFogNightColor = clr(31, 35, 39);
|
||||||
|
snow.mAmbientSunriseColor = clr(92, 84, 84);
|
||||||
|
snow.mAmbientDayColor = clr(93, 96, 105);
|
||||||
|
snow.mAmbientSunsetColor = clr(70, 79, 87);
|
||||||
|
snow.mAmbientNightColor = clr(49, 58, 68);
|
||||||
|
snow.mSunSunriseColor = clr(141, 109, 109);
|
||||||
|
snow.mSunDayColor = clr(163, 169, 183);
|
||||||
|
snow.mSunSunsetColor = clr(101, 121, 141);
|
||||||
|
snow.mSunNightColor = clr(55, 66, 77);
|
||||||
|
snow.mSunDiscSunsetColor = clr(128, 128, 128);
|
||||||
|
snow.mLandFogDayDepth = 1.0;
|
||||||
|
snow.mLandFogNightDepth = 1.2;
|
||||||
|
snow.mWindSpeed = 0;
|
||||||
|
snow.mCloudSpeed = 1.5;
|
||||||
|
snow.mGlareView = 0;
|
||||||
|
mWeatherSettings["snow"] = snow;
|
||||||
|
|
||||||
|
Weather blizzard;
|
||||||
|
blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds";
|
||||||
|
blizzard.mCloudsMaximumPercent = 1.0;
|
||||||
|
blizzard.mTransitionDelta = 0.030;
|
||||||
|
blizzard.mSkySunriseColor = clr(91, 99, 106);
|
||||||
|
blizzard.mSkyDayColor = clr(121, 133, 145);
|
||||||
|
blizzard.mSkySunsetColor = clr(108, 115, 121);
|
||||||
|
blizzard.mSkyNightColor = clr(27, 29, 31);
|
||||||
|
blizzard.mFogSunriseColor = clr(91, 99, 106);
|
||||||
|
blizzard.mFogDayColor = clr(121, 133, 145);
|
||||||
|
blizzard.mFogSunsetColor = clr(108, 115, 121);
|
||||||
|
blizzard.mFogNightColor = clr(21, 24, 28);
|
||||||
|
blizzard.mAmbientSunriseColor = clr(84, 88, 92);
|
||||||
|
blizzard.mAmbientDayColor = clr(93, 96, 105);
|
||||||
|
blizzard.mAmbientSunsetColor = clr(83, 77, 75);
|
||||||
|
blizzard.mAmbientNightColor = clr(53, 62, 70);
|
||||||
|
blizzard.mSunSunriseColor = clr(114, 128, 146);
|
||||||
|
blizzard.mSunDayColor = clr(163, 169, 183);
|
||||||
|
blizzard.mSunSunsetColor = clr(106, 114, 136);
|
||||||
|
blizzard.mSunNightColor = clr(57, 66, 74);
|
||||||
|
blizzard.mSunDiscSunsetColor = clr(128, 128, 128);
|
||||||
|
blizzard.mLandFogDayDepth = 2.8;
|
||||||
|
blizzard.mLandFogNightDepth = 3.0;
|
||||||
|
blizzard.mWindSpeed = 0.9;
|
||||||
|
blizzard.mCloudSpeed = 7.5;
|
||||||
|
blizzard.mGlareView = 0;
|
||||||
|
blizzard.mAmbientLoopSoundID = "BM Blizzard";
|
||||||
|
mWeatherSettings["blizzard"] = blizzard;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeatherManager::setWeather(const String& weather, bool instant)
|
||||||
|
{
|
||||||
|
if (instant || mFirstUpdate)
|
||||||
|
{
|
||||||
|
mNextWeather = "";
|
||||||
|
mCurrentWeather = weather;
|
||||||
|
mFirstUpdate = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mNextWeather != "")
|
||||||
|
{
|
||||||
|
// transition more than 50% finished?
|
||||||
|
if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60) <= 0.5)
|
||||||
|
mCurrentWeather = mNextWeather;
|
||||||
|
}
|
||||||
|
|
||||||
|
mNextWeather = weather;
|
||||||
|
mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WeatherResult WeatherManager::getResult(const String& weather)
|
||||||
|
{
|
||||||
|
const Weather& current = mWeatherSettings[weather];
|
||||||
|
WeatherResult result;
|
||||||
|
|
||||||
|
result.mCloudTexture = current.mCloudTexture;
|
||||||
|
result.mCloudBlendFactor = 0;
|
||||||
|
result.mCloudOpacity = current.mCloudsMaximumPercent;
|
||||||
|
result.mWindSpeed = current.mWindSpeed;
|
||||||
|
result.mCloudSpeed = current.mCloudSpeed;
|
||||||
|
result.mGlareView = current.mGlareView;
|
||||||
|
result.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
|
||||||
|
result.mSunColor = current.mSunDiscSunsetColor;
|
||||||
|
|
||||||
|
const float fade_duration = current.mTransitionDelta * 24.f;
|
||||||
|
|
||||||
|
result.mNight = (mHour < 6.f+fade_duration || mHour > 20.f-fade_duration);
|
||||||
|
|
||||||
|
result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
|
||||||
|
|
||||||
|
// night
|
||||||
|
if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
|
||||||
|
|| mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration))
|
||||||
|
{
|
||||||
|
result.mFogColor = current.mFogNightColor;
|
||||||
|
result.mAmbientColor = current.mAmbientNightColor;
|
||||||
|
result.mSunColor = current.mSunNightColor;
|
||||||
|
result.mSkyColor = current.mSkyNightColor;
|
||||||
|
result.mNightFade = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sunrise
|
||||||
|
else if (mHour >= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) && mHour <= WeatherGlobals::mSunriseTime)
|
||||||
|
{
|
||||||
|
if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration))
|
||||||
|
{
|
||||||
|
// fade in
|
||||||
|
float advance = (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)-mHour;
|
||||||
|
float factor = (advance / fade_duration);
|
||||||
|
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor);
|
||||||
|
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor);
|
||||||
|
result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor);
|
||||||
|
result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor);
|
||||||
|
result.mNightFade = factor;
|
||||||
|
}
|
||||||
|
else if (mHour >= (WeatherGlobals::mSunriseTime-fade_duration))
|
||||||
|
{
|
||||||
|
// fade out
|
||||||
|
float advance = mHour-(WeatherGlobals::mSunriseTime-fade_duration);
|
||||||
|
float factor = advance / fade_duration;
|
||||||
|
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor);
|
||||||
|
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor);
|
||||||
|
result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor);
|
||||||
|
result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.mFogColor = current.mFogSunriseColor;
|
||||||
|
result.mAmbientColor = current.mAmbientSunriseColor;
|
||||||
|
result.mSunColor = current.mSunSunriseColor;
|
||||||
|
result.mSkyColor = current.mSkySunriseColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// day
|
||||||
|
else if (mHour >= (WeatherGlobals::mSunriseTime) && mHour <= (WeatherGlobals::mSunsetTime))
|
||||||
|
{
|
||||||
|
result.mFogColor = current.mFogDayColor;
|
||||||
|
result.mAmbientColor = current.mAmbientDayColor;
|
||||||
|
result.mSunColor = current.mSunDayColor;
|
||||||
|
result.mSkyColor = current.mSkyDayColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sunset
|
||||||
|
else if (mHour >= (WeatherGlobals::mSunsetTime) && mHour <= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration))
|
||||||
|
{
|
||||||
|
if (mHour <= (WeatherGlobals::mSunsetTime+fade_duration))
|
||||||
|
{
|
||||||
|
// fade in
|
||||||
|
float advance = (WeatherGlobals::mSunsetTime+fade_duration)-mHour;
|
||||||
|
float factor = (advance / fade_duration);
|
||||||
|
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor);
|
||||||
|
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor);
|
||||||
|
result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor);
|
||||||
|
result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor);
|
||||||
|
}
|
||||||
|
else if (mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration))
|
||||||
|
{
|
||||||
|
// fade out
|
||||||
|
float advance = mHour-(WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration);
|
||||||
|
float factor = advance / fade_duration;
|
||||||
|
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor);
|
||||||
|
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor);
|
||||||
|
result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor);
|
||||||
|
result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor);
|
||||||
|
result.mNightFade = factor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.mFogColor = current.mFogSunsetColor;
|
||||||
|
result.mAmbientColor = current.mAmbientSunsetColor;
|
||||||
|
result.mSunColor = current.mSunSunsetColor;
|
||||||
|
result.mSkyColor = current.mSkySunsetColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WeatherResult WeatherManager::transition(float factor)
|
||||||
|
{
|
||||||
|
const WeatherResult& current = getResult(mCurrentWeather);
|
||||||
|
const WeatherResult& other = getResult(mNextWeather);
|
||||||
|
WeatherResult result;
|
||||||
|
|
||||||
|
result.mCloudTexture = current.mCloudTexture;
|
||||||
|
result.mNextCloudTexture = other.mCloudTexture;
|
||||||
|
result.mCloudBlendFactor = factor;
|
||||||
|
|
||||||
|
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
|
||||||
|
result.mFogColor = lerp(current.mFogColor, other.mFogColor);
|
||||||
|
result.mSunColor = lerp(current.mSunColor, other.mSunColor);
|
||||||
|
result.mSkyColor = lerp(current.mSkyColor, other.mSkyColor);
|
||||||
|
|
||||||
|
result.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor);
|
||||||
|
result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor);
|
||||||
|
result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth);
|
||||||
|
result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed);
|
||||||
|
result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed);
|
||||||
|
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
|
||||||
|
result.mGlareView = lerp(current.mGlareView, other.mGlareView);
|
||||||
|
|
||||||
|
result.mNight = current.mNight;
|
||||||
|
|
||||||
|
// sound change behaviour:
|
||||||
|
// if 'other' has a new sound, switch to it after 1/2 of the transition length
|
||||||
|
if (other.mAmbientLoopSoundID != "")
|
||||||
|
result.mAmbientLoopSoundID = factor>0.5 ? other.mAmbientLoopSoundID : current.mAmbientLoopSoundID;
|
||||||
|
// if 'current' has a sound and 'other' does not have a sound, turn off the sound immediately
|
||||||
|
else if (current.mAmbientLoopSoundID != "")
|
||||||
|
result.mAmbientLoopSoundID = "";
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeatherManager::update(float duration)
|
||||||
|
{
|
||||||
|
mWeatherUpdateTime -= duration;
|
||||||
|
if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior())
|
||||||
|
{
|
||||||
|
std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region;
|
||||||
|
boost::algorithm::to_lower(regionstr);
|
||||||
|
|
||||||
|
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
|
||||||
|
{
|
||||||
|
mCurrentRegion = regionstr;
|
||||||
|
mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f;
|
||||||
|
|
||||||
|
std::string weather;
|
||||||
|
|
||||||
|
if (mRegionOverrides.find(regionstr) != mRegionOverrides.end())
|
||||||
|
weather = mRegionOverrides[regionstr];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// get weather probabilities for the current region
|
||||||
|
const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr);
|
||||||
|
|
||||||
|
float clear = region->data.clear/255.f;
|
||||||
|
float cloudy = region->data.cloudy/255.f;
|
||||||
|
float foggy = region->data.foggy/255.f;
|
||||||
|
float overcast = region->data.overcast/255.f;
|
||||||
|
float rain = region->data.rain/255.f;
|
||||||
|
float thunder = region->data.thunder/255.f;
|
||||||
|
float ash = region->data.ash/255.f;
|
||||||
|
float blight = region->data.blight/255.f;
|
||||||
|
float snow = region->data.a/255.f;
|
||||||
|
float blizzard = region->data.b/255.f;
|
||||||
|
|
||||||
|
// re-scale to 100 percent
|
||||||
|
const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
float random = ((rand()%100)/100.f) * total;
|
||||||
|
|
||||||
|
if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||||
|
weather = "blizzard";
|
||||||
|
else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||||
|
weather = "snow";
|
||||||
|
else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||||
|
weather = "blight";
|
||||||
|
else if (random >= thunder+rain+overcast+foggy+cloudy+clear)
|
||||||
|
weather = "ashstorm";
|
||||||
|
else if (random >= rain+overcast+foggy+cloudy+clear)
|
||||||
|
weather = "thunderstorm";
|
||||||
|
else if (random >= overcast+foggy+cloudy+clear)
|
||||||
|
weather = "rain";
|
||||||
|
else if (random >= foggy+cloudy+clear)
|
||||||
|
weather = "overcast";
|
||||||
|
else if (random >= cloudy+clear)
|
||||||
|
weather = "foggy";
|
||||||
|
else if (random >= clear)
|
||||||
|
weather = "cloudy";
|
||||||
|
else
|
||||||
|
weather = "clear";
|
||||||
|
}
|
||||||
|
|
||||||
|
setWeather(weather, false);
|
||||||
|
/*
|
||||||
|
std::cout << "roll result: " << random << std::endl;
|
||||||
|
|
||||||
|
std::cout << regionstr << " weather probabilities: " << clear << " " << cloudy << " " << foggy << " "
|
||||||
|
<< overcast << " " << rain << " " << thunder << " " << ash << " " << blight << " " << snow << " "
|
||||||
|
<< blizzard << std::endl;
|
||||||
|
|
||||||
|
std::cout << "New weather : " << weather << std::endl;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
WeatherResult result;
|
||||||
|
|
||||||
|
if (mNextWeather != "")
|
||||||
|
{
|
||||||
|
mRemainingTransitionTime -= duration;
|
||||||
|
if (mRemainingTransitionTime < 0)
|
||||||
|
{
|
||||||
|
mCurrentWeather = mNextWeather;
|
||||||
|
mNextWeather = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNextWeather != "")
|
||||||
|
result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60)));
|
||||||
|
else
|
||||||
|
result = getResult(mCurrentWeather);
|
||||||
|
|
||||||
|
mRendering->configureFog(result.mFogDepth, result.mFogColor);
|
||||||
|
|
||||||
|
// disable sun during night
|
||||||
|
if (mHour >= WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration
|
||||||
|
|| mHour <= WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
|
||||||
|
mRendering->getSkyManager()->sunDisable();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// during day, calculate sun angle
|
||||||
|
float height = 1-std::abs(((mHour-13)/7.f));
|
||||||
|
int facing = mHour > 13.f ? 1 : -1;
|
||||||
|
Vector3 final(
|
||||||
|
(1-height)*facing,
|
||||||
|
(1-height)*facing,
|
||||||
|
height);
|
||||||
|
mRendering->setSunDirection(final);
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->sunEnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// moon calculations
|
||||||
|
float night;
|
||||||
|
if (mHour >= 14)
|
||||||
|
night = mHour-14;
|
||||||
|
else if (mHour <= 10)
|
||||||
|
night = mHour+10;
|
||||||
|
else
|
||||||
|
night = 0;
|
||||||
|
|
||||||
|
night /= 20.f;
|
||||||
|
|
||||||
|
if (night != 0)
|
||||||
|
{
|
||||||
|
float moonHeight = 1-std::abs((night-0.5)*2);
|
||||||
|
int facing = (mHour > 0.f && mHour<12.f) ? 1 : -1;
|
||||||
|
Vector3 masser(
|
||||||
|
(1-moonHeight)*facing,
|
||||||
|
(1-moonHeight)*facing,
|
||||||
|
moonHeight);
|
||||||
|
|
||||||
|
Vector3 secunda(
|
||||||
|
(1-moonHeight)*facing*0.8,
|
||||||
|
(1-moonHeight)*facing*1.25,
|
||||||
|
moonHeight);
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->setMasserDirection(masser);
|
||||||
|
mRendering->getSkyManager()->setSecundaDirection(secunda);
|
||||||
|
mRendering->getSkyManager()->masserEnable();
|
||||||
|
mRendering->getSkyManager()->secundaEnable();
|
||||||
|
|
||||||
|
float hour_fade;
|
||||||
|
if (mHour >= 7.f && mHour <= 14.f)
|
||||||
|
hour_fade = 1-(mHour-7)/3.f;
|
||||||
|
else if (mHour >= 14 && mHour <= 15.f)
|
||||||
|
hour_fade = mHour-14;
|
||||||
|
else
|
||||||
|
hour_fade = 1;
|
||||||
|
|
||||||
|
float secunda_angle_fade;
|
||||||
|
float masser_angle_fade;
|
||||||
|
float angle = moonHeight*90.f;
|
||||||
|
|
||||||
|
if (angle >= 30 && angle <= 50)
|
||||||
|
secunda_angle_fade = (angle-30)/20.f;
|
||||||
|
else if (angle <30)
|
||||||
|
secunda_angle_fade = 0.f;
|
||||||
|
else
|
||||||
|
secunda_angle_fade = 1.f;
|
||||||
|
|
||||||
|
if (angle >= 40 && angle <= 50)
|
||||||
|
masser_angle_fade = (angle-40)/10.f;
|
||||||
|
else if (angle <40)
|
||||||
|
masser_angle_fade = 0.f;
|
||||||
|
else
|
||||||
|
masser_angle_fade = 1.f;
|
||||||
|
|
||||||
|
masser_angle_fade *= hour_fade;
|
||||||
|
secunda_angle_fade *= hour_fade;
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->setMasserFade(masser_angle_fade);
|
||||||
|
mRendering->getSkyManager()->setSecundaFade(secunda_angle_fade);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mRendering->getSkyManager()->masserDisable();
|
||||||
|
mRendering->getSkyManager()->secundaDisable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCurrentWeather == "thunderstorm" && mNextWeather == "")
|
||||||
|
{
|
||||||
|
if (mThunderFlash > 0)
|
||||||
|
{
|
||||||
|
// play the sound after a delay
|
||||||
|
mThunderSoundDelay -= duration;
|
||||||
|
if (mThunderSoundDelay <= 0)
|
||||||
|
{
|
||||||
|
// pick a random sound
|
||||||
|
int sound = rand() % 4;
|
||||||
|
std::string soundname;
|
||||||
|
if (sound == 0) soundname = WeatherGlobals::mThunderSoundID0;
|
||||||
|
else if (sound == 1) soundname = WeatherGlobals::mThunderSoundID1;
|
||||||
|
else if (sound == 2) soundname = WeatherGlobals::mThunderSoundID2;
|
||||||
|
else if (sound == 3) soundname = WeatherGlobals::mThunderSoundID3;
|
||||||
|
mEnvironment->mSoundManager->playSound(soundname, 1.0, 1.0);
|
||||||
|
mThunderSoundDelay = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
mThunderFlash -= duration;
|
||||||
|
if (mThunderFlash > 0)
|
||||||
|
mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srand(time(NULL));
|
||||||
|
mThunderChanceNeeded = rand() % 100;
|
||||||
|
mThunderChance = 0;
|
||||||
|
mRendering->getSkyManager()->setThunder( 0.f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no thunder active
|
||||||
|
mThunderChance += duration*4; // chance increases by 4 percent every second
|
||||||
|
if (mThunderChance >= mThunderChanceNeeded)
|
||||||
|
{
|
||||||
|
mThunderFlash = WeatherGlobals::mThunderThreshold;
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
|
||||||
|
|
||||||
|
mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mRendering->getSkyManager()->setThunder(0.f);
|
||||||
|
|
||||||
|
mRendering->setAmbientColour(result.mAmbientColor);
|
||||||
|
mRendering->sunEnable();
|
||||||
|
mRendering->setSunColour(result.mSunColor);
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->setWeather(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mRendering->sunDisable();
|
||||||
|
mRendering->skyDisable();
|
||||||
|
mRendering->getSkyManager()->setThunder(0.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeatherManager::setHour(const float hour)
|
||||||
|
{
|
||||||
|
// accelerate a bit for testing
|
||||||
|
/*
|
||||||
|
mHour += 0.005;
|
||||||
|
|
||||||
|
if (mHour >= 24.f) mHour = 0.f;
|
||||||
|
|
||||||
|
std::cout << "hour " << mHour << std::endl;
|
||||||
|
*/
|
||||||
|
|
||||||
|
mHour = hour;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeatherManager::setDate(const int day, const int month)
|
||||||
|
{
|
||||||
|
mDay = day;
|
||||||
|
mMonth = month;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int WeatherManager::getWeatherID() const
|
||||||
|
{
|
||||||
|
// Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather
|
||||||
|
|
||||||
|
if (mCurrentWeather == "clear")
|
||||||
|
return 0;
|
||||||
|
else if (mCurrentWeather == "cloudy")
|
||||||
|
return 1;
|
||||||
|
else if (mCurrentWeather == "foggy")
|
||||||
|
return 2;
|
||||||
|
else if (mCurrentWeather == "overcast")
|
||||||
|
return 3;
|
||||||
|
else if (mCurrentWeather == "rain")
|
||||||
|
return 4;
|
||||||
|
else if (mCurrentWeather == "thunder")
|
||||||
|
return 5;
|
||||||
|
else if (mCurrentWeather == "ashstorm")
|
||||||
|
return 6;
|
||||||
|
else if (mCurrentWeather == "blight")
|
||||||
|
return 7;
|
||||||
|
else if (mCurrentWeather == "snow")
|
||||||
|
return 8;
|
||||||
|
else if (mCurrentWeather == "blizzard")
|
||||||
|
return 9;
|
||||||
|
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeatherManager::changeWeather(const std::string& region, const unsigned int id)
|
||||||
|
{
|
||||||
|
std::string weather;
|
||||||
|
if (id==0)
|
||||||
|
weather = "clear";
|
||||||
|
else if (id==1)
|
||||||
|
weather = "cloudy";
|
||||||
|
else if (id==2)
|
||||||
|
weather = "foggy";
|
||||||
|
else if (id==3)
|
||||||
|
weather = "overcast";
|
||||||
|
else if (id==4)
|
||||||
|
weather = "rain";
|
||||||
|
else if (id==5)
|
||||||
|
weather = "thunder";
|
||||||
|
else if (id==6)
|
||||||
|
weather = "ashstorm";
|
||||||
|
else if (id==7)
|
||||||
|
weather = "blight";
|
||||||
|
else if (id==8)
|
||||||
|
weather = "snow";
|
||||||
|
else if (id==9)
|
||||||
|
weather = "blizzard";
|
||||||
|
else
|
||||||
|
weather = "clear";
|
||||||
|
|
||||||
|
mRegionOverrides[region] = weather;
|
||||||
|
}
|
272
apps/openmw/mwworld/weather.hpp
Normal file
272
apps/openmw/mwworld/weather.hpp
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
#ifndef GAME_MWWORLD_WEATHER_H
|
||||||
|
#define GAME_MWWORLD_WEATHER_H
|
||||||
|
|
||||||
|
#include <OgreString.h>
|
||||||
|
#include <OgreColourValue.h>
|
||||||
|
|
||||||
|
namespace MWRender
|
||||||
|
{
|
||||||
|
class RenderingManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
class Environment;
|
||||||
|
|
||||||
|
/// Global weather manager properties (according to INI)
|
||||||
|
struct WeatherGlobals
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
[Weather]
|
||||||
|
EnvReduceColor=255,255,255,255
|
||||||
|
LerpCloseColor=037,046,048,255
|
||||||
|
BumpFadeColor=230,239,255,255
|
||||||
|
AlphaReduce=0.35
|
||||||
|
Minimum Time Between Environmental Sounds=1.0
|
||||||
|
Maximum Time Between Environmental Sounds=5.0
|
||||||
|
Sun Glare Fader Max=0.5
|
||||||
|
Sun Glare Fader Angle Max=30.0
|
||||||
|
Sun Glare Fader Color=222,095,039
|
||||||
|
Timescale Clouds=0
|
||||||
|
Precip Gravity=575
|
||||||
|
Hours Between Weather Changes=20
|
||||||
|
Rain Ripples=1
|
||||||
|
Rain Ripple Radius=1024
|
||||||
|
Rain Ripples Per Drop=1
|
||||||
|
Rain Ripple Scale=0.3
|
||||||
|
Rain Ripple Speed=1.0
|
||||||
|
Fog Depth Change Speed=3
|
||||||
|
Sunrise Time=6
|
||||||
|
Sunset Time=18
|
||||||
|
Sunrise Duration=2
|
||||||
|
Sunset Duration=2
|
||||||
|
Sky Pre-Sunrise Time=.5
|
||||||
|
Sky Post-Sunrise Time=1
|
||||||
|
Sky Pre-Sunset Time=1.5
|
||||||
|
Sky Post-Sunset Time=.5
|
||||||
|
Ambient Pre-Sunrise Time=.5
|
||||||
|
Ambient Post-Sunrise Time=2
|
||||||
|
Ambient Pre-Sunset Time=1
|
||||||
|
Ambient Post-Sunset Time=1.25
|
||||||
|
Fog Pre-Sunrise Time=.5
|
||||||
|
Fog Post-Sunrise Time=1
|
||||||
|
Fog Pre-Sunset Time=2
|
||||||
|
Fog Post-Sunset Time=1
|
||||||
|
Sun Pre-Sunrise Time=0
|
||||||
|
Sun Post-Sunrise Time=0
|
||||||
|
Sun Pre-Sunset Time=1
|
||||||
|
Sun Post-Sunset Time=1.25
|
||||||
|
Stars Post-Sunset Start=1
|
||||||
|
Stars Pre-Sunrise Finish=2
|
||||||
|
Stars Fading Duration=2
|
||||||
|
Snow Ripples=0
|
||||||
|
Snow Ripple Radius=1024
|
||||||
|
Snow Ripples Per Flake=1
|
||||||
|
Snow Ripple Scale=0.3
|
||||||
|
Snow Ripple Speed=1.0
|
||||||
|
Snow Gravity Scale=0.1
|
||||||
|
Snow High Kill=700
|
||||||
|
Snow Low Kill=150
|
||||||
|
|
||||||
|
|
||||||
|
[Moons]
|
||||||
|
Masser Size=94
|
||||||
|
Masser Fade In Start=14
|
||||||
|
Masser Fade In Finish=15
|
||||||
|
Masser Fade Out Start=7
|
||||||
|
Masser Fade Out Finish=10
|
||||||
|
Masser Axis Offset=35
|
||||||
|
Masser Speed=.5
|
||||||
|
Masser Daily Increment=1
|
||||||
|
Masser Fade Start Angle=50
|
||||||
|
Masser Fade End Angle=40
|
||||||
|
Masser Moon Shadow Early Fade Angle=0.5
|
||||||
|
Secunda Size=40
|
||||||
|
Secunda Fade In Start=14
|
||||||
|
Secunda Fade In Finish=15
|
||||||
|
Secunda Fade Out Start=7
|
||||||
|
Secunda Fade Out Finish=10
|
||||||
|
Secunda Axis Offset=50
|
||||||
|
Secunda Speed=.6
|
||||||
|
Secunda Daily Increment=1.2
|
||||||
|
Secunda Fade Start Angle=50
|
||||||
|
Secunda Fade End Angle=30
|
||||||
|
Secunda Moon Shadow Early Fade Angle=0.5
|
||||||
|
Script Color=255,20,20
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const float mSunriseTime = 8;
|
||||||
|
static const float mSunsetTime = 18;
|
||||||
|
static const float mSunriseDuration = 2;
|
||||||
|
static const float mSunsetDuration = 2;
|
||||||
|
|
||||||
|
static const float mWeatherUpdateTime = 20.f;
|
||||||
|
|
||||||
|
// morrowind sets these per-weather, but since they are only used by 'thunderstorm'
|
||||||
|
// weather setting anyway, we can just as well set them globally
|
||||||
|
static const float mThunderFrequency = .4;
|
||||||
|
static const float mThunderThreshold = 0.6;
|
||||||
|
static const float mThunderSoundDelay = 0.25;
|
||||||
|
static const std::string mThunderSoundID0;
|
||||||
|
static const std::string mThunderSoundID1;
|
||||||
|
static const std::string mThunderSoundID2;
|
||||||
|
static const std::string mThunderSoundID3;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Defines the actual weather that results from weather setting (see below), time of day and weather transition
|
||||||
|
struct WeatherResult
|
||||||
|
{
|
||||||
|
Ogre::String mCloudTexture;
|
||||||
|
Ogre::String mNextCloudTexture;
|
||||||
|
float mCloudBlendFactor;
|
||||||
|
|
||||||
|
Ogre::ColourValue mFogColor;
|
||||||
|
|
||||||
|
Ogre::ColourValue mAmbientColor;
|
||||||
|
|
||||||
|
Ogre::ColourValue mSkyColor;
|
||||||
|
|
||||||
|
Ogre::ColourValue mSunColor;
|
||||||
|
|
||||||
|
Ogre::ColourValue mSunDiscColor;
|
||||||
|
|
||||||
|
float mFogDepth;
|
||||||
|
|
||||||
|
float mWindSpeed;
|
||||||
|
|
||||||
|
float mCloudSpeed;
|
||||||
|
|
||||||
|
float mCloudOpacity;
|
||||||
|
|
||||||
|
float mGlareView;
|
||||||
|
|
||||||
|
bool mNight; // use night skybox
|
||||||
|
float mNightFade; // fading factor for night skybox
|
||||||
|
|
||||||
|
Ogre::String mAmbientLoopSoundID;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Defines a single weather setting (according to INI)
|
||||||
|
struct Weather
|
||||||
|
{
|
||||||
|
Ogre::String mCloudTexture;
|
||||||
|
|
||||||
|
// Sky (atmosphere) colors
|
||||||
|
Ogre::ColourValue mSkySunriseColor,
|
||||||
|
mSkyDayColor,
|
||||||
|
mSkySunsetColor,
|
||||||
|
mSkyNightColor;
|
||||||
|
|
||||||
|
// Fog colors
|
||||||
|
Ogre::ColourValue mFogSunriseColor,
|
||||||
|
mFogDayColor,
|
||||||
|
mFogSunsetColor,
|
||||||
|
mFogNightColor;
|
||||||
|
|
||||||
|
// Ambient lighting colors
|
||||||
|
Ogre::ColourValue mAmbientSunriseColor,
|
||||||
|
mAmbientDayColor,
|
||||||
|
mAmbientSunsetColor,
|
||||||
|
mAmbientNightColor;
|
||||||
|
|
||||||
|
// Sun (directional) lighting colors
|
||||||
|
Ogre::ColourValue mSunSunriseColor,
|
||||||
|
mSunDayColor,
|
||||||
|
mSunSunsetColor,
|
||||||
|
mSunNightColor;
|
||||||
|
|
||||||
|
// Fog depth/density
|
||||||
|
float mLandFogDayDepth,
|
||||||
|
mLandFogNightDepth;
|
||||||
|
|
||||||
|
// Color modulation for the sun itself during sunset (not completely sure)
|
||||||
|
Ogre::ColourValue mSunDiscSunsetColor;
|
||||||
|
|
||||||
|
// Duration of weather transition (in days)
|
||||||
|
float mTransitionDelta;
|
||||||
|
|
||||||
|
// No idea what this one is used for?
|
||||||
|
float mWindSpeed;
|
||||||
|
|
||||||
|
// Cloud animation speed multiplier
|
||||||
|
float mCloudSpeed;
|
||||||
|
|
||||||
|
// Multiplier for clouds transparency
|
||||||
|
float mCloudsMaximumPercent;
|
||||||
|
|
||||||
|
// Value between 0 and 1, defines the strength of the sun glare effect
|
||||||
|
float mGlareView;
|
||||||
|
|
||||||
|
// Sound effect
|
||||||
|
// This is used for Blight, Ashstorm and Blizzard (Bloodmoon)
|
||||||
|
Ogre::String mAmbientLoopSoundID;
|
||||||
|
|
||||||
|
// Rain sound effect
|
||||||
|
Ogre::String mRainLoopSoundID;
|
||||||
|
|
||||||
|
/// \todo disease chance
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Interface for weather settings
|
||||||
|
///
|
||||||
|
class WeatherManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the weather in the specified region
|
||||||
|
* @param region that should be changed
|
||||||
|
* @param ID of the weather setting to shift to
|
||||||
|
*/
|
||||||
|
void changeWeather(const std::string& region, const unsigned int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Per-frame update
|
||||||
|
* @param duration
|
||||||
|
*/
|
||||||
|
void update(float duration);
|
||||||
|
|
||||||
|
void setHour(const float hour);
|
||||||
|
|
||||||
|
void setDate(const int day, const int month);
|
||||||
|
|
||||||
|
unsigned int getWeatherID() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float mHour;
|
||||||
|
int mDay, mMonth;
|
||||||
|
|
||||||
|
MWRender::RenderingManager* mRendering;
|
||||||
|
MWWorld::Environment* mEnvironment;
|
||||||
|
|
||||||
|
std::map<Ogre::String, Weather> mWeatherSettings;
|
||||||
|
|
||||||
|
std::map<std::string, std::string> mRegionOverrides;
|
||||||
|
|
||||||
|
Ogre::String mCurrentWeather;
|
||||||
|
Ogre::String mNextWeather;
|
||||||
|
|
||||||
|
std::string mCurrentRegion;
|
||||||
|
|
||||||
|
bool mFirstUpdate;
|
||||||
|
|
||||||
|
float mWeatherUpdateTime;
|
||||||
|
|
||||||
|
float mRemainingTransitionTime;
|
||||||
|
|
||||||
|
float mThunderFlash;
|
||||||
|
float mThunderChance;
|
||||||
|
float mThunderChanceNeeded;
|
||||||
|
float mThunderSoundDelay;
|
||||||
|
|
||||||
|
WeatherResult transition(const float factor);
|
||||||
|
WeatherResult getResult(const Ogre::String& weather);
|
||||||
|
|
||||||
|
void setWeather(const Ogre::String& weather, bool instant=false);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GAME_MWWORLD_WEATHER_H
|
|
@ -13,15 +13,20 @@
|
||||||
|
|
||||||
#include "../mwsound/soundmanager.hpp"
|
#include "../mwsound/soundmanager.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include "ptr.hpp"
|
#include "ptr.hpp"
|
||||||
#include "environment.hpp"
|
#include "environment.hpp"
|
||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
#include "weather.hpp"
|
||||||
|
|
||||||
#include "refdata.hpp"
|
#include "refdata.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
#include "cellfunctors.hpp"
|
#include "cellfunctors.hpp"
|
||||||
|
|
||||||
|
#include <OgreVector3.h>
|
||||||
|
using namespace Ogre;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -135,12 +140,16 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::adjustSky()
|
void World::adjustSky()
|
||||||
{
|
{
|
||||||
if (mSky)
|
if (mSky && (isCellExterior() || isCellQuasiExterior()))
|
||||||
{
|
{
|
||||||
toggleSky();
|
mRendering->skySetHour (mGlobalVariables->getFloat ("gamehour"));
|
||||||
// TODO set weather
|
mRendering->skySetDate (mGlobalVariables->getInt ("day"),
|
||||||
toggleSky();
|
mGlobalVariables->getInt ("month"));
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->enable();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mRendering->getSkyManager()->disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
World::World (OEngine::Render::OgreRenderer& renderer,
|
World::World (OEngine::Render::OgreRenderer& renderer,
|
||||||
|
@ -148,12 +157,14 @@ namespace MWWorld
|
||||||
const std::string& master, const boost::filesystem::path& resDir,
|
const std::string& master, const boost::filesystem::path& resDir,
|
||||||
bool newGame, Environment& environment, const std::string& encoding)
|
bool newGame, Environment& environment, const std::string& encoding)
|
||||||
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
|
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
|
||||||
mSky (false), mEnvironment (environment), mNextDynamicRecord (0), mCells (mStore, mEsm, *this)
|
mSky (true), mEnvironment (environment), mNextDynamicRecord (0), mCells (mStore, mEsm, *this)
|
||||||
{
|
{
|
||||||
mPhysics = new PhysicsSystem(renderer);
|
mPhysics = new PhysicsSystem(renderer);
|
||||||
mPhysEngine = mPhysics->getEngine();
|
mPhysEngine = mPhysics->getEngine();
|
||||||
|
|
||||||
mRendering = new MWRender::RenderingManager(renderer, resDir, mPhysEngine, environment);
|
mRendering = new MWRender::RenderingManager(renderer, resDir, mPhysEngine, environment);
|
||||||
|
|
||||||
|
mWeatherManager = new MWWorld::WeatherManager(mRendering, &environment);
|
||||||
|
|
||||||
boost::filesystem::path masterPath (fileCollections.getCollection (".esm").getPath (master));
|
boost::filesystem::path masterPath (fileCollections.getCollection (".esm").getPath (master));
|
||||||
|
|
||||||
|
@ -181,8 +192,10 @@ namespace MWWorld
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
World::~World()
|
World::~World()
|
||||||
{
|
{
|
||||||
|
delete mWeatherManager;
|
||||||
delete mWorldScene;
|
delete mWorldScene;
|
||||||
delete mGlobalVariables;
|
delete mGlobalVariables;
|
||||||
delete mRendering;
|
delete mRendering;
|
||||||
|
@ -368,6 +381,8 @@ namespace MWWorld
|
||||||
mGlobalVariables->setFloat ("gamehour", hour);
|
mGlobalVariables->setFloat ("gamehour", hour);
|
||||||
|
|
||||||
mRendering->skySetHour (hour);
|
mRendering->skySetHour (hour);
|
||||||
|
|
||||||
|
mWeatherManager->setHour (hour);
|
||||||
|
|
||||||
if (days>0)
|
if (days>0)
|
||||||
setDay (days + mGlobalVariables->getInt ("day"));
|
setDay (days + mGlobalVariables->getInt ("day"));
|
||||||
|
@ -403,6 +418,10 @@ namespace MWWorld
|
||||||
mGlobalVariables->setInt ("month", month);
|
mGlobalVariables->setInt ("month", month);
|
||||||
|
|
||||||
mRendering->skySetDate (day, month);
|
mRendering->skySetDate (day, month);
|
||||||
|
|
||||||
|
mWeatherManager->setDate (day, month);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::setMonth (int month)
|
void World::setMonth (int month)
|
||||||
|
@ -437,10 +456,6 @@ namespace MWWorld
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mSky = true;
|
mSky = true;
|
||||||
// TODO check for extorior or interior with sky.
|
|
||||||
mRendering->skySetHour (mGlobalVariables->getFloat ("gamehour"));
|
|
||||||
mRendering->skySetDate (mGlobalVariables->getInt ("day"),
|
|
||||||
mGlobalVariables->getInt ("month"));
|
|
||||||
mRendering->skyEnable();
|
mRendering->skyEnable();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -610,7 +625,7 @@ namespace MWWorld
|
||||||
|
|
||||||
bool World::toggleCollisionMode()
|
bool World::toggleCollisionMode()
|
||||||
{
|
{
|
||||||
return mPhysics->toggleCollisionMode();
|
return mPhysics->toggleCollisionMode();;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::toggleRenderMode (RenderMode mode)
|
bool World::toggleRenderMode (RenderMode mode)
|
||||||
|
@ -687,5 +702,56 @@ namespace MWWorld
|
||||||
void World::update (float duration)
|
void World::update (float duration)
|
||||||
{
|
{
|
||||||
mWorldScene->update (duration);
|
mWorldScene->update (duration);
|
||||||
|
|
||||||
|
mWeatherManager->update (duration);
|
||||||
|
|
||||||
|
// cast a ray from player to sun to detect if the sun is visible
|
||||||
|
// this is temporary until we find a better place to put this code
|
||||||
|
// currently its here because we need to access the physics system
|
||||||
|
float* p = mPlayer->getPlayer().getRefData().getPosition().pos;
|
||||||
|
Vector3 sun = mRendering->getSkyManager()->getRealSunPos();
|
||||||
|
sun = Vector3(sun.x, -sun.z, sun.y);
|
||||||
|
mRendering->getSkyManager()->setGlare(!mPhysics->castRay(Ogre::Vector3(p[0], p[1], p[2]), sun));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool World::isCellExterior() const
|
||||||
|
{
|
||||||
|
Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
|
||||||
|
if (currentCell)
|
||||||
|
{
|
||||||
|
if (!(currentCell->cell->data.flags & ESM::Cell::Interior))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool World::isCellQuasiExterior() const
|
||||||
|
{
|
||||||
|
Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
|
||||||
|
if (currentCell)
|
||||||
|
{
|
||||||
|
if (!(currentCell->cell->data.flags & ESM::Cell::QuasiEx))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int World::getCurrentWeather() const
|
||||||
|
{
|
||||||
|
return mWeatherManager->getWeatherID();
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::changeWeather(const std::string& region, const unsigned int id)
|
||||||
|
{
|
||||||
|
mWeatherManager->changeWeather(region, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
OEngine::Render::Fader* World::getFader()
|
||||||
|
{
|
||||||
|
return mRendering->getFader();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "localscripts.hpp"
|
#include "localscripts.hpp"
|
||||||
|
|
||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
|
#include <openengine/ogre/fader.hpp>
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
|
@ -49,6 +50,7 @@ namespace MWRender
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
class WeatherManager;
|
||||||
class Environment;
|
class Environment;
|
||||||
class Player;
|
class Player;
|
||||||
|
|
||||||
|
@ -60,12 +62,15 @@ namespace MWWorld
|
||||||
|
|
||||||
enum RenderMode
|
enum RenderMode
|
||||||
{
|
{
|
||||||
Render_CollisionDebug
|
Render_CollisionDebug,
|
||||||
|
Render_Wireframe
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
MWRender::RenderingManager* mRendering;
|
MWRender::RenderingManager* mRendering;
|
||||||
|
|
||||||
|
MWWorld::WeatherManager* mWeatherManager;
|
||||||
|
|
||||||
MWWorld::Scene *mWorldScene;
|
MWWorld::Scene *mWorldScene;
|
||||||
MWWorld::Player *mPlayer;
|
MWWorld::Player *mPlayer;
|
||||||
|
@ -101,11 +106,13 @@ namespace MWWorld
|
||||||
Environment& environment, const std::string& encoding);
|
Environment& environment, const std::string& encoding);
|
||||||
|
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
|
OEngine::Render::Fader* getFader();
|
||||||
|
|
||||||
Ptr::CellStore *getExterior (int x, int y);
|
Ptr::CellStore *getExterior (int x, int y);
|
||||||
|
|
||||||
Ptr::CellStore *getInterior (const std::string& name);
|
Ptr::CellStore *getInterior (const std::string& name);
|
||||||
|
|
||||||
void adjustSky();
|
void adjustSky();
|
||||||
|
|
||||||
MWWorld::Player& getPlayer();
|
MWWorld::Player& getPlayer();
|
||||||
|
@ -118,6 +125,9 @@ namespace MWWorld
|
||||||
|
|
||||||
bool hasCellChanged() const;
|
bool hasCellChanged() const;
|
||||||
///< Has the player moved to a different cell, since the last frame?
|
///< Has the player moved to a different cell, since the last frame?
|
||||||
|
|
||||||
|
bool isCellExterior() const;
|
||||||
|
bool isCellQuasiExterior() const;
|
||||||
|
|
||||||
Globals::Data& getGlobalVariable (const std::string& name);
|
Globals::Data& getGlobalVariable (const std::string& name);
|
||||||
|
|
||||||
|
@ -153,6 +163,10 @@ namespace MWWorld
|
||||||
|
|
||||||
bool toggleSky();
|
bool toggleSky();
|
||||||
///< \return Resulting mode
|
///< \return Resulting mode
|
||||||
|
|
||||||
|
void changeWeather(const std::string& region, const unsigned int id);
|
||||||
|
|
||||||
|
int getCurrentWeather() const;
|
||||||
|
|
||||||
int getMasserPhase() const;
|
int getMasserPhase() const;
|
||||||
|
|
||||||
|
@ -224,6 +238,7 @@ namespace MWWorld
|
||||||
/// references that are currently not in the rendered scene should be ignored.
|
/// references that are currently not in the rendered scene should be ignored.
|
||||||
|
|
||||||
void update (float duration);
|
void update (float duration);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
# Once done, this will define
|
# Once done, this will define
|
||||||
#
|
#
|
||||||
# OGRE_FOUND - system has OGRE
|
# OGRE_FOUND - system has OGRE
|
||||||
# OGRE_INCLUDE_DIRS - the OGRE include directories
|
# OGRE_INCLUDE_DIRS - the OGRE include directories
|
||||||
# OGRE_LIBRARIES - link these to use the OGRE core
|
# OGRE_LIBRARIES - link these to use the OGRE core
|
||||||
# OGRE_BINARY_REL - location of the main Ogre binary (win32 non-static only, release)
|
# OGRE_BINARY_REL - location of the main Ogre binary (win32 non-static only, release)
|
||||||
# OGRE_BINARY_DBG - location of the main Ogre binaries (win32 non-static only, debug)
|
# OGRE_BINARY_DBG - location of the main Ogre binaries (win32 non-static only, debug)
|
||||||
|
@ -33,9 +33,10 @@
|
||||||
#
|
#
|
||||||
# For each of these components, the following variables are defined:
|
# For each of these components, the following variables are defined:
|
||||||
#
|
#
|
||||||
|
|
||||||
# OGRE_${COMPONENT}_FOUND - ${COMPONENT} is available
|
# OGRE_${COMPONENT}_FOUND - ${COMPONENT} is available
|
||||||
# OGRE_${COMPONENT}_INCLUDE_DIRS - additional include directories for ${COMPONENT}
|
# OGRE_${COMPONENT}_INCLUDE_DIRS - additional include directories for ${COMPONENT}
|
||||||
# OGRE_${COMPONENT}_LIBRARIES - link these to use ${COMPONENT}
|
# OGRE_${COMPONENT}_LIBRARIES - link these to use ${COMPONENT}
|
||||||
# OGRE_${COMPONENT}_BINARY_REL - location of the component binary (win32 non-static only, release)
|
# OGRE_${COMPONENT}_BINARY_REL - location of the component binary (win32 non-static only, release)
|
||||||
# OGRE_${COMPONENT}_BINARY_DBG - location of the component binary (win32 non-static only, debug)
|
# OGRE_${COMPONENT}_BINARY_DBG - location of the component binary (win32 non-static only, debug)
|
||||||
#
|
#
|
||||||
|
@ -112,7 +113,7 @@ if (OGRE_PREFIX_SOURCE AND OGRE_PREFIX_BUILD)
|
||||||
set(OGRE_BIN_SEARCH_PATH ${dir}/bin ${OGRE_BIN_SEARCH_PATH})
|
set(OGRE_BIN_SEARCH_PATH ${dir}/bin ${OGRE_BIN_SEARCH_PATH})
|
||||||
set(OGRE_BIN_SEARCH_PATH ${dir}/Samples/Common/bin ${OGRE_BIN_SEARCH_PATH})
|
set(OGRE_BIN_SEARCH_PATH ${dir}/Samples/Common/bin ${OGRE_BIN_SEARCH_PATH})
|
||||||
endforeach(dir)
|
endforeach(dir)
|
||||||
|
|
||||||
if (OGRE_PREFIX_DEPENDENCIES_DIR)
|
if (OGRE_PREFIX_DEPENDENCIES_DIR)
|
||||||
set(OGRE_INC_SEARCH_PATH ${OGRE_PREFIX_DEPENDENCIES_DIR}/include ${OGRE_INC_SEARCH_PATH})
|
set(OGRE_INC_SEARCH_PATH ${OGRE_PREFIX_DEPENDENCIES_DIR}/include ${OGRE_INC_SEARCH_PATH})
|
||||||
set(OGRE_LIB_SEARCH_PATH ${OGRE_PREFIX_DEPENDENCIES_DIR}/lib ${OGRE_LIB_SEARCH_PATH})
|
set(OGRE_LIB_SEARCH_PATH ${OGRE_PREFIX_DEPENDENCIES_DIR}/lib ${OGRE_LIB_SEARCH_PATH})
|
||||||
|
@ -124,12 +125,12 @@ else()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# redo search if any of the environmental hints changed
|
# redo search if any of the environmental hints changed
|
||||||
set(OGRE_COMPONENTS Paging Terrain
|
set(OGRE_COMPONENTS Paging Terrain
|
||||||
Plugin_BSPSceneManager Plugin_CgProgramManager Plugin_OctreeSceneManager
|
Plugin_BSPSceneManager Plugin_CgProgramManager Plugin_OctreeSceneManager
|
||||||
Plugin_OctreeZone Plugin_PCZSceneManager Plugin_ParticleFX
|
Plugin_OctreeZone Plugin_PCZSceneManager Plugin_ParticleFX
|
||||||
RenderSystem_Direct3D11 RenderSystem_Direct3D9 RenderSystem_GL RenderSystem_GLES RenderSystem_GLES2)
|
RenderSystem_Direct3D11 RenderSystem_Direct3D9 RenderSystem_GL RenderSystem_GLES RenderSystem_GLES2)
|
||||||
set(OGRE_RESET_VARS
|
set(OGRE_RESET_VARS
|
||||||
OGRE_CONFIG_INCLUDE_DIR OGRE_INCLUDE_DIR
|
OGRE_CONFIG_INCLUDE_DIR OGRE_INCLUDE_DIR
|
||||||
OGRE_LIBRARY_FWK OGRE_LIBRARY_REL OGRE_LIBRARY_DBG
|
OGRE_LIBRARY_FWK OGRE_LIBRARY_REL OGRE_LIBRARY_DBG
|
||||||
OGRE_PLUGIN_DIR_DBG OGRE_PLUGIN_DIR_REL OGRE_MEDIA_DIR)
|
OGRE_PLUGIN_DIR_DBG OGRE_PLUGIN_DIR_REL OGRE_MEDIA_DIR)
|
||||||
foreach (comp ${OGRE_COMPONENTS})
|
foreach (comp ${OGRE_COMPONENTS})
|
||||||
|
@ -265,7 +266,7 @@ if (OGRE_STATIC)
|
||||||
if (APPLE AND NOT OGRE_BUILD_PLATFORM_APPLE_IOS)
|
if (APPLE AND NOT OGRE_BUILD_PLATFORM_APPLE_IOS)
|
||||||
set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${X11_LIBRARIES} ${X11_Xt_LIBRARIES} ${XAW_LIBRARY} ${X11_Xrandr_LIB} ${Carbon_LIBRARIES} ${Cocoa_LIBRARIES})
|
set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${X11_LIBRARIES} ${X11_Xt_LIBRARIES} ${XAW_LIBRARY} ${X11_Xrandr_LIB} ${Carbon_LIBRARIES} ${Cocoa_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT ZLIB_FOUND OR NOT ZZip_FOUND)
|
if (NOT ZLIB_FOUND OR NOT ZZip_FOUND)
|
||||||
set(OGRE_DEPS_FOUND FALSE)
|
set(OGRE_DEPS_FOUND FALSE)
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -308,7 +309,7 @@ if (OGRE_STATIC)
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT OGRE_DEPS_FOUND)
|
if (NOT OGRE_DEPS_FOUND)
|
||||||
pkg_message(OGRE "Could not find all required dependencies for the Ogre package.")
|
pkg_message(OGRE "Could not find all required dependencies for the Ogre package.")
|
||||||
set(OGRE_FOUND FALSE)
|
set(OGRE_FOUND FALSE)
|
||||||
|
@ -340,7 +341,7 @@ endif()
|
||||||
# Find Ogre components
|
# Find Ogre components
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|
||||||
set(OGRE_COMPONENT_SEARCH_PATH_REL
|
set(OGRE_COMPONENT_SEARCH_PATH_REL
|
||||||
${OGRE_LIBRARY_DIR_REL}/..
|
${OGRE_LIBRARY_DIR_REL}/..
|
||||||
${OGRE_LIBRARY_DIR_REL}/../..
|
${OGRE_LIBRARY_DIR_REL}/../..
|
||||||
${OGRE_BIN_SEARCH_PATH}
|
${OGRE_BIN_SEARCH_PATH}
|
||||||
|
@ -392,17 +393,17 @@ macro(ogre_find_plugin PLUGIN HEADER)
|
||||||
set(TMP_CMAKE_LIB_PREFIX ${CMAKE_FIND_LIBRARY_PREFIXES})
|
set(TMP_CMAKE_LIB_PREFIX ${CMAKE_FIND_LIBRARY_PREFIXES})
|
||||||
set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} "")
|
set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# strip RenderSystem_ or Plugin_ prefix from plugin name
|
# strip RenderSystem_ or Plugin_ prefix from plugin name
|
||||||
string(REPLACE "RenderSystem_" "" PLUGIN_TEMP ${PLUGIN})
|
string(REPLACE "RenderSystem_" "" PLUGIN_TEMP ${PLUGIN})
|
||||||
string(REPLACE "Plugin_" "" PLUGIN_NAME ${PLUGIN_TEMP})
|
string(REPLACE "Plugin_" "" PLUGIN_NAME ${PLUGIN_TEMP})
|
||||||
|
|
||||||
# header files for plugins are not usually needed, but find them anyway if they are present
|
# header files for plugins are not usually needed, but find them anyway if they are present
|
||||||
set(OGRE_PLUGIN_PATH_SUFFIXES
|
set(OGRE_PLUGIN_PATH_SUFFIXES
|
||||||
PlugIns PlugIns/${PLUGIN_NAME} Plugins Plugins/${PLUGIN_NAME} ${PLUGIN}
|
PlugIns PlugIns/${PLUGIN_NAME} Plugins Plugins/${PLUGIN_NAME} ${PLUGIN}
|
||||||
RenderSystems RenderSystems/${PLUGIN_NAME} ${ARGN})
|
RenderSystems RenderSystems/${PLUGIN_NAME} ${ARGN})
|
||||||
find_path(OGRE_${PLUGIN}_INCLUDE_DIR NAMES ${HEADER}
|
find_path(OGRE_${PLUGIN}_INCLUDE_DIR NAMES ${HEADER}
|
||||||
HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_PREFIX_SOURCE}
|
HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_PREFIX_SOURCE}
|
||||||
PATH_SUFFIXES ${OGRE_PLUGIN_PATH_SUFFIXES})
|
PATH_SUFFIXES ${OGRE_PLUGIN_PATH_SUFFIXES})
|
||||||
# find link libraries for plugins
|
# find link libraries for plugins
|
||||||
set(OGRE_${PLUGIN}_LIBRARY_NAMES "${PLUGIN}${OGRE_LIB_SUFFIX}")
|
set(OGRE_${PLUGIN}_LIBRARY_NAMES "${PLUGIN}${OGRE_LIB_SUFFIX}")
|
||||||
|
@ -428,7 +429,7 @@ macro(ogre_find_plugin PLUGIN HEADER)
|
||||||
if (OGRE_${PLUGIN}_FOUND)
|
if (OGRE_${PLUGIN}_FOUND)
|
||||||
if (NOT OGRE_PLUGIN_DIR_REL OR NOT OGRE_PLUGIN_DIR_DBG)
|
if (NOT OGRE_PLUGIN_DIR_REL OR NOT OGRE_PLUGIN_DIR_DBG)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(OGRE_PLUGIN_SEARCH_PATH_REL
|
set(OGRE_PLUGIN_SEARCH_PATH_REL
|
||||||
${OGRE_LIBRARY_DIR_REL}/..
|
${OGRE_LIBRARY_DIR_REL}/..
|
||||||
${OGRE_LIBRARY_DIR_REL}/../..
|
${OGRE_LIBRARY_DIR_REL}/../..
|
||||||
${OGRE_BIN_SEARCH_PATH}
|
${OGRE_BIN_SEARCH_PATH}
|
||||||
|
@ -449,7 +450,7 @@ macro(ogre_find_plugin PLUGIN HEADER)
|
||||||
set(OGRE_PLUGIN_DIR_DBG ${OGRE_PLUGIN_DIR_TMP} CACHE STRING "Ogre plugin dir (debug)" FORCE)
|
set(OGRE_PLUGIN_DIR_DBG ${OGRE_PLUGIN_DIR_TMP} CACHE STRING "Ogre plugin dir (debug)" FORCE)
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# find binaries
|
# find binaries
|
||||||
if (NOT OGRE_STATIC)
|
if (NOT OGRE_STATIC)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
@ -458,7 +459,7 @@ macro(ogre_find_plugin PLUGIN HEADER)
|
||||||
endif()
|
endif()
|
||||||
mark_as_advanced(OGRE_${PLUGIN}_REL OGRE_${PLUGIN}_DBG)
|
mark_as_advanced(OGRE_${PLUGIN}_REL OGRE_${PLUGIN}_DBG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (TMP_CMAKE_LIB_PREFIX)
|
if (TMP_CMAKE_LIB_PREFIX)
|
||||||
|
@ -498,7 +499,7 @@ if (OGRE_STATIC)
|
||||||
if (NOT Cg_FOUND)
|
if (NOT Cg_FOUND)
|
||||||
set(OGRE_Plugin_CgProgramManager_FOUND FALSE)
|
set(OGRE_Plugin_CgProgramManager_FOUND FALSE)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(OGRE_RenderSystem_Direct3D9_LIBRARIES ${OGRE_RenderSystem_Direct3D9_LIBRARIES}
|
set(OGRE_RenderSystem_Direct3D9_LIBRARIES ${OGRE_RenderSystem_Direct3D9_LIBRARIES}
|
||||||
${DirectX_LIBRARIES}
|
${DirectX_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
@ -539,4 +540,3 @@ set(OGRE_MEDIA_SEARCH_SUFFIX
|
||||||
clear_if_changed(OGRE_PREFIX_WATCH OGRE_MEDIA_DIR)
|
clear_if_changed(OGRE_PREFIX_WATCH OGRE_MEDIA_DIR)
|
||||||
find_path(OGRE_MEDIA_DIR NAMES packs/cubemapsJS.zip HINTS ${OGRE_MEDIA_SEARCH_PATH}
|
find_path(OGRE_MEDIA_DIR NAMES packs/cubemapsJS.zip HINTS ${OGRE_MEDIA_SEARCH_PATH}
|
||||||
PATHS ${OGRE_PREFIX_PATH} PATH_SUFFIXES ${OGRE_MEDIA_SEARCH_SUFFIX})
|
PATHS ${OGRE_PREFIX_PATH} PATH_SUFFIXES ${OGRE_MEDIA_SEARCH_SUFFIX})
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,6 @@ add_component_dir (bsa
|
||||||
bsa_archive bsa_file
|
bsa_archive bsa_file
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (cfg
|
|
||||||
configurationmanager
|
|
||||||
)
|
|
||||||
|
|
||||||
add_component_dir (nif
|
add_component_dir (nif
|
||||||
controlled effect nif_types record controller extra node record_ptr data nif_file property
|
controlled effect nif_types record controller extra node record_ptr data nif_file property
|
||||||
)
|
)
|
||||||
|
@ -47,7 +43,7 @@ add_component_dir (misc
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (files
|
add_component_dir (files
|
||||||
linuxpath windowspath macospath path multidircollection collections fileops
|
linuxpath windowspath macospath fixedpath multidircollection collections fileops configurationmanager
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (compiler
|
add_component_dir (compiler
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
#include "configurationmanager.hpp"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace Cfg
|
|
||||||
{
|
|
||||||
|
|
||||||
static const char* const openmwCfgFile = "openmw.cfg";
|
|
||||||
static const char* const ogreCfgFile = "ogre.cfg";
|
|
||||||
static const char* const pluginsCfgFile = "plugins.cfg";
|
|
||||||
|
|
||||||
|
|
||||||
ConfigurationManager::ConfigurationManager()
|
|
||||||
: mPath("openmw")
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* According to task #168 plugins.cfg file shall be located in global
|
|
||||||
* configuration path or in runtime configuration path.
|
|
||||||
*/
|
|
||||||
mPluginsCfgPath = mPath.getGlobalConfigPath() / pluginsCfgFile;
|
|
||||||
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
|
||||||
{
|
|
||||||
mPluginsCfgPath = mPath.getRuntimeConfigPath() / pluginsCfgFile;
|
|
||||||
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to find " << pluginsCfgFile << " file!" << std::endl;
|
|
||||||
mPluginsCfgPath.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* According to task #168 ogre.cfg file shall be located only
|
|
||||||
* in user configuration path.
|
|
||||||
*/
|
|
||||||
mOgreCfgPath = mPath.getLocalConfigPath() / ogreCfgFile;
|
|
||||||
|
|
||||||
mLogPath = mPath.getLocalConfigPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurationManager::~ConfigurationManager()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::readConfiguration(boost::program_options::variables_map& variables,
|
|
||||||
boost::program_options::options_description& description)
|
|
||||||
{
|
|
||||||
loadConfig(mPath.getLocalConfigPath(), variables, description);
|
|
||||||
boost::program_options::notify(variables);
|
|
||||||
loadConfig(mPath.getRuntimeConfigPath(), variables, description);
|
|
||||||
boost::program_options::notify(variables);
|
|
||||||
loadConfig(mPath.getGlobalConfigPath(), variables, description);
|
|
||||||
boost::program_options::notify(variables);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::loadConfig(const boost::filesystem::path& path,
|
|
||||||
boost::program_options::variables_map& variables,
|
|
||||||
boost::program_options::options_description& description)
|
|
||||||
{
|
|
||||||
boost::filesystem::path cfgFile(path);
|
|
||||||
cfgFile /= std::string(openmwCfgFile);
|
|
||||||
if (boost::filesystem::is_regular_file(cfgFile))
|
|
||||||
{
|
|
||||||
std::cout << "Loading config file: " << cfgFile.string() << "... ";
|
|
||||||
|
|
||||||
std::ifstream configFileStream(cfgFile.string().c_str());
|
|
||||||
if (configFileStream.is_open())
|
|
||||||
{
|
|
||||||
boost::program_options::store(boost::program_options::parse_config_file(
|
|
||||||
configFileStream, description), variables);
|
|
||||||
|
|
||||||
std::cout << "done." << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "failed." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getGlobalConfigPath() const
|
|
||||||
{
|
|
||||||
return mPath.getGlobalConfigPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setGlobalConfigPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setGlobalConfigPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getLocalConfigPath() const
|
|
||||||
{
|
|
||||||
return mPath.getLocalConfigPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setLocalConfigPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setLocalConfigPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getRuntimeConfigPath() const
|
|
||||||
{
|
|
||||||
return mPath.getRuntimeConfigPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setRuntimeConfigPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setRuntimeConfigPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getGlobalDataPath() const
|
|
||||||
{
|
|
||||||
return mPath.getGlobalDataPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setGlobalDataPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setGlobalDataPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getLocalDataPath() const
|
|
||||||
{
|
|
||||||
return mPath.getLocalDataPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setLocalDataPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setLocalDataPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getRuntimeDataPath() const
|
|
||||||
{
|
|
||||||
return mPath.getRuntimeDataPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setRuntimeDataPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setRuntimeDataPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getOgreConfigPath() const
|
|
||||||
{
|
|
||||||
return mOgreCfgPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getPluginsConfigPath() const
|
|
||||||
{
|
|
||||||
return mPluginsCfgPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getLogPath() const
|
|
||||||
{
|
|
||||||
return mLogPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace Cfg */
|
|
|
@ -1,62 +0,0 @@
|
||||||
#ifndef COMPONENTS_CFG_CONFIGURATIONMANAGER_HPP
|
|
||||||
#define COMPONENTS_CFG_CONFIGURATIONMANAGER_HPP
|
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
#include <components/files/path.hpp>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \namespace Cfg
|
|
||||||
*/
|
|
||||||
namespace Cfg
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \struct ConfigurationManager
|
|
||||||
*/
|
|
||||||
struct ConfigurationManager
|
|
||||||
{
|
|
||||||
ConfigurationManager();
|
|
||||||
virtual ~ConfigurationManager();
|
|
||||||
|
|
||||||
void readConfiguration(boost::program_options::variables_map& variables,
|
|
||||||
boost::program_options::options_description& description);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getGlobalConfigPath() const;
|
|
||||||
void setGlobalConfigPath(const boost::filesystem::path& newPath);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getLocalConfigPath() const;
|
|
||||||
void setLocalConfigPath(const boost::filesystem::path& newPath);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getRuntimeConfigPath() const;
|
|
||||||
void setRuntimeConfigPath(const boost::filesystem::path& newPath);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getGlobalDataPath() const;
|
|
||||||
void setGlobalDataPath(const boost::filesystem::path& newPath);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getLocalDataPath() const;
|
|
||||||
void setLocalDataPath(const boost::filesystem::path& newPath);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getRuntimeDataPath() const;
|
|
||||||
void setRuntimeDataPath(const boost::filesystem::path& newPath);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getOgreConfigPath() const;
|
|
||||||
const boost::filesystem::path& getPluginsConfigPath() const;
|
|
||||||
const boost::filesystem::path& getLogPath() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void loadConfig(const boost::filesystem::path& path,
|
|
||||||
boost::program_options::variables_map& variables,
|
|
||||||
boost::program_options::options_description& description);
|
|
||||||
|
|
||||||
Files::Path<> mPath;
|
|
||||||
|
|
||||||
boost::filesystem::path mOgreCfgPath;
|
|
||||||
boost::filesystem::path mPluginsCfgPath;
|
|
||||||
boost::filesystem::path mLogPath;
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace Cfg */
|
|
||||||
|
|
||||||
#endif /* COMPONENTS_CFG_CONFIGURATIONMANAGER_HPP */
|
|
|
@ -153,7 +153,7 @@ public:
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
int getVer() { return mCtx.header.version; }
|
int getVer() { return mCtx.header.version; }
|
||||||
float getFVer() { return *((float*)&mCtx.header.version); }
|
float getFVer() { if(mCtx.header.version == VER_12) return 1.2; else return 1.3; }
|
||||||
int getSpecial() { return mSpf; }
|
int getSpecial() { return mSpf; }
|
||||||
const std::string getAuthor() { return mCtx.header.author.toString(); }
|
const std::string getAuthor() { return mCtx.header.author.toString(); }
|
||||||
const std::string getDesc() { return mCtx.header.desc.toString(); }
|
const std::string getDesc() { return mCtx.header.desc.toString(); }
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#ifndef FILE_FINDER_MAIN_H
|
#ifndef FILE_FINDER_MAIN_H
|
||||||
#define FILE_FINDER_MAIN_H
|
#define FILE_FINDER_MAIN_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "search.hpp"
|
#include "search.hpp"
|
||||||
#include "filename_less.hpp"
|
#include "filename_less.hpp"
|
||||||
#include <map>
|
#include <components/files/multidircollection.hpp>
|
||||||
|
|
||||||
namespace FileFinder
|
namespace FileFinder
|
||||||
{
|
{
|
||||||
|
@ -11,7 +13,8 @@ namespace FileFinder
|
||||||
template <typename LESS>
|
template <typename LESS>
|
||||||
class FileFinderT
|
class FileFinderT
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string, LESS> table;
|
typedef std::map<std::string, std::string, LESS> TableContainer;
|
||||||
|
TableContainer table;
|
||||||
|
|
||||||
struct Inserter : ReturnPath
|
struct Inserter : ReturnPath
|
||||||
{
|
{
|
||||||
|
@ -35,12 +38,12 @@ public:
|
||||||
|
|
||||||
// Remember the original path length, so we can cut it away from
|
// Remember the original path length, so we can cut it away from
|
||||||
// the relative paths used as keys
|
// the relative paths used as keys
|
||||||
std::string pstring = path.string();
|
const std::string& pstring = path.string();
|
||||||
inserter.cut = pstring.size();
|
inserter.cut = pstring.size();
|
||||||
|
|
||||||
// If the path does not end in a slash, then boost will add one
|
// If the path does not end in a slash, then boost will add one
|
||||||
// later, which means one more character we have to remove.
|
// later, which means one more character we have to remove.
|
||||||
char last = pstring[pstring.size()-1];
|
char last = *pstring.rbegin();
|
||||||
if(last != '\\' && last != '/')
|
if(last != '\\' && last != '/')
|
||||||
inserter.cut++;
|
inserter.cut++;
|
||||||
|
|
||||||
|
@ -56,12 +59,84 @@ public:
|
||||||
// Find the full path from a relative path.
|
// Find the full path from a relative path.
|
||||||
const std::string &lookup(const std::string& file) const
|
const std::string &lookup(const std::string& file) const
|
||||||
{
|
{
|
||||||
return table.find(file)->second;
|
static std::string empty;
|
||||||
|
typename TableContainer::const_iterator it = table.find(file);
|
||||||
|
return (it != table.end()) ? it->second : empty;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class LESS
|
||||||
|
>
|
||||||
|
struct TreeFileFinder
|
||||||
|
{
|
||||||
|
typedef TreeFileFinder<LESS> finder_t;
|
||||||
|
|
||||||
|
TreeFileFinder(const Files::PathContainer& paths, bool recurse = true)
|
||||||
|
{
|
||||||
|
struct : ReturnPath
|
||||||
|
{
|
||||||
|
finder_t *owner;
|
||||||
|
int cut;
|
||||||
|
|
||||||
|
void add(const boost::filesystem::path &pth)
|
||||||
|
{
|
||||||
|
std::string file = pth.string();
|
||||||
|
std::string key = file.substr(cut);
|
||||||
|
owner->mTable[key] = file;
|
||||||
|
}
|
||||||
|
} inserter;
|
||||||
|
|
||||||
|
inserter.owner = this;
|
||||||
|
|
||||||
|
for (Files::PathContainer::const_iterator it = paths.begin(); it != paths.end(); ++it)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Remember the original path length, so we can cut it away from
|
||||||
|
// the relative paths used as keys
|
||||||
|
const std::string& pstring = it->string();
|
||||||
|
inserter.cut = pstring.size();
|
||||||
|
|
||||||
|
// If the path does not end in a slash, then boost will add one
|
||||||
|
// later, which means one more character we have to remove.
|
||||||
|
char last = *pstring.rbegin();
|
||||||
|
if (last != '\\' && last != '/')
|
||||||
|
{
|
||||||
|
inserter.cut++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the map
|
||||||
|
find(*it, inserter, recurse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has(const std::string& file) const
|
||||||
|
{
|
||||||
|
return mTable.find(file) != mTable.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& lookup(const std::string& file) const
|
||||||
|
{
|
||||||
|
static std::string empty;
|
||||||
|
typename TableContainer::const_iterator it = mTable.find(file);
|
||||||
|
return (it != mTable.end()) ? it->second : empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<std::string, std::string, LESS> TableContainer;
|
||||||
|
TableContainer mTable;
|
||||||
|
|
||||||
|
// Inserter inserter;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// The default is to use path_less for equality checks
|
// The default is to use path_less for equality checks
|
||||||
typedef FileFinderT<path_less> FileFinder;
|
typedef FileFinderT<path_less> FileFinder;
|
||||||
typedef FileFinderT<path_slash> FileFinderStrict;
|
typedef FileFinderT<path_slash> FileFinderStrict;
|
||||||
}
|
|
||||||
#endif
|
typedef TreeFileFinder<path_less> LessTreeFileFinder;
|
||||||
|
typedef TreeFileFinder<path_slash> StrictTreeFileFinder;
|
||||||
|
|
||||||
|
} /* namespace FileFinder */
|
||||||
|
#endif /* FILE_FINDER_MAIN_H */
|
||||||
|
|
|
@ -2,27 +2,35 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
void FileFinder::find(const boost::filesystem::path & dir_path, ReturnPath &ret, bool recurse)
|
||||||
using namespace boost::filesystem;
|
|
||||||
|
|
||||||
void FileFinder::find(const path & dir_path, ReturnPath &ret, bool recurse)
|
|
||||||
{
|
{
|
||||||
if ( !exists( dir_path ) )
|
if (boost::filesystem::exists(dir_path))
|
||||||
{
|
{
|
||||||
cout << "Path " << dir_path << " not found\n";
|
if (!recurse)
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
directory_iterator end_itr; // default construction yields past-the-end
|
|
||||||
for ( directory_iterator itr(dir_path);
|
|
||||||
itr != end_itr;
|
|
||||||
++itr )
|
|
||||||
{
|
|
||||||
if ( is_directory( *itr ) )
|
|
||||||
{
|
{
|
||||||
if(recurse) find(*itr, ret);
|
boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
|
||||||
|
for (boost::filesystem::directory_iterator itr(dir_path); itr != end_itr; ++itr)
|
||||||
|
{
|
||||||
|
if (!boost::filesystem::is_directory( *itr ))
|
||||||
|
{
|
||||||
|
ret.add(*itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret.add(*itr);
|
{
|
||||||
|
boost::filesystem::recursive_directory_iterator end_itr; // default construction yields past-the-end
|
||||||
|
for (boost::filesystem::recursive_directory_iterator itr(dir_path); itr != end_itr; ++itr)
|
||||||
|
{
|
||||||
|
if (!boost::filesystem::is_directory(*itr))
|
||||||
|
{
|
||||||
|
ret.add(*itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Path " << dir_path << " not found" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
182
components/files/configurationmanager.cpp
Normal file
182
components/files/configurationmanager.cpp
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
#include "configurationmanager.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/algorithm/string/erase.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \namespace Files
|
||||||
|
*/
|
||||||
|
namespace Files
|
||||||
|
{
|
||||||
|
|
||||||
|
static const char* const openmwCfgFile = "openmw.cfg";
|
||||||
|
static const char* const ogreCfgFile = "ogre.cfg";
|
||||||
|
static const char* const pluginsCfgFile = "plugins.cfg";
|
||||||
|
|
||||||
|
const char* const mwToken = "?mw?";
|
||||||
|
const char* const localToken = "?local?";
|
||||||
|
const char* const userToken = "?user?";
|
||||||
|
const char* const globalToken = "?global?";
|
||||||
|
|
||||||
|
ConfigurationManager::ConfigurationManager()
|
||||||
|
: mFixedPath("openmw")
|
||||||
|
{
|
||||||
|
setupTokensMapping();
|
||||||
|
|
||||||
|
mPluginsCfgPath = mFixedPath.getGlobalPath() / pluginsCfgFile;
|
||||||
|
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
||||||
|
{
|
||||||
|
mPluginsCfgPath = mFixedPath.getLocalPath() / pluginsCfgFile;
|
||||||
|
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to find " << pluginsCfgFile << " file!" << std::endl;
|
||||||
|
mPluginsCfgPath.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mOgreCfgPath = mFixedPath.getUserPath() / ogreCfgFile;
|
||||||
|
mLogPath = mFixedPath.getUserPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationManager::~ConfigurationManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationManager::setupTokensMapping()
|
||||||
|
{
|
||||||
|
mTokensMapping.insert(std::make_pair(mwToken, &FixedPath<>::getInstallPath));
|
||||||
|
mTokensMapping.insert(std::make_pair(localToken, &FixedPath<>::getLocalPath));
|
||||||
|
mTokensMapping.insert(std::make_pair(userToken, &FixedPath<>::getUserPath));
|
||||||
|
mTokensMapping.insert(std::make_pair(globalToken, &FixedPath<>::getGlobalDataPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationManager::readConfiguration(boost::program_options::variables_map& variables,
|
||||||
|
boost::program_options::options_description& description)
|
||||||
|
{
|
||||||
|
loadConfig(mFixedPath.getUserPath(), variables, description);
|
||||||
|
boost::program_options::notify(variables);
|
||||||
|
|
||||||
|
loadConfig(mFixedPath.getLocalPath(), variables, description);
|
||||||
|
boost::program_options::notify(variables);
|
||||||
|
loadConfig(mFixedPath.getGlobalPath(), variables, description);
|
||||||
|
boost::program_options::notify(variables);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationManager::processPaths(Files::PathContainer& dataDirs)
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it)
|
||||||
|
{
|
||||||
|
path = it->string();
|
||||||
|
boost::erase_all(path, "\"");
|
||||||
|
*it = boost::filesystem::path(path);
|
||||||
|
|
||||||
|
// Check if path contains a token
|
||||||
|
if (!path.empty() && *path.begin() == '?')
|
||||||
|
{
|
||||||
|
std::string::size_type pos = path.find('?', 1);
|
||||||
|
if (pos != std::string::npos && pos != 0)
|
||||||
|
{
|
||||||
|
TokensMappingContainer::iterator tokenIt = mTokensMapping.find(path.substr(0, pos + 1));
|
||||||
|
if (tokenIt != mTokensMapping.end())
|
||||||
|
{
|
||||||
|
boost::filesystem::path tempPath(((mFixedPath).*(tokenIt->second))());
|
||||||
|
if (pos < path.length() - 1)
|
||||||
|
{
|
||||||
|
// There is something after the token, so we should
|
||||||
|
// append it to the path
|
||||||
|
tempPath /= path.substr(pos + 1, path.length() - pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
*it = tempPath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clean invalid / unknown token, it will be removed outside the loop
|
||||||
|
(*it).clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!boost::filesystem::is_directory(*it))
|
||||||
|
{
|
||||||
|
(*it).clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataDirs.erase(std::remove_if(dataDirs.begin(), dataDirs.end(),
|
||||||
|
boost::bind(&boost::filesystem::path::empty, _1)), dataDirs.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationManager::loadConfig(const boost::filesystem::path& path,
|
||||||
|
boost::program_options::variables_map& variables,
|
||||||
|
boost::program_options::options_description& description)
|
||||||
|
{
|
||||||
|
boost::filesystem::path cfgFile(path);
|
||||||
|
cfgFile /= std::string(openmwCfgFile);
|
||||||
|
if (boost::filesystem::is_regular_file(cfgFile))
|
||||||
|
{
|
||||||
|
std::cout << "Loading config file: " << cfgFile.string() << "... ";
|
||||||
|
|
||||||
|
std::ifstream configFileStream(cfgFile.string().c_str());
|
||||||
|
if (configFileStream.is_open())
|
||||||
|
{
|
||||||
|
boost::program_options::store(boost::program_options::parse_config_file(
|
||||||
|
configFileStream, description, true), variables);
|
||||||
|
|
||||||
|
std::cout << "done." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "failed." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getGlobalPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getGlobalPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getUserPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getUserPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getLocalPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getLocalPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getGlobalDataPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getGlobalDataPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getInstallPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getInstallPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getOgreConfigPath() const
|
||||||
|
{
|
||||||
|
return mOgreCfgPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getPluginsConfigPath() const
|
||||||
|
{
|
||||||
|
return mPluginsCfgPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getLogPath() const
|
||||||
|
{
|
||||||
|
return mLogPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace Cfg */
|
71
components/files/configurationmanager.hpp
Normal file
71
components/files/configurationmanager.hpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#ifndef COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP
|
||||||
|
#define COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <boost/tr1/tr1/unordered_map>
|
||||||
|
#else
|
||||||
|
#include <tr1/unordered_map>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#include <components/files/fixedpath.hpp>
|
||||||
|
#include <components/files/collections.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \namespace Files
|
||||||
|
*/
|
||||||
|
namespace Files
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \struct ConfigurationManager
|
||||||
|
*/
|
||||||
|
struct ConfigurationManager
|
||||||
|
{
|
||||||
|
ConfigurationManager();
|
||||||
|
virtual ~ConfigurationManager();
|
||||||
|
|
||||||
|
void readConfiguration(boost::program_options::variables_map& variables,
|
||||||
|
boost::program_options::options_description& description);
|
||||||
|
void processPaths(Files::PathContainer& dataDirs);
|
||||||
|
|
||||||
|
/**< Fixed paths */
|
||||||
|
const boost::filesystem::path& getGlobalPath() const;
|
||||||
|
const boost::filesystem::path& getUserPath() const;
|
||||||
|
const boost::filesystem::path& getLocalPath() const;
|
||||||
|
|
||||||
|
const boost::filesystem::path& getGlobalDataPath() const;
|
||||||
|
const boost::filesystem::path& getUserDataPath() const;
|
||||||
|
const boost::filesystem::path& getLocalDataPath() const;
|
||||||
|
const boost::filesystem::path& getInstallPath() const;
|
||||||
|
|
||||||
|
const boost::filesystem::path& getOgreConfigPath() const;
|
||||||
|
const boost::filesystem::path& getPluginsConfigPath() const;
|
||||||
|
const boost::filesystem::path& getLogPath() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef Files::FixedPath<> FixedPathType;
|
||||||
|
|
||||||
|
typedef const boost::filesystem::path& (FixedPathType::*path_type_f)() const;
|
||||||
|
typedef std::tr1::unordered_map<std::string, path_type_f> TokensMappingContainer;
|
||||||
|
|
||||||
|
void loadConfig(const boost::filesystem::path& path,
|
||||||
|
boost::program_options::variables_map& variables,
|
||||||
|
boost::program_options::options_description& description);
|
||||||
|
|
||||||
|
void setupTokensMapping();
|
||||||
|
|
||||||
|
FixedPathType mFixedPath;
|
||||||
|
|
||||||
|
boost::filesystem::path mOgreCfgPath;
|
||||||
|
boost::filesystem::path mPluginsCfgPath;
|
||||||
|
boost::filesystem::path mLogPath;
|
||||||
|
|
||||||
|
TokensMappingContainer mTokensMapping;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace Cfg */
|
||||||
|
|
||||||
|
#endif /* COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue