From 2efd38b1ab3f9d349284eb478caaf4918eeac030 Mon Sep 17 00:00:00 2001 From: Phillip Andrews Date: Sun, 13 Nov 2016 13:32:42 -0600 Subject: [PATCH 01/10] Fix install procedure so it works with all MSVC build configurations, not just Release --- CMakeLists.txt | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 939c27310..7d206baab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git) else(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/shallow) message(STATUS "Shallow Git clone detected, not attempting to retrieve version info") endif(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/shallow) -endif(EXISTS ${PROJECT_SOURCE_DIR}/.git) +endif(EXISTS ${PROJECT_SOURCE_DIR}/.git) # Macros include(OpenMWMacros) @@ -419,8 +419,10 @@ IF(NOT WIN32 AND NOT APPLE) ENDIF(NOT WIN32 AND NOT APPLE) if(WIN32) - FILE(GLOB dll_files "${OpenMW_BINARY_DIR}/Release/*.dll") - INSTALL(FILES ${dll_files} DESTINATION ".") + FILE(GLOB dll_files_debug "${OpenMW_BINARY_DIR}/Debug/*.dll") + FILE(GLOB dll_files_release "${OpenMW_BINARY_DIR}/Release/*.dll") + INSTALL(FILES ${dll_files_debug} DESTINATION "." CONFIGURATIONS Debug) + INSTALL(FILES ${dll_files_release} DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") @@ -429,27 +431,34 @@ if(WIN32) "${OpenMW_SOURCE_DIR}/Docs/license/DejaVu Font License.txt" "${OpenMW_BINARY_DIR}/settings-default.cfg" "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" - "${OpenMW_BINARY_DIR}/Release/openmw.exe" DESTINATION ".") + INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/openmw.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/openmw.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) IF(BUILD_LAUNCHER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-launcher.exe" DESTINATION ".") + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-launcher.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-launcher.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_LAUNCHER) IF(BUILD_MWINIIMPORTER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-iniimporter.exe" DESTINATION ".") + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-iniimporter.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-iniimporter.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_MWINIIMPORTER) IF(BUILD_ESSIMPORTER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-essimporter.exe" DESTINATION ".") + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-essimporter.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-essimporter.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_ESSIMPORTER) IF(BUILD_OPENCS) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-cs.exe" DESTINATION ".") + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-cs.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-cs.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION ".") ENDIF(BUILD_OPENCS) IF(BUILD_WIZARD) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION ".") + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-wizard.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_WIZARD) if(BUILD_MYGUI_PLUGIN) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION ".") + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_MYGUI_PLUGIN) IF(DESIRED_QT_VERSION MATCHES 5) @@ -828,3 +837,4 @@ if (DOXYGEN_FOUND) WORKING_DIRECTORY ${OpenMW_BINARY_DIR} COMMENT "Generating documentation for the github-pages at ${DOXYGEN_PAGES_OUTPUT_DIR}" VERBATIM) endif () + From 1861302dbd82ff674da0beacad76c44b21760c7b Mon Sep 17 00:00:00 2001 From: Phillip Andrews Date: Sun, 13 Nov 2016 14:27:59 -0600 Subject: [PATCH 02/10] Include various libraries for Visual Studio environment --- apps/essimporter/CMakeLists.txt | 4 ++++ apps/launcher/CMakeLists.txt | 4 ++++ apps/mwiniimporter/CMakeLists.txt | 4 ++++ apps/opencs/CMakeLists.txt | 9 +++++++++ apps/openmw/CMakeLists.txt | 2 ++ 5 files changed, 23 insertions(+) diff --git a/apps/essimporter/CMakeLists.txt b/apps/essimporter/CMakeLists.txt index 84e31dad9..5fe93bd3e 100644 --- a/apps/essimporter/CMakeLists.txt +++ b/apps/essimporter/CMakeLists.txt @@ -42,3 +42,7 @@ if (BUILD_WITH_CODE_COVERAGE) add_definitions (--coverage) target_link_libraries(openmw-essimporter gcov) endif() + +if (MSVC) + target_link_libraries(openmw-essimporter imm32.lib winmm.lib version.lib) +endif(MSVC) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 207f6a84b..8bb55158e 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -92,6 +92,10 @@ target_link_libraries(openmw-launcher components ) +if(MSVC) + target_link_libraries(openmw-launcher imm32.lib winmm.lib version.lib) +endif(MSVC) + if (DESIRED_QT_VERSION MATCHES 4) target_link_libraries(openmw-launcher ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY}) if(WIN32) diff --git a/apps/mwiniimporter/CMakeLists.txt b/apps/mwiniimporter/CMakeLists.txt index 4024c0b42..4c73a4c35 100644 --- a/apps/mwiniimporter/CMakeLists.txt +++ b/apps/mwiniimporter/CMakeLists.txt @@ -24,6 +24,10 @@ if (WIN32) ${Boost_LOCALE_LIBRARY}) endif() +if(MSVC) + target_link_libraries(openmw-iniimporter imm32.lib winmm.lib version.lib) +endif(MSVC) + if (MINGW) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") endif() diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 1f572c3f8..c5f18656c 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -225,6 +225,15 @@ if (WIN32) target_link_libraries(openmw-cs ${Boost_LOCALE_LIBRARY}) endif() +if (MSVC) + # Debug version needs increased number of sections beyond 2^16 + if (CMAKE_CL_64) + set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") + endif (CMAKE_CL_64) + add_definitions("-D_USE_MATH_DEFINES") + target_link_libraries(openmw-cs imm32.lib winmm.lib version.lib) +endif (MSVC) + if(APPLE) INSTALL(TARGETS openmw-cs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 277acea2d..e24c8ad94 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -201,4 +201,6 @@ if (MSVC) set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") endif (CMAKE_CL_64) add_definitions("-D_USE_MATH_DEFINES") + target_link_libraries(openmw imm32.lib winmm.lib version.lib) endif (MSVC) + From a1225ff4ecd915a481848104252d737263249761 Mon Sep 17 00:00:00 2001 From: Phillip Andrews Date: Sun, 13 Nov 2016 14:34:12 -0600 Subject: [PATCH 03/10] Additional MSVC library dependencies --- apps/bsatool/CMakeLists.txt | 4 ++++ apps/esmtool/CMakeLists.txt | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/apps/bsatool/CMakeLists.txt b/apps/bsatool/CMakeLists.txt index 27baff815..0c18e6bc1 100644 --- a/apps/bsatool/CMakeLists.txt +++ b/apps/bsatool/CMakeLists.txt @@ -18,3 +18,7 @@ if (BUILD_WITH_CODE_COVERAGE) add_definitions (--coverage) target_link_libraries(bsatool gcov) endif() + +if(MSVC) + target_link_libraries(bsatool imm32.lib winmm.lib version.lib) +endif(MSVC) diff --git a/apps/esmtool/CMakeLists.txt b/apps/esmtool/CMakeLists.txt index 1d5e662d8..6704e45f4 100644 --- a/apps/esmtool/CMakeLists.txt +++ b/apps/esmtool/CMakeLists.txt @@ -21,3 +21,7 @@ if (BUILD_WITH_CODE_COVERAGE) add_definitions (--coverage) target_link_libraries(esmtool gcov) endif() + +if(MSVC) + target_link_libraries(esmtool imm32.lib winmm.lib version.lib) +endif(MSVC) From 86b46735396e9fcc871e0f02327415cb4bfcc40a Mon Sep 17 00:00:00 2001 From: Phillip Andrews Date: Sun, 13 Nov 2016 16:43:07 -0600 Subject: [PATCH 04/10] Removed math constants in openmw-cs, which are apparently not going to be used --- apps/opencs/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index c5f18656c..6e5b7b7c9 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -230,7 +230,6 @@ if (MSVC) if (CMAKE_CL_64) set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") endif (CMAKE_CL_64) - add_definitions("-D_USE_MATH_DEFINES") target_link_libraries(openmw-cs imm32.lib winmm.lib version.lib) endif (MSVC) From 59eba1dedecee642c9c0b68d5c7829b9f0688631 Mon Sep 17 00:00:00 2001 From: Phillip Andrews Date: Sun, 13 Nov 2016 16:59:36 -0600 Subject: [PATCH 05/10] Changed tabs to spaces, oops --- CMakeLists.txt | 21 +++++++++++---------- apps/essimporter/CMakeLists.txt | 2 +- apps/launcher/CMakeLists.txt | 2 +- apps/mwiniimporter/CMakeLists.txt | 2 +- apps/opencs/CMakeLists.txt | 2 +- apps/openmw/CMakeLists.txt | 2 +- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d206baab..b4d4b37cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -419,10 +419,11 @@ IF(NOT WIN32 AND NOT APPLE) ENDIF(NOT WIN32 AND NOT APPLE) if(WIN32) - FILE(GLOB dll_files_debug "${OpenMW_BINARY_DIR}/Debug/*.dll") + MESSAGE(${RUNTIME_OUTPUT_DIR}) + FILE(GLOB dll_files_debug "${OpenMW_BINARY_DIR}/Debug/*.dll") FILE(GLOB dll_files_release "${OpenMW_BINARY_DIR}/Release/*.dll") INSTALL(FILES ${dll_files_debug} DESTINATION "." CONFIGURATIONS Debug) - INSTALL(FILES ${dll_files_release} DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) + INSTALL(FILES ${dll_files_release} DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") @@ -432,32 +433,32 @@ if(WIN32) "${OpenMW_BINARY_DIR}/settings-default.cfg" "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION ".") - INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/openmw.exe" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/openmw.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) + INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/openmw.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/openmw.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) IF(BUILD_LAUNCHER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-launcher.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-launcher.exe" DESTINATION "." CONFIGURATIONS Debug) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-launcher.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_LAUNCHER) IF(BUILD_MWINIIMPORTER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-iniimporter.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-iniimporter.exe" DESTINATION "." CONFIGURATIONS Debug) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-iniimporter.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_MWINIIMPORTER) IF(BUILD_ESSIMPORTER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-essimporter.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-essimporter.exe" DESTINATION "." CONFIGURATIONS Debug) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-essimporter.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_ESSIMPORTER) IF(BUILD_OPENCS) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-cs.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-cs.exe" DESTINATION "." CONFIGURATIONS Debug) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-cs.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION ".") ENDIF(BUILD_OPENCS) IF(BUILD_WIZARD) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-wizard.exe" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-wizard.exe" DESTINATION "." CONFIGURATIONS Debug) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_WIZARD) if(BUILD_MYGUI_PLUGIN) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION "." CONFIGURATIONS Debug) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_MYGUI_PLUGIN) diff --git a/apps/essimporter/CMakeLists.txt b/apps/essimporter/CMakeLists.txt index 5fe93bd3e..5a0a3e6b8 100644 --- a/apps/essimporter/CMakeLists.txt +++ b/apps/essimporter/CMakeLists.txt @@ -44,5 +44,5 @@ if (BUILD_WITH_CODE_COVERAGE) endif() if (MSVC) - target_link_libraries(openmw-essimporter imm32.lib winmm.lib version.lib) + target_link_libraries(openmw-essimporter imm32.lib winmm.lib version.lib) endif(MSVC) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 8bb55158e..6d5655836 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -93,7 +93,7 @@ target_link_libraries(openmw-launcher ) if(MSVC) - target_link_libraries(openmw-launcher imm32.lib winmm.lib version.lib) + target_link_libraries(openmw-launcher imm32.lib winmm.lib version.lib) endif(MSVC) if (DESIRED_QT_VERSION MATCHES 4) diff --git a/apps/mwiniimporter/CMakeLists.txt b/apps/mwiniimporter/CMakeLists.txt index 4c73a4c35..3e0f4da61 100644 --- a/apps/mwiniimporter/CMakeLists.txt +++ b/apps/mwiniimporter/CMakeLists.txt @@ -25,7 +25,7 @@ if (WIN32) endif() if(MSVC) - target_link_libraries(openmw-iniimporter imm32.lib winmm.lib version.lib) + target_link_libraries(openmw-iniimporter imm32.lib winmm.lib version.lib) endif(MSVC) if (MINGW) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 6e5b7b7c9..00c2853a6 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -230,7 +230,7 @@ if (MSVC) if (CMAKE_CL_64) set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") endif (CMAKE_CL_64) - target_link_libraries(openmw-cs imm32.lib winmm.lib version.lib) + target_link_libraries(openmw-cs imm32.lib winmm.lib version.lib) endif (MSVC) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index e24c8ad94..21b69f36e 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -201,6 +201,6 @@ if (MSVC) set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") endif (CMAKE_CL_64) add_definitions("-D_USE_MATH_DEFINES") - target_link_libraries(openmw imm32.lib winmm.lib version.lib) + target_link_libraries(openmw imm32.lib winmm.lib version.lib) endif (MSVC) From 7383cc9de4dd03c5402a4366b47942cc82e9914e Mon Sep 17 00:00:00 2001 From: Phillip Andrews Date: Sun, 13 Nov 2016 17:06:00 -0600 Subject: [PATCH 06/10] Forgot to undo my test edits because I am a big dum-dum --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4d4b37cf..025e602f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -419,7 +419,6 @@ IF(NOT WIN32 AND NOT APPLE) ENDIF(NOT WIN32 AND NOT APPLE) if(WIN32) - MESSAGE(${RUNTIME_OUTPUT_DIR}) FILE(GLOB dll_files_debug "${OpenMW_BINARY_DIR}/Debug/*.dll") FILE(GLOB dll_files_release "${OpenMW_BINARY_DIR}/Release/*.dll") INSTALL(FILES ${dll_files_debug} DESTINATION "." CONFIGURATIONS Debug) From aeaedbc57a682cc50dc645654f8a3039e7d842b8 Mon Sep 17 00:00:00 2001 From: Phillip Andrews Date: Sun, 13 Nov 2016 22:49:01 -0600 Subject: [PATCH 07/10] Moved install commands to target-specific cmakelists so that all configurations work. --- CMakeLists.txt | 32 ++++++------------------------- apps/essimporter/CMakeLists.txt | 4 ++++ apps/launcher/CMakeLists.txt | 4 ++++ apps/mwiniimporter/CMakeLists.txt | 3 ++- apps/opencs/CMakeLists.txt | 2 ++ apps/openmw/CMakeLists.txt | 4 ++++ apps/wizard/CMakeLists.txt | 3 +++ 7 files changed, 25 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 025e602f8..0d74e8cbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -432,42 +432,22 @@ if(WIN32) "${OpenMW_BINARY_DIR}/settings-default.cfg" "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION ".") - INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/openmw.exe" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/openmw.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - IF(BUILD_LAUNCHER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-launcher.exe" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-launcher.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - ENDIF(BUILD_LAUNCHER) - IF(BUILD_MWINIIMPORTER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-iniimporter.exe" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-iniimporter.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - ENDIF(BUILD_MWINIIMPORTER) - IF(BUILD_ESSIMPORTER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-essimporter.exe" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-essimporter.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - ENDIF(BUILD_ESSIMPORTER) - IF(BUILD_OPENCS) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-cs.exe" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-cs.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION ".") - ENDIF(BUILD_OPENCS) - IF(BUILD_WIZARD) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/openmw-wizard.exe" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - ENDIF(BUILD_WIZARD) if(BUILD_MYGUI_PLUGIN) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION "." CONFIGURATIONS Debug) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF(BUILD_MYGUI_PLUGIN) IF(DESIRED_QT_VERSION MATCHES 5) - INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Release/platforms" DESTINATION ".") + INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Debug/platforms" DESTINATION "." CONFIGURATIONS Debug) + INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Release/platforms" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) ENDIF() INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") - FILE(GLOB plugin_dir "${OpenMW_BINARY_DIR}/Release/osgPlugins-*") - INSTALL(DIRECTORY ${plugin_dir} DESTINATION ".") + FILE(GLOB plugin_dir_debug "${OpenMW_BINARY_DIR}/Debug/osgPlugins-*") + FILE(GLOB plugin_dir_release "${OpenMW_BINARY_DIR}/Release/osgPlugins-*") + INSTALL(DIRECTORY ${plugin_dir_debug} DESTINATION "." CONFIGURATIONS Debug) + INSTALL(DIRECTORY ${plugin_dir_release} DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) SET(CPACK_GENERATOR "NSIS") SET(CPACK_PACKAGE_NAME "OpenMW") diff --git a/apps/essimporter/CMakeLists.txt b/apps/essimporter/CMakeLists.txt index 5a0a3e6b8..5683a6a86 100644 --- a/apps/essimporter/CMakeLists.txt +++ b/apps/essimporter/CMakeLists.txt @@ -43,6 +43,10 @@ if (BUILD_WITH_CODE_COVERAGE) target_link_libraries(openmw-essimporter gcov) endif() +if (WIN32) + INSTALL(TARGETS openmw-essimporter RUNTIME DESTINATION ".") +endif(WIN32) + if (MSVC) target_link_libraries(openmw-essimporter imm32.lib winmm.lib version.lib) endif(MSVC) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 6d5655836..476451d2a 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -87,6 +87,10 @@ add_executable(openmw-launcher ${UI_HDRS} ) +if (WIN32) + INSTALL(TARGETS openmw-launcher RUNTIME DESTINATION ".") +endif (WIN32) + target_link_libraries(openmw-launcher ${SDL2_LIBRARY_ONLY} components diff --git a/apps/mwiniimporter/CMakeLists.txt b/apps/mwiniimporter/CMakeLists.txt index 3e0f4da61..b0351eb3f 100644 --- a/apps/mwiniimporter/CMakeLists.txt +++ b/apps/mwiniimporter/CMakeLists.txt @@ -22,7 +22,8 @@ target_link_libraries(openmw-iniimporter if (WIN32) target_link_libraries(openmw-iniimporter ${Boost_LOCALE_LIBRARY}) -endif() + INSTALL(TARGETS openmw-iniimporter RUNTIME DESTINATION ".") +endif(WIN32) if(MSVC) target_link_libraries(openmw-iniimporter imm32.lib winmm.lib version.lib) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 00c2853a6..1511a0bc4 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -223,6 +223,8 @@ endif() if (WIN32) target_link_libraries(openmw-cs ${Boost_LOCALE_LIBRARY}) + INSTALL(TARGETS openmw-cs RUNTIME DESTINATION ".") + INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION ".") endif() if (MSVC) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 21b69f36e..fa2fed3c6 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -204,3 +204,7 @@ if (MSVC) target_link_libraries(openmw imm32.lib winmm.lib version.lib) endif (MSVC) +if (WIN32) + INSTALL(TARGETS openmw RUNTIME DESTINATION ".") +endif (WIN32) + diff --git a/apps/wizard/CMakeLists.txt b/apps/wizard/CMakeLists.txt index dd2e1a748..d2b9ab0f6 100644 --- a/apps/wizard/CMakeLists.txt +++ b/apps/wizard/CMakeLists.txt @@ -140,3 +140,6 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux") target_link_libraries(openmw-wizard dl Xt) endif() +if (WIN32) + INSTALL(TARGETS openmw-wizard RUNTIME DESTINATION ".") +endif(WIN32) From c18fc113e56efb28b0ddb1ef8f70b6f2b0129965 Mon Sep 17 00:00:00 2001 From: Phillip Andrews Date: Mon, 14 Nov 2016 00:01:22 -0600 Subject: [PATCH 08/10] Changed missing library dependencies to simple fix --- apps/bsatool/CMakeLists.txt | 4 ---- apps/esmtool/CMakeLists.txt | 4 ---- apps/essimporter/CMakeLists.txt | 4 ---- apps/launcher/CMakeLists.txt | 4 ---- apps/mwiniimporter/CMakeLists.txt | 4 ---- apps/opencs/CMakeLists.txt | 1 - apps/openmw/CMakeLists.txt | 1 - components/CMakeLists.txt | 2 +- 8 files changed, 1 insertion(+), 23 deletions(-) diff --git a/apps/bsatool/CMakeLists.txt b/apps/bsatool/CMakeLists.txt index 0c18e6bc1..27baff815 100644 --- a/apps/bsatool/CMakeLists.txt +++ b/apps/bsatool/CMakeLists.txt @@ -18,7 +18,3 @@ if (BUILD_WITH_CODE_COVERAGE) add_definitions (--coverage) target_link_libraries(bsatool gcov) endif() - -if(MSVC) - target_link_libraries(bsatool imm32.lib winmm.lib version.lib) -endif(MSVC) diff --git a/apps/esmtool/CMakeLists.txt b/apps/esmtool/CMakeLists.txt index 6704e45f4..1d5e662d8 100644 --- a/apps/esmtool/CMakeLists.txt +++ b/apps/esmtool/CMakeLists.txt @@ -21,7 +21,3 @@ if (BUILD_WITH_CODE_COVERAGE) add_definitions (--coverage) target_link_libraries(esmtool gcov) endif() - -if(MSVC) - target_link_libraries(esmtool imm32.lib winmm.lib version.lib) -endif(MSVC) diff --git a/apps/essimporter/CMakeLists.txt b/apps/essimporter/CMakeLists.txt index 5683a6a86..93f53d0e8 100644 --- a/apps/essimporter/CMakeLists.txt +++ b/apps/essimporter/CMakeLists.txt @@ -46,7 +46,3 @@ endif() if (WIN32) INSTALL(TARGETS openmw-essimporter RUNTIME DESTINATION ".") endif(WIN32) - -if (MSVC) - target_link_libraries(openmw-essimporter imm32.lib winmm.lib version.lib) -endif(MSVC) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 476451d2a..8cbe18d51 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -96,10 +96,6 @@ target_link_libraries(openmw-launcher components ) -if(MSVC) - target_link_libraries(openmw-launcher imm32.lib winmm.lib version.lib) -endif(MSVC) - if (DESIRED_QT_VERSION MATCHES 4) target_link_libraries(openmw-launcher ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY}) if(WIN32) diff --git a/apps/mwiniimporter/CMakeLists.txt b/apps/mwiniimporter/CMakeLists.txt index b0351eb3f..4bd661685 100644 --- a/apps/mwiniimporter/CMakeLists.txt +++ b/apps/mwiniimporter/CMakeLists.txt @@ -25,10 +25,6 @@ if (WIN32) INSTALL(TARGETS openmw-iniimporter RUNTIME DESTINATION ".") endif(WIN32) -if(MSVC) - target_link_libraries(openmw-iniimporter imm32.lib winmm.lib version.lib) -endif(MSVC) - if (MINGW) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") endif() diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 1511a0bc4..acf3cf021 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -232,7 +232,6 @@ if (MSVC) if (CMAKE_CL_64) set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") endif (CMAKE_CL_64) - target_link_libraries(openmw-cs imm32.lib winmm.lib version.lib) endif (MSVC) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index fa2fed3c6..452629fcf 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -201,7 +201,6 @@ if (MSVC) set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") endif (CMAKE_CL_64) add_definitions("-D_USE_MATH_DEFINES") - target_link_libraries(openmw imm32.lib winmm.lib version.lib) endif (MSVC) if (WIN32) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 51faaba1d..3f3e1dbde 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -206,7 +206,7 @@ target_link_libraries(components ${OSGFX_LIBRARIES} ${OSGANIMATION_LIBRARIES} ${Bullet_LIBRARIES} - ${SDL2_LIBRARY} + ${SDL2_LIBRARIES} # For MyGUI platform ${GL_LIB} ${MyGUI_LIBRARIES} From 5e46121046eb045446543663b172dd2a23d3dfec Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Wed, 16 Nov 2016 20:15:25 +0100 Subject: [PATCH 09/10] Implement fleeing AI (Closes #1118) --- apps/openmw/mwbase/world.hpp | 6 + apps/openmw/mwmechanics/aicombat.cpp | 243 +++++++++++--- apps/openmw/mwmechanics/aicombat.hpp | 2 + apps/openmw/mwmechanics/aicombataction.cpp | 302 ++++++++++++++++++ apps/openmw/mwmechanics/aicombataction.hpp | 21 ++ apps/openmw/mwmechanics/combat.cpp | 15 + apps/openmw/mwmechanics/combat.hpp | 1 + .../mwmechanics/mechanicsmanagerimp.cpp | 16 +- apps/openmw/mwworld/class.cpp | 21 +- apps/openmw/mwworld/class.hpp | 2 + apps/openmw/mwworld/worldimp.cpp | 20 +- apps/openmw/mwworld/worldimp.hpp | 6 + 12 files changed, 599 insertions(+), 56 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 0178a3f2b..74bc0b7fd 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -560,6 +560,12 @@ namespace MWBase virtual void removeContainerScripts(const MWWorld::Ptr& reference) = 0; virtual bool isPlayerInJail() const = 0; + + /// Return terrain height at \a worldPos position. + virtual float getTerrainHeightAt(const osg::Vec3f& worldPos) const = 0; + + /// Return physical or rendering half extents of the given actor. + virtual osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor, bool rendering=false) const = 0; }; } diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 2e1dfbac5..80b343d4f 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -18,6 +18,7 @@ #include "character.hpp" #include "aicombataction.hpp" #include "combat.hpp" +#include "coordinateconverter.hpp" namespace { @@ -50,6 +51,19 @@ namespace MWMechanics bool mForceNoShortcut; ESM::Position mShortcutFailPos; MWMechanics::Movement mMovement; + + enum FleeState + { + FleeState_None, + FleeState_Idle, + FleeState_RunBlindly, + FleeState_RunToDestination + }; + FleeState mFleeState; + bool mFleeLOS; + float mFleeUpdateLOSTimer; + float mFleeBlindRunTimer; + ESM::Pathgrid::Point mFleeDest; AiCombatStorage(): mAttackCooldown(0), @@ -66,7 +80,11 @@ namespace MWMechanics mStrength(), mForceNoShortcut(false), mShortcutFailPos(), - mMovement() + mMovement(), + mFleeState(FleeState_None), + mFleeLOS(false), + mFleeUpdateLOSTimer(0.0f), + mFleeBlindRunTimer(0.0f) {} void startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, const MWWorld::Ptr& actor, const MWWorld::Ptr& target); @@ -76,6 +94,10 @@ namespace MWMechanics const ESM::Weapon* weapon, bool distantCombat); void updateAttack(CharacterController& characterController); void stopAttack(); + + void startFleeing(); + void stopFleeing(); + bool isFleeing(); }; AiCombat::AiCombat(const MWWorld::Ptr& actor) : @@ -157,16 +179,23 @@ namespace MWMechanics || target.getClass().getCreatureStats(target).isDead()) return true; - if (storage.mCurrentAction.get()) // need to wait to init action with it's attack range + if (!storage.isFleeing()) { - //Update every frame - bool is_target_reached = pathTo(actor, target.getRefData().getPosition().pos, duration, storage.mAttackRange); - if (is_target_reached) storage.mReadyToAttack = true; - } + if (storage.mCurrentAction.get()) // need to wait to init action with it's attack range + { + //Update every frame + bool is_target_reached = pathTo(actor, target.getRefData().getPosition().pos, duration, storage.mAttackRange); + if (is_target_reached) storage.mReadyToAttack = true; + } - storage.updateCombatMove(duration); - if (storage.mReadyToAttack) updateActorsMovement(actor, duration, storage); - storage.updateAttack(characterController); + storage.updateCombatMove(duration); + if (storage.mReadyToAttack) updateActorsMovement(actor, duration, storage); + storage.updateAttack(characterController); + } + else + { + updateFleeing(actor, target, duration, storage); + } storage.mActionCooldown -= duration; float& timerReact = storage.mTimerReact; @@ -185,12 +214,6 @@ namespace MWMechanics void AiCombat::attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController) { - if (isTargetMagicallyHidden(target)) - { - storage.stopAttack(); - return; // TODO: run away instead of doing nothing - } - const MWWorld::CellStore*& currentCell = storage.mCell; bool cellChange = currentCell && (actor.getCell() != currentCell); if(!currentCell || cellChange) @@ -198,30 +221,61 @@ namespace MWMechanics currentCell = actor.getCell(); } + bool forceFlee = false; + if (!canFight(actor, target)) + { + storage.stopAttack(); + characterController.setAttackingOrSpell(false); + storage.mActionCooldown = 0.f; + forceFlee = true; + } + const MWWorld::Class& actorClass = actor.getClass(); actorClass.getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); float& actionCooldown = storage.mActionCooldown; - if (actionCooldown > 0) - return; - - float &rangeAttack = storage.mAttackRange; boost::shared_ptr& currentAction = storage.mCurrentAction; - if (characterController.readyToPrepareAttack()) + + if (!forceFlee) { - currentAction = prepareNextAction(actor, target); + if (actionCooldown > 0) + return; + + if (characterController.readyToPrepareAttack()) + { + currentAction = prepareNextAction(actor, target); + actionCooldown = currentAction->getActionCooldown(); + } + } + else + { + currentAction.reset(new ActionFlee()); actionCooldown = currentAction->getActionCooldown(); } - const ESM::Weapon *weapon = NULL; - bool isRangedCombat = false; - if (currentAction.get()) + if (!currentAction) + return; + + if (storage.isFleeing() != currentAction->isFleeing()) { - rangeAttack = currentAction->getCombatRange(isRangedCombat); - // Get weapon characteristics - weapon = currentAction->getWeapon(); + if (currentAction->isFleeing()) + { + storage.startFleeing(); + MWBase::Environment::get().getDialogueManager()->say(actor, "flee"); + return; + } + else + storage.stopFleeing(); } + bool isRangedCombat = false; + float &rangeAttack = storage.mAttackRange; + + rangeAttack = currentAction->getCombatRange(isRangedCombat); + + // Get weapon characteristics + const ESM::Weapon* weapon = currentAction->getWeapon(); + ESM::Position pos = actor.getRefData().getPosition(); osg::Vec3f vActorPos(pos.asVec3()); osg::Vec3f vTargetPos(target.getRefData().getPosition().asVec3()); @@ -229,19 +283,7 @@ namespace MWMechanics osg::Vec3f vAimDir = MWBase::Environment::get().getWorld()->aimToTarget(actor, target); float distToTarget = MWBase::Environment::get().getWorld()->getHitDistance(actor, target); - if (!currentAction) - return; - storage.mReadyToAttack = (currentAction->isAttackingOrSpell() && distToTarget <= rangeAttack); - - // can't fight if attacker can't go where target is. E.g. A fish can't attack person on land. - if (distToTarget > rangeAttack - && !actorClass.isNpc() && !MWMechanics::isEnvironmentCompatible(actor, target)) - { - // TODO: start fleeing? - storage.stopAttack(); - return; - } if (storage.mReadyToAttack) { @@ -267,6 +309,106 @@ namespace MWMechanics } } + void MWMechanics::AiCombat::updateFleeing(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, MWMechanics::AiCombatStorage& storage) + { + static const float LOS_UPDATE_DURATION = 0.5f; + static const float BLIND_RUN_DURATION = 1.0f; + + if (storage.mFleeUpdateLOSTimer <= 0.f) + { + storage.mFleeLOS = MWBase::Environment::get().getWorld()->getLOS(actor, target); + storage.mFleeUpdateLOSTimer = LOS_UPDATE_DURATION; + } + else + storage.mFleeUpdateLOSTimer -= duration; + + AiCombatStorage::FleeState& state = storage.mFleeState; + switch (state) + { + case AiCombatStorage::FleeState_None: + return; + + case AiCombatStorage::FleeState_Idle: + { + float triggerDist = getMaxAttackDistance(target); + + if (storage.mFleeLOS && + (triggerDist >= 1000 || getDistanceMinusHalfExtents(actor, target) <= triggerDist)) + { + const ESM::Pathgrid* pathgrid = + MWBase::Environment::get().getWorld()->getStore().get().search(*storage.mCell->getCell()); + + bool runFallback = true; + + if (pathgrid && !actor.getClass().isPureWaterCreature(actor)) + { + ESM::Pathgrid::PointList points; + CoordinateConverter coords(storage.mCell->getCell()); + + osg::Vec3f localPos = actor.getRefData().getPosition().asVec3(); + coords.toLocal(localPos); + + int closestPointIndex = PathFinder::GetClosestPoint(pathgrid, localPos); + for (int i = 0; i < static_cast(pathgrid->mPoints.size()); i++) + { + if (i != closestPointIndex && storage.mCell->isPointConnected(closestPointIndex, i)) + { + points.push_back(pathgrid->mPoints[static_cast(i)]); + } + } + + if (!points.empty()) + { + ESM::Pathgrid::Point dest = points[Misc::Rng::rollDice(points.size())]; + coords.toWorld(dest); + + state = AiCombatStorage::FleeState_RunToDestination; + storage.mFleeDest = ESM::Pathgrid::Point(dest.mX, dest.mY, dest.mZ); + + runFallback = false; + } + } + + if (runFallback) + { + state = AiCombatStorage::FleeState_RunBlindly; + storage.mFleeBlindRunTimer = 0.0f; + } + } + } + break; + + case AiCombatStorage::FleeState_RunBlindly: + { + // timer to prevent twitchy movement that can be observed in vanilla MW + if (storage.mFleeBlindRunTimer < BLIND_RUN_DURATION) + { + storage.mFleeBlindRunTimer += duration; + + storage.mMovement.mRotation[2] = osg::PI + getZAngleToDir(target.getRefData().getPosition().asVec3()-actor.getRefData().getPosition().asVec3()); + storage.mMovement.mPosition[1] = 1; + updateActorsMovement(actor, duration, storage); + } + else + state = AiCombatStorage::FleeState_Idle; + } + break; + + case AiCombatStorage::FleeState_RunToDestination: + { + static const float fFleeDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fFleeDistance")->getFloat(); + + float dist = (actor.getRefData().getPosition().asVec3() - target.getRefData().getPosition().asVec3()).length(); + if ((dist > fFleeDistance && !storage.mFleeLOS) + || pathTo(actor, storage.mFleeDest, duration)) + { + state = AiCombatStorage::FleeState_Idle; + } + } + break; + }; + } + void AiCombat::updateActorsMovement(const MWWorld::Ptr& actor, float duration, AiCombatStorage& storage) { // apply combat movement @@ -446,6 +588,29 @@ namespace MWMechanics mReadyToAttack = false; mAttack = false; } + + void AiCombatStorage::startFleeing() + { + stopFleeing(); + mFleeState = FleeState_Idle; + } + + void AiCombatStorage::stopFleeing() + { + mMovement.mPosition[0] = 0; + mMovement.mPosition[1] = 0; + mMovement.mPosition[2] = 0; + mFleeState = FleeState_None; + mFleeDest = ESM::Pathgrid::Point(0, 0, 0); + mFleeLOS = false; + mFleeUpdateLOSTimer = 0.0f; + mFleeUpdateLOSTimer = 0.0f; + } + + bool AiCombatStorage::isFleeing() + { + return mFleeState != FleeState_None; + } } diff --git a/apps/openmw/mwmechanics/aicombat.hpp b/apps/openmw/mwmechanics/aicombat.hpp index 4be2ac9da..3f2bde776 100644 --- a/apps/openmw/mwmechanics/aicombat.hpp +++ b/apps/openmw/mwmechanics/aicombat.hpp @@ -61,6 +61,8 @@ namespace MWMechanics void attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController); + void updateFleeing(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, AiCombatStorage& storage); + /// Transfer desired movement (from AiCombatStorage) to Actor void updateActorsMovement(const MWWorld::Ptr& actor, float duration, AiCombatStorage& storage); void rotateActorOnAxis(const MWWorld::Ptr& actor, int axis, diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index 094df1db3..437aae277 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -5,14 +5,17 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/actionequip.hpp" +#include "../mwworld/cellstore.hpp" #include "npcstats.hpp" #include "spellcasting.hpp" +#include "combat.hpp" namespace { @@ -517,6 +520,7 @@ namespace MWMechanics Spells& spells = actor.getClass().getCreatureStats(actor).getSpells(); float bestActionRating = 0.f; + float antiFleeRating = 0.f; // Default to hand-to-hand combat boost::shared_ptr bestAction (new ActionWeapon(MWWorld::Ptr())); if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) @@ -536,6 +540,7 @@ namespace MWMechanics { bestActionRating = rating; bestAction.reset(new ActionPotion(*it)); + antiFleeRating = std::numeric_limits::max(); } } @@ -546,6 +551,7 @@ namespace MWMechanics { bestActionRating = rating; bestAction.reset(new ActionEnchantedItem(it)); + antiFleeRating = std::numeric_limits::max(); } } @@ -593,6 +599,7 @@ namespace MWMechanics bestActionRating = rating; bestAction.reset(new ActionWeapon(*it, ammo)); + antiFleeRating = vanillaRateWeaponAndAmmo(*it, ammo, actor, enemy); } } } @@ -606,13 +613,308 @@ namespace MWMechanics { bestActionRating = rating; bestAction.reset(new ActionSpell(spell->mId)); + antiFleeRating = vanillaRateSpell(spell, actor, enemy); } } + if (makeFleeDecision(actor, enemy, antiFleeRating)) + bestAction.reset(new ActionFlee()); + if (bestAction.get()) bestAction->prepare(actor); return bestAction; } + + float getDistanceMinusHalfExtents(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, bool minusZDist) + { + osg::Vec3f actor1Pos = actor1.getRefData().getPosition().asVec3(); + osg::Vec3f actor2Pos = actor2.getRefData().getPosition().asVec3(); + + float dist = (actor1Pos - actor2Pos).length(); + + if (minusZDist) + dist -= std::abs(actor1Pos.z() - actor2Pos.z()); + + return (dist + - MWBase::Environment::get().getWorld()->getHalfExtents(actor1).y() + - MWBase::Environment::get().getWorld()->getHalfExtents(actor2).y()); + } + + float getMaxAttackDistance(const MWWorld::Ptr& actor) + { + const CreatureStats& stats = actor.getClass().getCreatureStats(actor); + const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + + std::string selectedSpellId = stats.getSpells().getSelectedSpell(); + MWWorld::Ptr selectedEnchItem; + + MWWorld::Ptr activeWeapon, activeAmmo; + if (actor.getClass().hasInventoryStore(actor)) + { + MWWorld::InventoryStore& invStore = actor.getClass().getInventoryStore(actor); + + MWWorld::ContainerStoreIterator item = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (item != invStore.end() && item.getType() == MWWorld::ContainerStore::Type_Weapon) + activeWeapon = *item; + + item = invStore.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + if (item != invStore.end() && item.getType() == MWWorld::ContainerStore::Type_Weapon) + activeAmmo = *item; + + if (invStore.getSelectedEnchantItem() != invStore.end()) + selectedEnchItem = *invStore.getSelectedEnchantItem(); + } + + float dist = 1.0f; + if (activeWeapon.isEmpty() && !selectedSpellId.empty() && !selectedEnchItem.isEmpty()) + { + static const float fHandToHandReach = gmst.find("fHandToHandReach")->getFloat(); + dist = fHandToHandReach; + } + else if (stats.getDrawState() == MWMechanics::DrawState_Spell) + { + dist = 1.0f; + if (!selectedSpellId.empty()) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(selectedSpellId); + for (std::vector::const_iterator effectIt = + spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt) + { + if (effectIt->mArea == ESM::RT_Target) + { + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mEffectID); + dist = effect->mData.mSpeed; + break; + } + } + } + else if (!selectedEnchItem.isEmpty()) + { + std::string enchId = selectedEnchItem.getClass().getEnchantment(selectedEnchItem); + if (!enchId.empty()) + { + const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get().find(enchId); + for (std::vector::const_iterator effectIt = + ench->mEffects.mList.begin(); effectIt != ench->mEffects.mList.end(); ++effectIt) + { + if (effectIt->mArea == ESM::RT_Target) + { + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mEffectID); + dist = effect->mData.mSpeed; + break; + } + } + } + } + + static const float fTargetSpellMaxSpeed = gmst.find("fTargetSpellMaxSpeed")->getFloat(); + dist *= std::max(1000.0f, fTargetSpellMaxSpeed); + } + else if (!activeWeapon.isEmpty()) + { + const ESM::Weapon* esmWeap = activeWeapon.get()->mBase; + if (esmWeap->mData.mType >= ESM::Weapon::MarksmanBow) + { + static const float fTargetSpellMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat(); + dist = fTargetSpellMaxSpeed; + if (!activeAmmo.isEmpty()) + { + const ESM::Weapon* esmAmmo = activeAmmo.get()->mBase; + dist *= esmAmmo->mData.mSpeed; + } + } + else if (esmWeap->mData.mReach > 1) + { + dist = esmWeap->mData.mReach; + } + } + + dist = (dist > 0.f) ? dist : 1.0f; + + static const float fCombatDistance = gmst.find("fCombatDistance")->getFloat(); + static const float fCombatDistanceWerewolfMod = gmst.find("fCombatDistanceWerewolfMod")->getFloat(); + + float combatDistance = fCombatDistance; + if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) + combatDistance *= (fCombatDistanceWerewolfMod + 1.0f); + + if (dist < combatDistance) + dist *= combatDistance; + + return dist; + } + + bool canFight(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) + { + ESM::Position actorPos = actor.getRefData().getPosition(); + ESM::Position enemyPos = enemy.getRefData().getPosition(); + + const CreatureStats& enemyStats = enemy.getClass().getCreatureStats(enemy); + if (enemyStats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude() > 0 + || enemyStats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude() > 0) + { + if (!MWBase::Environment::get().getMechanicsManager()->awarenessCheck(enemy, actor)) + return false; + } + + if (actor.getClass().isPureWaterCreature(actor)) + { + if (!MWBase::Environment::get().getWorld()->isWading(enemy)) + return false; + } + + float atDist = getMaxAttackDistance(actor); + if (atDist > getDistanceMinusHalfExtents(actor, enemy) + && atDist > std::abs(actorPos.pos[2] - enemyPos.pos[2])) + { + if (MWBase::Environment::get().getWorld()->getLOS(actor, enemy)) + return true; + } + + if (actor.getClass().isPureFlyingCreature(actor) || actor.getClass().isPureLandCreature(actor)) + { + if (MWBase::Environment::get().getWorld()->isSwimming(enemy)) + return false; + } + + if (actor.getClass().isBipedal(actor) || !actor.getClass().canFly(actor)) + { + if (enemy.getClass().getCreatureStats(enemy).getMagicEffects().get(ESM::MagicEffect::Levitate).getMagnitude() > 0) + { + float attackDistance = getMaxAttackDistance(actor); + if ((attackDistance + actorPos.pos[2]) < enemyPos.pos[2]) + { + if (enemy.getCell()->isExterior()) + { + if (attackDistance < (enemyPos.pos[2] - MWBase::Environment::get().getWorld()->getTerrainHeightAt(enemyPos.asVec3()))) + return false; + } + } + } + } + + if (!actor.getClass().canWalk(actor) && !actor.getClass().isBipedal(actor)) + return true; + + if (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::Levitate).getMagnitude() > 0) + return true; + + if (MWBase::Environment::get().getWorld()->isSwimming(actor)) + return true; + + if (getDistanceMinusHalfExtents(actor, enemy, true) <= 0.0f) + return false; + + return true; + } + + float vanillaRateSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) + { + const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + + static const float fAIMagicSpellMult = gmst.find("fAIMagicSpellMult")->getFloat(); + static const float fAIRangeMagicSpellMult = gmst.find("fAIRangeMagicSpellMult")->getFloat(); + + float mult = fAIMagicSpellMult; + + for (std::vector::const_iterator effectIt = + spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt) + { + if (effectIt->mArea == ESM::RT_Target) + { + if (!MWBase::Environment::get().getWorld()->isSwimming(enemy)) + mult = fAIRangeMagicSpellMult; + else + mult = 0.0f; + break; + } + } + + return MWMechanics::getSpellSuccessChance(spell, actor) * mult; + } + + float vanillaRateWeaponAndAmmo(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) + { + const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + + static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->getFloat(); + static const float fAIMeleeArmorMult = gmst.find("fAIMeleeArmorMult")->getFloat(); + static const float fAIRangeMeleeWeaponMult = gmst.find("fAIRangeMeleeWeaponMult")->getFloat(); + + if (weapon.isEmpty()) + return 0.f; + + float skillMult = actor.getClass().getSkill(actor, weapon.getClass().getEquipmentSkill(weapon)) * 0.01f; + float chopMult = fAIMeleeWeaponMult; + float bonusDamage = 0.f; + + const ESM::Weapon* esmWeap = weapon.get()->mBase; + + if (esmWeap->mData.mType >= ESM::Weapon::MarksmanBow) + { + if (!ammo.isEmpty() && !MWBase::Environment::get().getWorld()->isSwimming(enemy)) + { + bonusDamage = ammo.get()->mBase->mData.mChop[1]; + chopMult = fAIRangeMeleeWeaponMult; + } + else + chopMult = 0.f; + } + + float chopRating = (esmWeap->mData.mChop[1] + bonusDamage) * skillMult * chopMult; + float slashRating = esmWeap->mData.mSlash[1] * skillMult * fAIMeleeWeaponMult; + float thrustRating = esmWeap->mData.mThrust[1] * skillMult * fAIMeleeWeaponMult; + + return actor.getClass().getArmorRating(actor) * fAIMeleeArmorMult + + std::max(std::max(chopRating, slashRating), thrustRating); + } + + float vanillaRateFlee(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) + { + const CreatureStats& stats = actor.getClass().getCreatureStats(actor); + const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + + int flee = stats.getAiSetting(CreatureStats::AI_Flee).getModified(); + if (flee >= 100) + return flee; + + static const float fAIFleeHealthMult = gmst.find("fAIFleeHealthMult")->getFloat(); + static const float fAIFleeFleeMult = gmst.find("fAIFleeFleeMult")->getFloat(); + + float healthPercentage = (stats.getHealth().getModified() == 0.0f) + ? 1.0f : stats.getHealth().getCurrent() / stats.getHealth().getModified(); + float rating = (1.0f - healthPercentage) * fAIFleeHealthMult + flee * fAIFleeFleeMult; + + static const int iWereWolfLevelToAttack = gmst.find("iWereWolfLevelToAttack")->getInt(); + + if (enemy.getClass().isNpc() && enemy.getClass().getNpcStats(enemy).isWerewolf() && stats.getLevel() < iWereWolfLevelToAttack) + { + static const int iWereWolfFleeMod = gmst.find("iWereWolfFleeMod")->getInt(); + rating = iWereWolfFleeMod; + } + + if (rating != 0.0f) + rating += getFightDistanceBias(actor, enemy); + + return rating; + } + + bool makeFleeDecision(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, float antiFleeRating) + { + float fleeRating = vanillaRateFlee(actor, enemy); + if (fleeRating < 100.0f) + fleeRating = 0.0f; + + if (fleeRating > antiFleeRating) + return true; + + // Run away after summoning a creature if we have nothing to use but fists. + if (antiFleeRating == 0.0f && !actor.getClass().getCreatureStats(actor).getSummonedCreatureMap().empty()) + return true; + + return false; + } + } diff --git a/apps/openmw/mwmechanics/aicombataction.hpp b/apps/openmw/mwmechanics/aicombataction.hpp index b36413587..0f1f7dd5b 100644 --- a/apps/openmw/mwmechanics/aicombataction.hpp +++ b/apps/openmw/mwmechanics/aicombataction.hpp @@ -20,6 +20,18 @@ namespace MWMechanics virtual float getActionCooldown() { return 0.f; } virtual const ESM::Weapon* getWeapon() const { return NULL; }; virtual bool isAttackingOrSpell() const { return true; } + virtual bool isFleeing() const { return false; } + }; + + class ActionFlee : public Action + { + public: + ActionFlee() {} + virtual void prepare(const MWWorld::Ptr& actor) {} + virtual float getCombatRange (bool& isRanged) const { return 0.0f; } + virtual float getActionCooldown() { return 3.0f; } + virtual bool isAttackingOrSpell() const { return false; } + virtual bool isFleeing() const { return true; } }; class ActionSpell : public Action @@ -89,6 +101,15 @@ namespace MWMechanics float rateEffects (const ESM::EffectList& list, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); boost::shared_ptr prepareNextAction (const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + + float getDistanceMinusHalfExtents(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool minusZDist=false); + float getMaxAttackDistance(const MWWorld::Ptr& actor); + bool canFight(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + + float vanillaRateSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + float vanillaRateWeaponAndAmmo(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + float vanillaRateFlee(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + bool makeFleeDecision(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, float antiFleeRating); } #endif diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index b454f8e3a..41d8b9595 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -431,4 +431,19 @@ namespace MWMechanics return true; } + + float getFightDistanceBias(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2) + { + osg::Vec3f pos1 (actor1.getRefData().getPosition().asVec3()); + osg::Vec3f pos2 (actor2.getRefData().getPosition().asVec3()); + + float d = (pos1 - pos2).length(); + + static const int iFightDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find( + "iFightDistanceBase")->getInt(); + static const float fFightDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore().get().find( + "fFightDistanceMultiplier")->getFloat(); + + return (iFightDistanceBase - fFightDistanceMultiplier * d); + } } diff --git a/apps/openmw/mwmechanics/combat.hpp b/apps/openmw/mwmechanics/combat.hpp index 7d0b3b78f..3f733763a 100644 --- a/apps/openmw/mwmechanics/combat.hpp +++ b/apps/openmw/mwmechanics/combat.hpp @@ -42,6 +42,7 @@ void applyFatigueLoss(const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, /// e.g. If attacker is a fish, is victim in water? Or, if attacker can't swim, is victim on land? bool isEnvironmentCompatible(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim); +float getFightDistanceBias(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2); } #endif diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index b10127f74..9661a9b3a 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -25,25 +25,11 @@ #include "autocalcspell.hpp" #include "npcstats.hpp" #include "actorutil.hpp" +#include "combat.hpp" namespace { - float getFightDistanceBias(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2) - { - osg::Vec3f pos1 (actor1.getRefData().getPosition().asVec3()); - osg::Vec3f pos2 (actor2.getRefData().getPosition().asVec3()); - - float d = (pos1 - pos2).length(); - - static const int iFightDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find( - "iFightDistanceBase")->getInt(); - static const float fFightDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore().get().find( - "fFightDistanceMultiplier")->getFloat(); - - return (iFightDistanceBase - fFightDistanceMultiplier * d); - } - float getFightDispositionBias(float disposition) { static const float fFightDispMult = MWBase::Environment::get().getWorld()->getStore().get().find( diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index d04252a2c..96a56fe39 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -393,7 +393,26 @@ namespace MWWorld bool Class::isPureWaterCreature(const MWWorld::Ptr& ptr) const { - return canSwim(ptr) && !canWalk(ptr); + return canSwim(ptr) + && !isBipedal(ptr) + && !canFly(ptr) + && !canWalk(ptr); + } + + bool Class::isPureFlyingCreature(const Ptr& ptr) const + { + return canFly(ptr) + && !isBipedal(ptr) + && !canSwim(ptr) + && !canWalk(ptr); + } + + bool Class::isPureLandCreature(const Ptr& ptr) const + { + return canWalk(ptr) + && !isBipedal(ptr) + && !canFly(ptr) + && !canSwim(ptr); } bool Class::isMobile(const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 8d3f9b891..06deedc53 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -312,6 +312,8 @@ namespace MWWorld virtual bool canSwim(const MWWorld::ConstPtr& ptr) const; virtual bool canWalk(const MWWorld::ConstPtr& ptr) const; bool isPureWaterCreature(const MWWorld::Ptr& ptr) const; + bool isPureFlyingCreature(const MWWorld::Ptr& ptr) const; + bool isPureLandCreature(const MWWorld::Ptr& ptr) const; bool isMobile(const MWWorld::Ptr& ptr) const; virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index fce3d69db..028cc45c9 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -421,11 +421,16 @@ namespace MWWorld gmst["sBribeFail"] = ESM::Variant("Bribe Fail"); gmst["fNPCHealthBarTime"] = ESM::Variant(5.f); gmst["fNPCHealthBarFade"] = ESM::Variant(1.f); + gmst["fFleeDistance"] = ESM::Variant(3000.f); // Werewolf (BM) gmst["fWereWolfRunMult"] = ESM::Variant(1.f); gmst["fWereWolfSilverWeaponDamageMult"] = ESM::Variant(1.f); gmst["iWerewolfFightMod"] = ESM::Variant(1); + gmst["iWereWolfFleeMod"] = ESM::Variant(100); + gmst["iWereWolfLevelToAttack"] = ESM::Variant(20); + gmst["iWereWolfBounty"] = ESM::Variant(10000); + gmst["fCombatDistanceWerewolfMod"] = ESM::Variant(0.3f); std::map globals; // vanilla Morrowind does not define dayspassed. @@ -1295,7 +1300,7 @@ namespace MWWorld float terrainHeight = -std::numeric_limits::max(); if (ptr.getCell()->isExterior()) - terrainHeight = mRendering->getTerrainHeightAt(pos.asVec3()); + terrainHeight = getTerrainHeightAt(pos.asVec3()); if (pos.pos[2] < terrainHeight) pos.pos[2] = terrainHeight; @@ -3121,6 +3126,19 @@ namespace MWWorld return MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Jail); } + float World::getTerrainHeightAt(const osg::Vec3f& worldPos) const + { + return mRendering->getTerrainHeightAt(worldPos); + } + + osg::Vec3f World::getHalfExtents(const ConstPtr& actor, bool rendering) const + { + if (rendering) + return mPhysics->getRenderingHalfExtents(actor); + else + return mPhysics->getHalfExtents(actor); + } + void World::spawnRandomCreature(const std::string &creatureList) { const ESM::CreatureLevList* list = getStore().get().find(creatureList); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index a5e250452..a9d3f3397 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -661,6 +661,12 @@ namespace MWWorld virtual float getHitDistance(const MWWorld::ConstPtr& actor, const MWWorld::ConstPtr& target); virtual bool isPlayerInJail() const; + + /// Return terrain height at \a worldPos position. + virtual float getTerrainHeightAt(const osg::Vec3f& worldPos) const; + + /// Return physical or rendering half extents of the given actor. + virtual osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor, bool rendering=false) const; }; } From 2368382ea53d57a1811416f25b69607d891c07c0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 17 Nov 2016 17:51:55 +0100 Subject: [PATCH 10/10] Fix upside down rain particle texture --- apps/openmw/mwrender/sky.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index b12f4510b..fba5f17b2 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -1329,7 +1329,7 @@ void SkyManager::createRain() mRainParticleSystem = new osgParticle::ParticleSystem; mRainParticleSystem->setParticleAlignment(osgParticle::ParticleSystem::FIXED); mRainParticleSystem->setAlignVectorX(osg::Vec3f(0.1,0,0)); - mRainParticleSystem->setAlignVectorY(osg::Vec3f(0,0,-1)); + mRainParticleSystem->setAlignVectorY(osg::Vec3f(0,0,1)); osg::ref_ptr stateset (mRainParticleSystem->getOrCreateStateSet());