forked from mirror/openmw-tes3mp
Merge branch 'master' of https://github.com/OpenMW/openmw into osg
Conflicts: apps/opencs/model/doc/document.cpp apps/opencs/model/doc/documentmanager.cpp components/CMakeLists.txt components/bsa/resources.cpp components/nif/data.hpp components/nif/node.cpp components/nifogre/mesh.hpp components/nifogre/ogrenifloader.cpp components/nifogre/particles.cpp
This commit is contained in:
commit
236d628884
480 changed files with 5184 additions and 3591 deletions
12
.travis.yml
12
.travis.yml
|
@ -21,6 +21,14 @@ addons:
|
|||
build_command_prepend: "cmake ."
|
||||
build_command: "make -j3"
|
||||
branch_pattern: coverity_scan
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
env:
|
||||
ANALYZE="scan-build-3.6 --use-cc clang-3.6 --use-c++ clang++-3.6 "
|
||||
compiler: clang
|
||||
allow_failures:
|
||||
- env: ANALYZE="scan-build-3.6 --use-cc clang-3.6 --use-c++ clang++-3.6 "
|
||||
|
||||
before_install:
|
||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_install.linux.sh; fi
|
||||
|
@ -30,8 +38,8 @@ before_script:
|
|||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi
|
||||
script:
|
||||
- cd ./build
|
||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make -j4; fi
|
||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && ["${TRAVIS_OS_NAME}" = "osx"]; then make package; fi
|
||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j4; fi
|
||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
|
||||
after_script:
|
||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
|
||||
notifications:
|
||||
|
|
|
@ -39,6 +39,8 @@ Programmers
|
|||
Eli2
|
||||
Emanuel Guével (potatoesmaster)
|
||||
eroen
|
||||
escondida
|
||||
Evgeniy Mineev (sandstranger)
|
||||
Fil Krynicki (filkry)
|
||||
Gašper Sedej
|
||||
gugus/gus
|
||||
|
@ -91,7 +93,6 @@ Programmers
|
|||
Rohit Nirmal
|
||||
Roman Melnik (Kromgart)
|
||||
Roman Proskuryakov (humbug)
|
||||
sandstranger
|
||||
Sandy Carter (bwrsandman)
|
||||
Scott Howard
|
||||
Sebastian Wick (swick)
|
||||
|
|
39
CHANGELOG.md
39
CHANGELOG.md
|
@ -1,3 +1,42 @@
|
|||
0.35.1
|
||||
------
|
||||
|
||||
Bug #781: incorrect trajectory of the sun
|
||||
Bug #1079: Wrong starting position in "Character Stuff Wonderland"
|
||||
Bug #1443: Repetitive taking of a stolen object is repetitively considered as a crime
|
||||
Bug #1533: Divine Intervention goes to the wrong place.
|
||||
Bug #1714: No visual indicator for time passed during training
|
||||
Bug #1916: Telekinesis does not allow safe opening of traps
|
||||
Bug #2227: Editor: addon file name inconsistency
|
||||
Bug #2271: Player can melee enemies from water with impunity
|
||||
Bug #2275: Objects with bigger scale move further using Move script
|
||||
Bug #2285: Aryon's Dominator enchantment does not work properly
|
||||
Bug #2290: No punishment for stealing gold from owned containers
|
||||
Bug #2328: Launcher does not respond to Ctrl+C
|
||||
Bug #2334: Drag-and-drop on a content file in the launcher creates duplicate items
|
||||
Bug #2338: Arrows reclaimed from corpses do not stack sometimes
|
||||
Bug #2344: Launcher - Settings importer running correctly?
|
||||
Bug #2346: Launcher - Importing plugins into content list screws up the load order
|
||||
Bug #2348: Mod: H.E.L.L.U.V.A. Handy Holdables does not appear in the content list
|
||||
Bug #2353: Detect Animal detects dead creatures
|
||||
Bug #2354: Cmake does not respect LIB_SUFFIX
|
||||
Bug #2356: Active magic set inactive when switching magic items
|
||||
Bug #2361: ERROR: ESM Error: Previous record contains unread bytes
|
||||
Bug #2382: Switching spells with "next spell" or "previous spell" while holding shift promps delete spell dialog
|
||||
Bug #2388: Regression: Can't toggle map on/off
|
||||
Bug #2392: MOD Shrines - Restore Health and Cancel Options adds 100 health points
|
||||
Bug #2394: List of Data Files tab in openmw-laucher needs to show all content files.
|
||||
Bug #2402: Editor: skills saved incorrectly
|
||||
Bug #2408: Equipping a constant effect Restore Health/Magicka/Fatigue item will permanently boost the stat it's restoring
|
||||
Bug #2415: It is now possible to fall off the prison ship into the water when starting a new game
|
||||
Bug #2419: MOD MCA crash to desktop
|
||||
Bug #2420: Game crashes when character enters a certain area
|
||||
Bug #2421: infinite loop when using cycle weapon without having a weapon
|
||||
Feature #2221: Cannot dress dead NPCs
|
||||
Feature #2349: Check CMake sets correct MSVC compiler settings for release build.
|
||||
Feature #2397: Set default values for global mandatory records.
|
||||
Feature #2412: Basic joystick support
|
||||
|
||||
0.35.0
|
||||
------
|
||||
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
export CXX=g++
|
||||
export CC=gcc
|
||||
if [ "${ANALYZE}" ]; then
|
||||
if [ $(lsb_release -sc) = "precise" ]; then
|
||||
echo "yes" | sudo apt-add-repository ppa:ubuntu-toolchain-r/test
|
||||
fi
|
||||
echo "yes" | sudo add-apt-repository "deb http://llvm.org/apt/`lsb_release -sc`/ llvm-toolchain-`lsb_release -sc`-3.6 main"
|
||||
wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add -
|
||||
fi
|
||||
|
||||
echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
|
||||
echo "yes" | sudo apt-add-repository ppa:openmw/openmw
|
||||
|
@ -10,6 +15,7 @@ sudo apt-get install -qq libgtest-dev google-mock
|
|||
sudo apt-get install -qq libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev libboost-wave-dev
|
||||
sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev
|
||||
sudo apt-get install -qq libbullet-dev libogre-1.9-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev
|
||||
if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi
|
||||
sudo mkdir /usr/src/gtest/build
|
||||
cd /usr/src/gtest/build
|
||||
sudo cmake .. -DBUILD_SHARED_LIBS=1
|
||||
|
|
|
@ -2,4 +2,6 @@
|
|||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1 -DCMAKE_INSTALL_PREFIX=/usr -DBINDIR=/usr/games -DCMAKE_BUILD_TYPE="RelWithDebInfo" -DUSE_SYSTEM_TINYXML=TRUE
|
||||
export CODE_COVERAGE=1
|
||||
if [ "${CC}" = "clang" ]; then export CODE_COVERAGE=0; fi
|
||||
${ANALYZE}cmake .. -DBUILD_WITH_CODE_COVERAGE=${CODE_COVERAGE} -DBUILD_UNITTESTS=1 -DCMAKE_INSTALL_PREFIX=/usr -DBINDIR=/usr/games -DCMAKE_BUILD_TYPE="RelWithDebInfo" -DUSE_SYSTEM_TINYXML=TRUE
|
||||
|
|
112
CMakeLists.txt
112
CMakeLists.txt
|
@ -20,7 +20,7 @@ message(STATUS "Configuring OpenMW...")
|
|||
|
||||
set(OPENMW_VERSION_MAJOR 0)
|
||||
set(OPENMW_VERSION_MINOR 35)
|
||||
set(OPENMW_VERSION_RELEASE 0)
|
||||
set(OPENMW_VERSION_RELEASE 1)
|
||||
|
||||
set(OPENMW_VERSION_COMMITHASH "")
|
||||
set(OPENMW_VERSION_TAGHASH "")
|
||||
|
@ -98,43 +98,6 @@ endif()
|
|||
# We probably support older versions than this.
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
# source directory: libs
|
||||
|
||||
set(LIBS_DIR ${CMAKE_SOURCE_DIR}/libs)
|
||||
|
||||
set(OENGINE_OGRE
|
||||
${LIBS_DIR}/openengine/ogre/renderer.cpp
|
||||
${LIBS_DIR}/openengine/ogre/lights.cpp
|
||||
${LIBS_DIR}/openengine/ogre/selectionbuffer.cpp
|
||||
${LIBS_DIR}/openengine/ogre/imagerotate.cpp
|
||||
)
|
||||
|
||||
set(OENGINE_GUI
|
||||
${LIBS_DIR}/openengine/gui/loglistener.cpp
|
||||
${LIBS_DIR}/openengine/gui/manager.cpp
|
||||
${LIBS_DIR}/openengine/gui/layout.cpp
|
||||
)
|
||||
|
||||
set(OENGINE_BULLET
|
||||
${LIBS_DIR}/openengine/bullet/BtOgre.cpp
|
||||
${LIBS_DIR}/openengine/bullet/BtOgreExtras.h
|
||||
${LIBS_DIR}/openengine/bullet/BtOgreGP.h
|
||||
${LIBS_DIR}/openengine/bullet/BtOgrePG.h
|
||||
${LIBS_DIR}/openengine/bullet/physic.cpp
|
||||
${LIBS_DIR}/openengine/bullet/physic.hpp
|
||||
${LIBS_DIR}/openengine/bullet/BulletShapeLoader.cpp
|
||||
${LIBS_DIR}/openengine/bullet/BulletShapeLoader.h
|
||||
${LIBS_DIR}/openengine/bullet/trace.cpp
|
||||
${LIBS_DIR}/openengine/bullet/trace.h
|
||||
|
||||
)
|
||||
|
||||
set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET})
|
||||
source_group(libs\\openengine FILES ${OENGINE_ALL})
|
||||
|
||||
set(OPENMW_LIBS ${OENGINE_ALL})
|
||||
set(OPENMW_LIBS_HEADER)
|
||||
|
||||
# Sound setup
|
||||
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE)
|
||||
unset(FFMPEG_LIBRARIES CACHE)
|
||||
|
@ -270,7 +233,8 @@ endif ()
|
|||
endif(WIN32)
|
||||
endif(OGRE_STATIC)
|
||||
|
||||
include_directories("."
|
||||
include_directories("." ${LIBS_DIR}
|
||||
SYSTEM
|
||||
${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS}
|
||||
${OGRE_INCLUDE_DIR}/Overlay ${OGRE_Overlay_INCLUDE_DIR}
|
||||
${SDL2_INCLUDE_DIR}
|
||||
|
@ -279,7 +243,7 @@ include_directories("."
|
|||
${MYGUI_INCLUDE_DIRS}
|
||||
${MYGUI_PLATFORM_INCLUDE_DIRS}
|
||||
${OPENAL_INCLUDE_DIR}
|
||||
${LIBS_DIR}
|
||||
${BULLET_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
|
||||
|
@ -379,6 +343,9 @@ configure_file(${OpenMW_SOURCE_DIR}/files/opencs.ini
|
|||
configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters
|
||||
"${OpenMW_BINARY_DIR}/resources/defaultfilters" COPYONLY)
|
||||
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/gamecontrollerdb.txt
|
||||
"${OpenMW_BINARY_DIR}/gamecontrollerdb.txt")
|
||||
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
||||
"${OpenMW_BINARY_DIR}/openmw.desktop")
|
||||
|
@ -386,22 +353,22 @@ if (NOT WIN32 AND NOT APPLE)
|
|||
"${OpenMW_BINARY_DIR}/openmw-cs.desktop")
|
||||
endif()
|
||||
|
||||
# Compiler settings
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
SET(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}")
|
||||
# CXX Compiler settings
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long")
|
||||
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||
SET(CMAKE_CXX_FLAGS "-Wno-unused-but-set-parameter ${CMAKE_CXX_FLAGS}")
|
||||
endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND "${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-but-set-parameter")
|
||||
endif(CMAKE_CXX_COMPILER_ID STREQUAL GNU AND "${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||
elseif (MSVC)
|
||||
# Enable link-time code generation globally for all linking
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
endif (CMAKE_COMPILER_IS_GNUCC)
|
||||
endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
|
||||
IF(NOT WIN32 AND NOT APPLE)
|
||||
# Linux building
|
||||
|
@ -468,6 +435,8 @@ IF(NOT WIN32 AND NOT APPLE)
|
|||
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
|
||||
IF(BUILD_OPENCS)
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs")
|
||||
ENDIF(BUILD_OPENCS)
|
||||
|
@ -488,6 +457,7 @@ if(WIN32)
|
|||
"${OpenMW_SOURCE_DIR}/Docs/license/DejaVu Font License.txt"
|
||||
"${OpenMW_BINARY_DIR}/settings-default.cfg"
|
||||
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
|
||||
"${OpenMW_BINARY_DIR}/gamecontrollerdb.txt"
|
||||
"${OpenMW_BINARY_DIR}/Release/openmw.exe"
|
||||
DESTINATION ".")
|
||||
|
||||
|
@ -572,6 +542,10 @@ if(WIN32)
|
|||
include(CPack)
|
||||
endif(WIN32)
|
||||
|
||||
# Libs
|
||||
include_directories(libs)
|
||||
add_subdirectory(libs/openengine)
|
||||
|
||||
# Extern
|
||||
#add_subdirectory (extern/shiny)
|
||||
#add_subdirectory (extern/ogre-ffmpeg-videoplayer)
|
||||
|
@ -682,6 +656,7 @@ if (WIN32)
|
|||
4193 # #pragma warning(pop) : no matching '#pragma warning(push)'
|
||||
4251 # class 'XXXX' needs to have dll-interface to be used by clients of class 'YYYY'
|
||||
4275 # non dll-interface struct 'XXXX' used as base for dll-interface class 'YYYY'
|
||||
4315 # undocumented, 'this' pointer for member might not be aligned (OgreMemoryStlAllocator.h)
|
||||
|
||||
# caused by boost
|
||||
4191 # 'type cast' : unsafe conversion (1.56, thread_primitives.hpp, normally off)
|
||||
|
@ -689,6 +664,7 @@ if (WIN32)
|
|||
# OpenMW specific warnings
|
||||
4099 # Type mismatch, declared class or struct is defined with other type
|
||||
4100 # Unreferenced formal parameter (-Wunused-parameter)
|
||||
4101 # Unreferenced local variable (-Wunused-variable)
|
||||
4127 # Conditional expression is constant
|
||||
4242 # Storing value in a variable of a smaller type, possible loss of data
|
||||
4244 # Storing value of one type in variable of another (size_t in int, for example)
|
||||
|
@ -707,56 +683,23 @@ if (WIN32)
|
|||
set(WARNINGS "${WARNINGS} /wd${d}")
|
||||
endforeach(d)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNINGS} ${MT_BUILD}")
|
||||
|
||||
# boost::wave has a few issues with signed / unsigned conversions, so we suppress those here
|
||||
set(SHINY_WARNINGS "${WARNINGS} /wd4245")
|
||||
set_target_properties(shiny PROPERTIES COMPILE_FLAGS "${SHINY_WARNINGS} ${MT_BUILD}")
|
||||
# there's an unreferenced local variable in the ogre platform, suppress it
|
||||
set(SHINY_OGRE_WARNINGS "${WARNINGS} /wd4101")
|
||||
set_target_properties(shiny.OgrePlatform PROPERTIES COMPILE_FLAGS "${SHINY_OGRE_WARNINGS} ${MT_BUILD}")
|
||||
set_target_properties(sdl4ogre PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
|
||||
# oics uses tinyxml, which has an initialized but unused variable
|
||||
set(OICS_WARNINGS "${WARNINGS} /wd4189")
|
||||
set_target_properties(oics PROPERTIES COMPILE_FLAGS "${OICS_WARNINGS} ${MT_BUILD}")
|
||||
set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
if (BUILD_LAUNCHER)
|
||||
set_target_properties(openmw-launcher PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_LAUNCHER)
|
||||
set_target_properties(openmw PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
if (BUILD_BSATOOL)
|
||||
set_target_properties(bsatool PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_BSATOOL)
|
||||
if (BUILD_ESMTOOL)
|
||||
set_target_properties(esmtool PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_ESMTOOL)
|
||||
if (BUILD_WIZARD)
|
||||
set_target_properties(openmw-wizard PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
endif (BUILD_WIZARD)
|
||||
|
||||
if (BUILD_OPENCS)
|
||||
# QT triggers an informational warning that the object layout may differ when compiled with /vd2
|
||||
set(OPENCS_WARNINGS "${WARNINGS} ${MT_BUILD} /wd4435")
|
||||
set_target_properties(openmw-cs PROPERTIES COMPILE_FLAGS ${OPENCS_WARNINGS})
|
||||
endif (BUILD_OPENCS)
|
||||
if (BUILD_MWINIIMPORTER)
|
||||
set_target_properties(openmw-iniimporter PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_MWINIIMPORTER)
|
||||
endif(MSVC)
|
||||
|
||||
# Same for MinGW
|
||||
if (MINGW)
|
||||
if (USE_DEBUG_CONSOLE)
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_DEBUG "-Wl,-subsystem,console")
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_RELWITHDEBINFO "-Wl,-subsystem,console")
|
||||
set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE")
|
||||
else(USE_DEBUG_CONSOLE)
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_DEBUG "-Wl,-subsystem,windows")
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_RELWITHDEBINFO "-Wl,-subsystem,windows")
|
||||
endif(USE_DEBUG_CONSOLE)
|
||||
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "-Wl,-subsystem,console")
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "-Wl,-subsystem,console")
|
||||
set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS_RELEASE "_CONSOLE")
|
||||
endif(MINGW)
|
||||
|
||||
# TODO: At some point release builds should not use the console but rather write to a log file
|
||||
#set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
||||
#set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
|
||||
|
@ -770,6 +713,7 @@ if (APPLE)
|
|||
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}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
|
||||
|
|
10
README.md
10
README.md
|
@ -6,7 +6,7 @@ OpenMW
|
|||
OpenMW is an attempt at recreating the engine for the popular role-playing game
|
||||
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
|
||||
|
||||
* Version: 0.35.0
|
||||
* Version: 0.35.1
|
||||
* License: GPL (see docs/license/GPL3.txt for more information)
|
||||
* Website: http://www.openmw.org
|
||||
* IRC: #openmw on irc.freenode.net
|
||||
|
@ -23,7 +23,7 @@ Getting Started
|
|||
* [Testing the game](https://wiki.openmw.org/index.php?title=Testing)
|
||||
* [How to contribute](https://wiki.openmw.org/index.php?title=Contribution_Wanted)
|
||||
* [Report a bug](http://bugs.openmw.org/projects/openmw) - read the [guidelines](https://wiki.openmw.org/index.php?title=Bug_Reporting_Guidelines) before submitting your first bug!
|
||||
* [Known issues] (http://bugs.openmw.org/projects/openmw/issues?utf8=%E2%9C%93&set_filter=1&f%5B%5D=status_id&op%5Bstatus_id%5D=%3D&v%5Bstatus_id%5D%5B%5D=7&f%5B%5D=tracker_id&op%5Btracker_id%5D=%3D&v%5Btracker_id%5D%5B%5D=1&f%5B%5D=&c%5B%5D=project&c%5B%5D=tracker&c%5B%5D=status&c%5B%5D=priority&c%5B%5D=subject&c%5B%5D=assigned_to&c%5B%5D=updated_on&group_by=tracker)
|
||||
* [Known issues](http://bugs.openmw.org/projects/openmw/issues?utf8=%E2%9C%93&set_filter=1&f%5B%5D=status_id&op%5Bstatus_id%5D=%3D&v%5Bstatus_id%5D%5B%5D=7&f%5B%5D=tracker_id&op%5Btracker_id%5D=%3D&v%5Btracker_id%5D%5B%5D=1&f%5B%5D=&c%5B%5D=project&c%5B%5D=tracker&c%5B%5D=status&c%5B%5D=priority&c%5B%5D=subject&c%5B%5D=assigned_to&c%5B%5D=updated_on&group_by=tracker)
|
||||
|
||||
The data path
|
||||
-------------
|
||||
|
@ -68,9 +68,9 @@ Command line options
|
|||
of the blacklist is enabled)
|
||||
--script-blacklist-use [=arg(=1)] (=1)
|
||||
enable script blacklisting
|
||||
--load-savegame arg load a save game file on game startup
|
||||
(specify an absolute filename or a
|
||||
filename relative to the current
|
||||
--load-savegame arg load a save game file on game startup
|
||||
(specify an absolute filename or a
|
||||
filename relative to the current
|
||||
working directory)
|
||||
--skip-menu [=arg(=1)] (=0) skip main menu on game startup
|
||||
--new-game [=arg(=1)] (=0) run new game sequence (ignored if
|
||||
|
|
|
@ -461,7 +461,7 @@ int clone(Arguments& info)
|
|||
for (Stats::iterator it = stats.begin(); it != stats.end(); ++it)
|
||||
{
|
||||
name.val = it->first;
|
||||
float amount = it->second;
|
||||
int amount = it->second;
|
||||
std::cout << std::setw(digitCount) << amount << " " << name.toString() << " ";
|
||||
|
||||
if (++i % 3 == 0)
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void printAIPackage(ESM::AIPackage p)
|
||||
{
|
||||
std::cout << " AI Type: " << aiTypeLabel(p.mType)
|
||||
|
@ -16,7 +19,7 @@ void printAIPackage(ESM::AIPackage p)
|
|||
std::cout << " Duration: " << p.mWander.mDuration << std::endl;
|
||||
std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl;
|
||||
if (p.mWander.mShouldRepeat != 1)
|
||||
std::cout << " Should repeat: " << (bool)p.mWander.mShouldRepeat << std::endl;
|
||||
std::cout << " Should repeat: " << (bool)(p.mWander.mShouldRepeat != 0) << std::endl;
|
||||
|
||||
std::cout << " Idle: ";
|
||||
for (int i = 0; i != 8; i++)
|
||||
|
@ -149,6 +152,26 @@ void printEffectList(ESM::EffectList effects)
|
|||
}
|
||||
}
|
||||
|
||||
void printTransport(const std::vector<ESM::Transport::Dest>& transport)
|
||||
{
|
||||
std::vector<ESM::Transport::Dest>::const_iterator dit;
|
||||
for (dit = transport.begin(); dit != transport.end(); ++dit)
|
||||
{
|
||||
std::cout << " Destination Position: "
|
||||
<< boost::format("%12.3f") % dit->mPos.pos[0] << ","
|
||||
<< boost::format("%12.3f") % dit->mPos.pos[1] << ","
|
||||
<< boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl;
|
||||
std::cout << " Destination Rotation: "
|
||||
<< boost::format("%9.6f") % dit->mPos.rot[0] << ","
|
||||
<< boost::format("%9.6f") % dit->mPos.rot[1] << ","
|
||||
<< boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl;
|
||||
if (dit->mCellName != "")
|
||||
std::cout << " Destination Cell: " << dit->mCellName << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace EsmTool {
|
||||
|
||||
RecordBase *
|
||||
|
@ -631,6 +654,8 @@ void Record<ESM::Creature>::print()
|
|||
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
|
||||
std::cout << " Spell: " << *sit << std::endl;
|
||||
|
||||
printTransport(mData.getTransport());
|
||||
|
||||
std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl;
|
||||
std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl;
|
||||
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
|
||||
|
@ -1042,20 +1067,7 @@ void Record<ESM::NPC>::print()
|
|||
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
|
||||
std::cout << " Spell: " << *sit << std::endl;
|
||||
|
||||
std::vector<ESM::NPC::Dest>::iterator dit;
|
||||
for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); ++dit)
|
||||
{
|
||||
std::cout << " Destination Position: "
|
||||
<< boost::format("%12.3f") % dit->mPos.pos[0] << ","
|
||||
<< boost::format("%12.3f") % dit->mPos.pos[1] << ","
|
||||
<< boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl;
|
||||
std::cout << " Destination Rotation: "
|
||||
<< boost::format("%9.6f") % dit->mPos.rot[0] << ","
|
||||
<< boost::format("%9.6f") % dit->mPos.rot[1] << ","
|
||||
<< boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl;
|
||||
if (dit->mCellName != "")
|
||||
std::cout << " Destination Cell: " << dit->mCellName << std::endl;
|
||||
}
|
||||
printTransport(mData.getTransport());
|
||||
|
||||
std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl;
|
||||
std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl;
|
||||
|
@ -1253,7 +1265,7 @@ void Record<ESM::Spell>::print()
|
|||
template<>
|
||||
void Record<ESM::StartScript>::print()
|
||||
{
|
||||
std::cout << "Start Script: " << mData.mScript << std::endl;
|
||||
std::cout << "Start Script: " << mData.mId << std::endl;
|
||||
std::cout << "Start Data: " << mData.mData << std::endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,18 +23,18 @@ namespace ESSImport
|
|||
}
|
||||
for (int i=0; i<8; ++i)
|
||||
{
|
||||
cStats.mAttributes[i].mBase = acdt.mAttributes[i][1];
|
||||
cStats.mAttributes[i].mMod = acdt.mAttributes[i][0];
|
||||
cStats.mAttributes[i].mCurrent = acdt.mAttributes[i][0];
|
||||
cStats.mAttributes[i].mBase = static_cast<int>(acdt.mAttributes[i][1]);
|
||||
cStats.mAttributes[i].mMod = static_cast<int>(acdt.mAttributes[i][0]);
|
||||
cStats.mAttributes[i].mCurrent = static_cast<int>(acdt.mAttributes[i][0]);
|
||||
}
|
||||
cStats.mGoldPool = acdt.mGoldPool;
|
||||
cStats.mTalkedTo = acdt.mFlags & TalkedToPlayer;
|
||||
cStats.mAttacked = acdt.mFlags & Attacked;
|
||||
cStats.mTalkedTo = (acdt.mFlags & TalkedToPlayer) != 0;
|
||||
cStats.mAttacked = (acdt.mFlags & Attacked) != 0;
|
||||
}
|
||||
|
||||
void convertACSC (const ACSC& acsc, ESM::CreatureStats& cStats)
|
||||
{
|
||||
cStats.mDead = acsc.mFlags & Dead;
|
||||
cStats.mDead = (acsc.mFlags & Dead) != 0;
|
||||
}
|
||||
|
||||
void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats)
|
||||
|
|
|
@ -553,7 +553,7 @@ public:
|
|||
ESM::WeatherState weather;
|
||||
weather.mCurrentWeather = toString(mGame.mGMDT.mCurrentWeather);
|
||||
weather.mNextWeather = toString(mGame.mGMDT.mNextWeather);
|
||||
weather.mRemainingTransitionTime = mGame.mGMDT.mWeatherTransition/100.f*(0.015*24*3600);
|
||||
weather.mRemainingTransitionTime = mGame.mGMDT.mWeatherTransition/100.f*(0.015f*24*3600);
|
||||
weather.mHour = mContext->mHour;
|
||||
weather.mWindSpeed = 0.f;
|
||||
weather.mTimePassed = 0.0;
|
||||
|
|
|
@ -43,13 +43,17 @@ namespace ESSImport
|
|||
float mMagicEffects[27]; // Effect attributes: https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attributes
|
||||
unsigned char mUnknown4[4];
|
||||
unsigned int mGoldPool;
|
||||
unsigned char mUnknown5[4];
|
||||
unsigned char mCountDown; // seen the same value as in ACSC.mCorpseClearCountdown, maybe
|
||||
// this one is for respawning?
|
||||
unsigned char mUnknown5[3];
|
||||
};
|
||||
struct ACSC
|
||||
{
|
||||
unsigned char mUnknown1[17];
|
||||
unsigned char mFlags; // ACSCFlags
|
||||
unsigned char mUnknown2[94];
|
||||
unsigned char mUnknown2[22];
|
||||
unsigned char mCorpseClearCountdown; // hours?
|
||||
unsigned char mUnknown3[71];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace ESSImport
|
|||
{
|
||||
unsigned int deleted;
|
||||
esm.getHT(deleted);
|
||||
mDeleted = (deleted >> 24) & 0x2; // the other 3 bytes seem to be uninitialized garbage
|
||||
mDeleted = ((deleted >> 24) & 0x2) != 0; // the other 3 bytes seem to be uninitialized garbage
|
||||
}
|
||||
|
||||
if (esm.isNextSub("MVRF"))
|
||||
|
|
|
@ -14,10 +14,10 @@ namespace ESSImport
|
|||
float scale;
|
||||
esm.getHNOT(scale, "XSCL");
|
||||
|
||||
// FIXME: use AiPackageList, need to fix getSubName()
|
||||
|
||||
while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F")
|
||||
|| esm.isNextSub("AI_A"))
|
||||
esm.skipHSub();
|
||||
mAiPackages.add(esm);
|
||||
|
||||
mInventory.load(esm);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define OPENMW_ESSIMPORT_CREC_H
|
||||
|
||||
#include "importinventory.hpp"
|
||||
#include <components/esm/aipackage.hpp>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -17,6 +18,7 @@ namespace ESSImport
|
|||
int mIndex;
|
||||
|
||||
Inventory mInventory;
|
||||
ESM::AIPackageList mAiPackages;
|
||||
|
||||
void load(ESM::ESMReader& esm);
|
||||
};
|
||||
|
|
|
@ -9,10 +9,9 @@ namespace ESSImport
|
|||
{
|
||||
esm.getHNT(mNPDT, "NPDT");
|
||||
|
||||
// FIXME: use AiPackageList, need to fix getSubName()
|
||||
while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F")
|
||||
|| esm.isNextSub("AI_A"))
|
||||
esm.skipHSub();
|
||||
mAiPackages.add(esm);
|
||||
|
||||
mInventory.load(esm);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace ESSImport
|
|||
} mNPDT;
|
||||
|
||||
Inventory mInventory;
|
||||
ESM::AIPackageList mAiPackages;
|
||||
|
||||
void load(ESM::ESMReader &esm);
|
||||
};
|
||||
|
|
|
@ -61,6 +61,7 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
|
|||
QString revision(OPENMW_VERSION_COMMITHASH);
|
||||
QString tag(OPENMW_VERSION_TAGHASH);
|
||||
|
||||
versionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
if (!revision.isEmpty() && !tag.isEmpty())
|
||||
{
|
||||
if (revision == tag) {
|
||||
|
@ -238,24 +239,8 @@ void Launcher::MainDialog::changePage(QListWidgetItem *current, QListWidgetItem
|
|||
current = previous;
|
||||
|
||||
int currentIndex = iconWidget->row(current);
|
||||
// int previousIndex = iconWidget->row(previous);
|
||||
|
||||
pagesWidget->setCurrentIndex(currentIndex);
|
||||
|
||||
// DataFilesPage *previousPage = dynamic_cast<DataFilesPage *>(pagesWidget->widget(previousIndex));
|
||||
// DataFilesPage *currentPage = dynamic_cast<DataFilesPage *>(pagesWidget->widget(currentIndex));
|
||||
|
||||
// //special call to update/save data files page list view when it's displayed/hidden.
|
||||
// if (previousPage)
|
||||
// {
|
||||
// if (previousPage->objectName() == "DataFilesPage")
|
||||
// previousPage->saveSettings();
|
||||
// }
|
||||
// else if (currentPage)
|
||||
// {
|
||||
// if (currentPage->objectName() == "DataFilesPage")
|
||||
// currentPage->loadSettings();
|
||||
// }
|
||||
mSettingsPage->resetProgressBar();
|
||||
}
|
||||
|
||||
bool Launcher::MainDialog::setupLauncherSettings()
|
||||
|
|
|
@ -39,6 +39,7 @@ Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg,
|
|||
|
||||
mWizardInvoker = new ProcessInvoker();
|
||||
mImporterInvoker = new ProcessInvoker();
|
||||
resetProgressBar();
|
||||
|
||||
connect(mWizardInvoker->getProcess(), SIGNAL(started()),
|
||||
this, SLOT(wizardStarted()));
|
||||
|
@ -94,7 +95,7 @@ Launcher::SettingsPage::~SettingsPage()
|
|||
|
||||
void Launcher::SettingsPage::on_wizardButton_clicked()
|
||||
{
|
||||
saveSettings();
|
||||
mMain->writeSettings();
|
||||
|
||||
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false))
|
||||
return;
|
||||
|
@ -102,7 +103,7 @@ void Launcher::SettingsPage::on_wizardButton_clicked()
|
|||
|
||||
void Launcher::SettingsPage::on_importerButton_clicked()
|
||||
{
|
||||
saveSettings();
|
||||
mMain->writeSettings();
|
||||
|
||||
// Create the file if it doesn't already exist, else the importer will fail
|
||||
QString path(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()));
|
||||
|
@ -141,8 +142,13 @@ void Launcher::SettingsPage::on_importerButton_clicked()
|
|||
|
||||
qDebug() << "arguments " << arguments;
|
||||
|
||||
// start the progress bar as a "bouncing ball"
|
||||
progressBar->setMaximum(0);
|
||||
progressBar->setValue(0);
|
||||
if (!mImporterInvoker->startProcess(QLatin1String("openmw-iniimporter"), arguments, false))
|
||||
return;
|
||||
{
|
||||
resetProgressBar();
|
||||
}
|
||||
}
|
||||
|
||||
void Launcher::SettingsPage::on_browseButton_clicked()
|
||||
|
@ -197,38 +203,35 @@ void Launcher::SettingsPage::importerStarted()
|
|||
void Launcher::SettingsPage::importerFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
if (exitCode != 0 || exitStatus == QProcess::CrashExit)
|
||||
return;
|
||||
|
||||
// Importer may have changed settings, so refresh
|
||||
mMain->reloadSettings();
|
||||
|
||||
// Import selected data files from openmw.cfg
|
||||
if (addonsCheckBox->isChecked())
|
||||
{
|
||||
// Because we've reloaded settings, the current content list matches content in OpenMW.cfg
|
||||
QString oldContentListName = mLauncherSettings.getCurrentContentListName();
|
||||
if (mProfileDialog->exec() == QDialog::Accepted)
|
||||
{
|
||||
// remove the current content list to prevent duplication
|
||||
//... except, not allowed to delete the Default content list
|
||||
if (oldContentListName.compare(DataFilesPage::mDefaultContentListName) != 0)
|
||||
{
|
||||
mLauncherSettings.removeContentList(oldContentListName);
|
||||
}
|
||||
resetProgressBar();
|
||||
|
||||
const QString newContentListName(mProfileDialog->lineEdit()->text());
|
||||
const QStringList files(mGameSettings.getContentList());
|
||||
mLauncherSettings.setCurrentContentListName(newContentListName);
|
||||
mLauncherSettings.setContentList(newContentListName, files);
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("Importer finished"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setText(tr("Failed to import settings from INI file."));
|
||||
msgBox.exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
// indicate progress finished
|
||||
progressBar->setMaximum(1);
|
||||
progressBar->setValue(1);
|
||||
|
||||
// Make DataFiles Page load the new content list.
|
||||
mMain->reloadSettings();
|
||||
}
|
||||
// Importer may have changed settings, so refresh
|
||||
mMain->reloadSettings();
|
||||
}
|
||||
|
||||
importerButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void Launcher::SettingsPage::resetProgressBar()
|
||||
{
|
||||
// set progress bar to 0 %
|
||||
progressBar->reset();
|
||||
}
|
||||
|
||||
void Launcher::SettingsPage::updateOkButton(const QString &text)
|
||||
{
|
||||
// We do this here because we need to access the profiles
|
||||
|
|
|
@ -29,6 +29,9 @@ namespace Launcher
|
|||
|
||||
void saveSettings();
|
||||
bool loadSettings();
|
||||
|
||||
/// set progress bar on page to 0%
|
||||
void resetProgressBar();
|
||||
|
||||
private slots:
|
||||
|
||||
|
@ -57,7 +60,6 @@ namespace Launcher
|
|||
MainDialog *mMain;
|
||||
TextInputDialog *mProfileDialog;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
#include <sstream>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
|
@ -660,7 +661,7 @@ std::string MwIniImporter::numberToString(int n) {
|
|||
return str.str();
|
||||
}
|
||||
|
||||
MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filename) const {
|
||||
MwIniImporter::multistrmap MwIniImporter::loadIniFile(const boost::filesystem::path& filename) const {
|
||||
std::cout << "load ini file: " << filename << std::endl;
|
||||
|
||||
std::string section("");
|
||||
|
@ -719,7 +720,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filenam
|
|||
return map;
|
||||
}
|
||||
|
||||
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::string& filename) {
|
||||
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const boost::filesystem::path& filename) {
|
||||
std::cout << "load cfg file: " << filename << std::endl;
|
||||
|
||||
MwIniImporter::multistrmap map;
|
||||
|
@ -825,10 +826,14 @@ void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) con
|
|||
}
|
||||
}
|
||||
|
||||
void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) const {
|
||||
std::vector<std::string> contentFiles;
|
||||
void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, const boost::filesystem::path& iniFilename) const {
|
||||
std::vector<std::pair<std::time_t, std::string> > contentFiles;
|
||||
std::string baseGameFile("Game Files:GameFile");
|
||||
std::string gameFile("");
|
||||
std::time_t defaultTime = 0;
|
||||
|
||||
// assume the Game Files are all in a "Data Files" directory under the directory holding Morrowind.ini
|
||||
const boost::filesystem::path gameFilesDir(iniFilename.parent_path() /= "Data Files");
|
||||
|
||||
multistrmap::const_iterator it = ini.begin();
|
||||
for(int i=0; it != ini.end(); i++) {
|
||||
|
@ -845,18 +850,20 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) co
|
|||
Misc::StringUtils::toLower(filetype);
|
||||
|
||||
if(filetype.compare("esm") == 0 || filetype.compare("esp") == 0) {
|
||||
contentFiles.push_back(*entry);
|
||||
boost::filesystem::path filepath(gameFilesDir);
|
||||
filepath /= *entry;
|
||||
contentFiles.push_back(std::make_pair(lastWriteTime(filepath, defaultTime), *entry));
|
||||
}
|
||||
}
|
||||
|
||||
gameFile = "";
|
||||
}
|
||||
|
||||
cfg.erase("content");
|
||||
cfg.insert( std::make_pair("content", std::vector<std::string>() ) );
|
||||
|
||||
for(std::vector<std::string>::const_iterator it=contentFiles.begin(); it!=contentFiles.end(); ++it) {
|
||||
cfg["content"].push_back(*it);
|
||||
// this will sort files by time order first, then alphabetical (maybe), I suspect non ASCII filenames will be stuffed.
|
||||
sort(contentFiles.begin(), contentFiles.end());
|
||||
for(std::vector<std::pair<std::time_t, std::string> >::const_iterator it=contentFiles.begin(); it!=contentFiles.end(); ++it) {
|
||||
cfg["content"].push_back(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -873,3 +880,27 @@ void MwIniImporter::setInputEncoding(const ToUTF8::FromType &encoding)
|
|||
{
|
||||
mEncoding = encoding;
|
||||
}
|
||||
|
||||
std::time_t MwIniImporter::lastWriteTime(const boost::filesystem::path& filename, std::time_t defaultTime)
|
||||
{
|
||||
std::time_t writeTime(defaultTime);
|
||||
if (boost::filesystem::exists(filename))
|
||||
{
|
||||
// FixMe: remove #if when Boost dependency for Linux builds updated
|
||||
// This allows Linux to build until then
|
||||
#if (BOOST_VERSION >= 104800)
|
||||
// need to resolve any symlinks so that we get time of file, not symlink
|
||||
boost::filesystem::path resolved = boost::filesystem::canonical(filename);
|
||||
#else
|
||||
boost::filesystem::path resolved = filename;
|
||||
#endif
|
||||
writeTime = boost::filesystem::last_write_time(resolved);
|
||||
std::cout << "content file: " << resolved << " timestamp = (" << writeTime <<
|
||||
") " << asctime(localtime(&writeTime)) << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "content file: " << filename << " not found" << std::endl;
|
||||
}
|
||||
return writeTime;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <vector>
|
||||
#include <exception>
|
||||
#include <iosfwd>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
|
@ -17,17 +18,22 @@ class MwIniImporter {
|
|||
MwIniImporter();
|
||||
void setInputEncoding(const ToUTF8::FromType& encoding);
|
||||
void setVerbose(bool verbose);
|
||||
multistrmap loadIniFile(const std::string& filename) const;
|
||||
static multistrmap loadCfgFile(const std::string& filename);
|
||||
multistrmap loadIniFile(const boost::filesystem::path& filename) const;
|
||||
static multistrmap loadCfgFile(const boost::filesystem::path& filename);
|
||||
void merge(multistrmap &cfg, const multistrmap &ini) const;
|
||||
void mergeFallback(multistrmap &cfg, const multistrmap &ini) const;
|
||||
void importGameFiles(multistrmap &cfg, const multistrmap &ini) const;
|
||||
void importGameFiles(multistrmap &cfg, const multistrmap &ini,
|
||||
const boost::filesystem::path& iniFilename) const;
|
||||
void importArchives(multistrmap &cfg, const multistrmap &ini) const;
|
||||
static void writeToFile(std::ostream &out, const multistrmap &cfg);
|
||||
|
||||
private:
|
||||
static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value);
|
||||
static std::string numberToString(int n);
|
||||
|
||||
/// \return file's "last modified time", used in original MW to determine plug-in load order
|
||||
static std::time_t lastWriteTime(const boost::filesystem::path& filename, std::time_t defaultTime);
|
||||
|
||||
bool mVerbose;
|
||||
strmap mMergeMap;
|
||||
std::vector<std::string> mMergeFallback;
|
||||
|
|
|
@ -93,8 +93,8 @@ int wmain(int argc, wchar_t *wargv[]) {
|
|||
|
||||
bpo::notify(vm);
|
||||
|
||||
std::string iniFile = vm["ini"].as<std::string>();
|
||||
std::string cfgFile = vm["cfg"].as<std::string>();
|
||||
boost::filesystem::path iniFile(vm["ini"].as<std::string>());
|
||||
boost::filesystem::path cfgFile(vm["cfg"].as<std::string>());
|
||||
|
||||
// if no output is given, write back to cfg file
|
||||
std::string outputFile(vm["output"].as<std::string>());
|
||||
|
@ -110,7 +110,7 @@ int wmain(int argc, wchar_t *wargv[]) {
|
|||
std::cerr << "cfg file does not exist" << std::endl;
|
||||
|
||||
MwIniImporter importer;
|
||||
importer.setVerbose(vm.count("verbose"));
|
||||
importer.setVerbose(vm.count("verbose") != 0);
|
||||
|
||||
// Font encoding settings
|
||||
std::string encoding(vm["encoding"].as<std::string>());
|
||||
|
@ -123,7 +123,7 @@ int wmain(int argc, wchar_t *wargv[]) {
|
|||
importer.mergeFallback(cfg, ini);
|
||||
|
||||
if(vm.count("game-files")) {
|
||||
importer.importGameFiles(cfg, ini);
|
||||
importer.importGameFiles(cfg, ini, iniFile);
|
||||
}
|
||||
|
||||
if(!vm.count("no-archives")) {
|
||||
|
|
|
@ -5,7 +5,7 @@ set (OPENCS_SRC main.cpp
|
|||
opencs_units (. editor)
|
||||
|
||||
opencs_units (model/doc
|
||||
document operation saving documentmanager loader runner
|
||||
document operation saving documentmanager loader runner operationholder
|
||||
)
|
||||
|
||||
opencs_units_noqt (model/doc
|
||||
|
@ -40,6 +40,7 @@ opencs_units (model/tools
|
|||
opencs_units_noqt (model/tools
|
||||
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
||||
birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck
|
||||
startscriptcheck
|
||||
)
|
||||
|
||||
|
||||
|
@ -164,7 +165,8 @@ qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
|
|||
qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
|
||||
qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${BULLET_INCLUDE_DIRS})
|
||||
# for compiled .ui files
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if(APPLE)
|
||||
set (OPENCS_MAC_ICON ${CMAKE_SOURCE_DIR}/files/mac/openmw-cs.icns)
|
||||
|
@ -174,7 +176,6 @@ endif(APPLE)
|
|||
|
||||
add_executable(openmw-cs
|
||||
MACOSX_BUNDLE
|
||||
${OENGINE_BULLET}
|
||||
${OPENCS_SRC}
|
||||
${OPENCS_UI_HDR}
|
||||
${OPENCS_MOC_SRC}
|
||||
|
@ -198,6 +199,7 @@ if(APPLE)
|
|||
endif(APPLE)
|
||||
|
||||
target_link_libraries(openmw-cs
|
||||
${OENGINE_LIBRARY}
|
||||
${OGRE_LIBRARIES}
|
||||
${OGRE_Overlay_LIBRARIES}
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
|
|
|
@ -28,4 +28,4 @@ void CSMDoc::Blacklist::add (CSMWorld::UniversalId::Type type,
|
|||
|
||||
std::transform (ids.begin(), ids.end(), list.begin()+size, Misc::StringUtils::lowerCase);
|
||||
std::sort (list.begin(), list.end());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2252,7 +2252,8 @@ CSMDoc::Document::Document (const VFS::Manager* vfs, const Files::ConfigurationM
|
|||
mTools (*this), mResDir(resDir),
|
||||
mProjectPath ((configuration.getUserDataPath() / "projects") /
|
||||
(savePath.filename().string() + ".project")),
|
||||
mSaving (*this, mProjectPath, encoding),
|
||||
mSavingOperation (*this, mProjectPath, encoding),
|
||||
mSaving (&mSavingOperation),
|
||||
mRunner (mProjectPath)
|
||||
{
|
||||
if (mContentFiles.empty())
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "saving.hpp"
|
||||
#include "blacklist.hpp"
|
||||
#include "runner.hpp"
|
||||
#include "operationholder.hpp"
|
||||
|
||||
class QAbstractItemModel;
|
||||
|
||||
|
@ -38,7 +39,7 @@ namespace ESM
|
|||
|
||||
namespace Files
|
||||
{
|
||||
class ConfigurationManager;
|
||||
struct ConfigurationManager;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
|
@ -61,7 +62,8 @@ namespace CSMDoc
|
|||
CSMWorld::Data mData;
|
||||
CSMTools::Tools mTools;
|
||||
boost::filesystem::path mProjectPath;
|
||||
Saving mSaving;
|
||||
Saving mSavingOperation;
|
||||
OperationHolder mSaving;
|
||||
boost::filesystem::path mResDir;
|
||||
Blacklist mBlacklist;
|
||||
Runner mRunner;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace VFS
|
|||
|
||||
namespace Files
|
||||
{
|
||||
class ConfigurationManager;
|
||||
struct ConfigurationManager;
|
||||
}
|
||||
|
||||
namespace CSMDoc
|
||||
|
@ -56,7 +56,7 @@ namespace CSMDoc
|
|||
///< \param new_ Do not load the last content file in \a files and instead create in an
|
||||
/// appropriate way.
|
||||
|
||||
void setResourceDir (const boost::filesystem::path& parResDir);
|
||||
void setResourceDir (const boost::filesystem::path& parResDir);
|
||||
|
||||
void setEncoding (ToUTF8::FromType encoding);
|
||||
|
||||
|
@ -66,7 +66,7 @@ namespace CSMDoc
|
|||
|
||||
private:
|
||||
|
||||
boost::filesystem::path mResDir;
|
||||
boost::filesystem::path mResDir;
|
||||
|
||||
private slots:
|
||||
|
||||
|
|
|
@ -25,4 +25,4 @@ CSMDoc::Messages::Iterator CSMDoc::Messages::begin() const
|
|||
CSMDoc::Messages::Iterator CSMDoc::Messages::end() const
|
||||
{
|
||||
return mMessages.end();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ void CSMDoc::Operation::prepareStages()
|
|||
CSMDoc::Operation::Operation (int type, bool ordered, bool finalAlways)
|
||||
: mType (type), mStages(std::vector<std::pair<Stage *, int> >()), mCurrentStage(mStages.begin()),
|
||||
mCurrentStep(0), mCurrentStepTotal(0), mTotalSteps(0), mOrdered (ordered),
|
||||
mFinalAlways (finalAlways), mError(false)
|
||||
mFinalAlways (finalAlways), mError(false), mConnected (false)
|
||||
{
|
||||
connect (this, SIGNAL (finished()), this, SLOT (operationDone()));
|
||||
mTimer = new QTimer (this);
|
||||
}
|
||||
|
||||
CSMDoc::Operation::~Operation()
|
||||
|
@ -42,15 +42,17 @@ CSMDoc::Operation::~Operation()
|
|||
|
||||
void CSMDoc::Operation::run()
|
||||
{
|
||||
mTimer->stop();
|
||||
|
||||
if (!mConnected)
|
||||
{
|
||||
connect (mTimer, SIGNAL (timeout()), this, SLOT (executeStage()));
|
||||
mConnected = true;
|
||||
}
|
||||
|
||||
prepareStages();
|
||||
|
||||
QTimer timer;
|
||||
|
||||
timer.connect (&timer, SIGNAL (timeout()), this, SLOT (executeStage()));
|
||||
|
||||
timer.start (0);
|
||||
|
||||
exec();
|
||||
mTimer->start (0);
|
||||
}
|
||||
|
||||
void CSMDoc::Operation::appendStage (Stage *stage)
|
||||
|
@ -65,7 +67,7 @@ bool CSMDoc::Operation::hasError() const
|
|||
|
||||
void CSMDoc::Operation::abort()
|
||||
{
|
||||
if (!isRunning())
|
||||
if (!mTimer->isActive())
|
||||
return;
|
||||
|
||||
mError = true;
|
||||
|
@ -116,10 +118,11 @@ void CSMDoc::Operation::executeStage()
|
|||
emit reportMessage (iter->mId, iter->mMessage, iter->mHint, mType);
|
||||
|
||||
if (mCurrentStage==mStages.end())
|
||||
exit();
|
||||
operationDone();
|
||||
}
|
||||
|
||||
void CSMDoc::Operation::operationDone()
|
||||
{
|
||||
mTimer->stop();
|
||||
emit done (mType, mError);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include <QThread>
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
|
@ -14,7 +15,7 @@ namespace CSMDoc
|
|||
{
|
||||
class Stage;
|
||||
|
||||
class Operation : public QThread
|
||||
class Operation : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -27,6 +28,8 @@ namespace CSMDoc
|
|||
int mOrdered;
|
||||
bool mFinalAlways;
|
||||
bool mError;
|
||||
bool mConnected;
|
||||
QTimer *mTimer;
|
||||
|
||||
void prepareStages();
|
||||
|
||||
|
@ -38,8 +41,6 @@ namespace CSMDoc
|
|||
|
||||
virtual ~Operation();
|
||||
|
||||
virtual void run();
|
||||
|
||||
void appendStage (Stage *stage);
|
||||
///< The ownership of \a stage is transferred to *this.
|
||||
///
|
||||
|
@ -60,6 +61,8 @@ namespace CSMDoc
|
|||
|
||||
void abort();
|
||||
|
||||
void run();
|
||||
|
||||
private slots:
|
||||
|
||||
void executeStage();
|
||||
|
@ -68,4 +71,4 @@ namespace CSMDoc
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
65
apps/opencs/model/doc/operationholder.cpp
Normal file
65
apps/opencs/model/doc/operationholder.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
#include "operationholder.hpp"
|
||||
|
||||
#include "operation.hpp"
|
||||
|
||||
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false)
|
||||
{
|
||||
if (operation)
|
||||
setOperation (operation);
|
||||
}
|
||||
|
||||
void CSMDoc::OperationHolder::setOperation (Operation *operation)
|
||||
{
|
||||
mOperation = operation;
|
||||
mOperation->moveToThread (&mThread);
|
||||
|
||||
connect (
|
||||
mOperation, SIGNAL (progress (int, int, int)),
|
||||
this, SIGNAL (progress (int, int, int)));
|
||||
|
||||
connect (
|
||||
mOperation, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
||||
this, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
||||
|
||||
connect (
|
||||
mOperation, SIGNAL (done (int, bool)),
|
||||
this, SLOT (doneSlot (int, bool)));
|
||||
|
||||
connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort()));
|
||||
|
||||
connect (&mThread, SIGNAL (started()), mOperation, SLOT (run()));
|
||||
}
|
||||
|
||||
bool CSMDoc::OperationHolder::isRunning() const
|
||||
{
|
||||
return mRunning;
|
||||
}
|
||||
|
||||
void CSMDoc::OperationHolder::start()
|
||||
{
|
||||
mRunning = true;
|
||||
mThread.start();
|
||||
}
|
||||
|
||||
void CSMDoc::OperationHolder::abort()
|
||||
{
|
||||
mRunning = false;
|
||||
emit abortSignal();
|
||||
}
|
||||
|
||||
void CSMDoc::OperationHolder::abortAndWait()
|
||||
{
|
||||
if (mRunning)
|
||||
{
|
||||
mThread.quit();
|
||||
mThread.wait();
|
||||
}
|
||||
}
|
||||
|
||||
void CSMDoc::OperationHolder::doneSlot (int type, bool failed)
|
||||
{
|
||||
mRunning = false;
|
||||
mThread.quit();
|
||||
emit done (type, failed);
|
||||
}
|
56
apps/opencs/model/doc/operationholder.hpp
Normal file
56
apps/opencs/model/doc/operationholder.hpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#ifndef CSM_DOC_OPERATIONHOLDER_H
|
||||
#define CSM_DOC_OPERATIONHOLDER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class UniversalId;
|
||||
}
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Operation;
|
||||
|
||||
class OperationHolder : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QThread mThread;
|
||||
Operation *mOperation;
|
||||
bool mRunning;
|
||||
|
||||
public:
|
||||
|
||||
OperationHolder (Operation *operation = 0);
|
||||
|
||||
void setOperation (Operation *operation);
|
||||
|
||||
bool isRunning() const;
|
||||
|
||||
void start();
|
||||
|
||||
void abort();
|
||||
|
||||
// Abort and wait until thread has finished.
|
||||
void abortAndWait();
|
||||
|
||||
private slots:
|
||||
|
||||
void doneSlot (int type, bool failed);
|
||||
|
||||
signals:
|
||||
|
||||
void progress (int current, int max, int type);
|
||||
|
||||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint, int type);
|
||||
|
||||
void done (int type, bool failed);
|
||||
|
||||
void abortSignal();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6,7 +6,7 @@
|
|||
#include <QTemporaryFile>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "operation.hpp"
|
||||
#include "operationholder.hpp"
|
||||
|
||||
CSMDoc::Runner::Runner (const boost::filesystem::path& projectPath)
|
||||
: mRunning (false), mStartup (0), mProjectPath (projectPath)
|
||||
|
@ -145,7 +145,7 @@ void CSMDoc::Runner::readyReadStandardOutput()
|
|||
}
|
||||
|
||||
|
||||
CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, Operation *operation)
|
||||
CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, OperationHolder *operation)
|
||||
: QObject (runner), mRunner (runner)
|
||||
{
|
||||
connect (operation, SIGNAL (done (int, bool)), this, SLOT (saveDone (int, bool)));
|
||||
|
|
|
@ -16,6 +16,8 @@ class QTemporaryFile;
|
|||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class OperationHolder;
|
||||
|
||||
class Runner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -74,7 +76,7 @@ namespace CSMDoc
|
|||
public:
|
||||
|
||||
/// *this attaches itself to runner
|
||||
SaveWatcher (Runner *runner, Operation *operation);
|
||||
SaveWatcher (Runner *runner, OperationHolder *operation);
|
||||
|
||||
private slots:
|
||||
|
||||
|
|
|
@ -78,6 +78,9 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje
|
|||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::MagicEffect> >
|
||||
(mDocument.getData().getMagicEffects(), mState));
|
||||
|
||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::StartScript> >
|
||||
(mDocument.getData().getStartScripts(), mState));
|
||||
|
||||
appendStage (new WriteDialogueCollectionStage (mDocument, mState, false));
|
||||
|
||||
appendStage (new WriteDialogueCollectionStage (mDocument, mState, true));
|
||||
|
@ -90,8 +93,12 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje
|
|||
|
||||
appendStage (new WritePathgridCollectionStage (mDocument, mState));
|
||||
|
||||
appendStage (new WriteLandCollectionStage (mDocument, mState));
|
||||
|
||||
appendStage (new WriteLandTextureCollectionStage (mDocument, mState));
|
||||
|
||||
// close file and clean up
|
||||
appendStage (new CloseSaveStage (mState));
|
||||
|
||||
appendStage (new FinalSavingStage (mDocument, mState));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages)
|
|||
|
||||
CSMDoc::WriteDialogueCollectionStage::WriteDialogueCollectionStage (Document& document,
|
||||
SavingState& state, bool journal)
|
||||
: mDocument (document), mState (state),
|
||||
: mState (state),
|
||||
mTopics (journal ? document.getData().getJournals() : document.getData().getTopics()),
|
||||
mInfos (journal ? document.getData().getJournalInfos() : document.getData().getTopicInfos())
|
||||
{}
|
||||
|
@ -353,6 +353,74 @@ void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& message
|
|||
}
|
||||
|
||||
|
||||
CSMDoc::WriteLandCollectionStage::WriteLandCollectionStage (Document& document,
|
||||
SavingState& state)
|
||||
: mDocument (document), mState (state)
|
||||
{}
|
||||
|
||||
int CSMDoc::WriteLandCollectionStage::setup()
|
||||
{
|
||||
return mDocument.getData().getLand().getSize();
|
||||
}
|
||||
|
||||
void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages)
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::Land>& land =
|
||||
mDocument.getData().getLand().getRecord (stage);
|
||||
|
||||
if (land.mState==CSMWorld::RecordBase::State_Modified ||
|
||||
land.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||
{
|
||||
CSMWorld::Land record = land.get();
|
||||
|
||||
mState.getWriter().startRecord (record.mLand->sRecordId);
|
||||
|
||||
record.mLand->save (mState.getWriter());
|
||||
if(record.mLand->mLandData)
|
||||
record.mLand->mLandData->save (mState.getWriter());
|
||||
|
||||
mState.getWriter().endRecord (record.mLand->sRecordId);
|
||||
}
|
||||
else if (land.mState==CSMWorld::RecordBase::State_Deleted)
|
||||
{
|
||||
/// \todo write record with delete flag
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSMDoc::WriteLandTextureCollectionStage::WriteLandTextureCollectionStage (Document& document,
|
||||
SavingState& state)
|
||||
: mDocument (document), mState (state)
|
||||
{}
|
||||
|
||||
int CSMDoc::WriteLandTextureCollectionStage::setup()
|
||||
{
|
||||
return mDocument.getData().getLandTextures().getSize();
|
||||
}
|
||||
|
||||
void CSMDoc::WriteLandTextureCollectionStage::perform (int stage, Messages& messages)
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::LandTexture>& landTexture =
|
||||
mDocument.getData().getLandTextures().getRecord (stage);
|
||||
|
||||
if (landTexture.mState==CSMWorld::RecordBase::State_Modified ||
|
||||
landTexture.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||
{
|
||||
CSMWorld::LandTexture record = landTexture.get();
|
||||
|
||||
mState.getWriter().startRecord (record.sRecordId);
|
||||
|
||||
record.save (mState.getWriter());
|
||||
|
||||
mState.getWriter().endRecord (record.sRecordId);
|
||||
}
|
||||
else if (landTexture.mState==CSMWorld::RecordBase::State_Deleted)
|
||||
{
|
||||
/// \todo write record with delete flag
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state)
|
||||
: mState (state)
|
||||
{}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "../world/idcollection.hpp"
|
||||
#include "../world/scope.hpp"
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
|
||||
#include "savingstate.hpp"
|
||||
|
||||
namespace ESM
|
||||
|
@ -103,8 +105,15 @@ namespace CSMDoc
|
|||
if (state==CSMWorld::RecordBase::State_Modified ||
|
||||
state==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||
{
|
||||
mState.getWriter().startRecord (mCollection.getRecord (stage).mModified.sRecordId);
|
||||
mState.getWriter().writeHNCString ("NAME", mCollection.getId (stage));
|
||||
// FIXME: A quick Workaround to support records which should not write
|
||||
// NAME, including SKIL, MGEF and SCPT. If there are many more
|
||||
// idcollection records that doesn't use NAME then a more generic
|
||||
// solution may be required.
|
||||
uint32_t name = mCollection.getRecord (stage).mModified.sRecordId;
|
||||
mState.getWriter().startRecord (name);
|
||||
|
||||
if(name != ESM::REC_SKIL && name != ESM::REC_MGEF && name != ESM::REC_SCPT)
|
||||
mState.getWriter().writeHNCString ("NAME", mCollection.getId (stage));
|
||||
mCollection.getRecord (stage).mModified.save (mState.getWriter());
|
||||
mState.getWriter().endRecord (mCollection.getRecord (stage).mModified.sRecordId);
|
||||
}
|
||||
|
@ -117,7 +126,6 @@ namespace CSMDoc
|
|||
|
||||
class WriteDialogueCollectionStage : public Stage
|
||||
{
|
||||
Document& mDocument;
|
||||
SavingState& mState;
|
||||
const CSMWorld::IdCollection<ESM::Dialogue>& mTopics;
|
||||
CSMWorld::InfoCollection& mInfos;
|
||||
|
@ -200,6 +208,40 @@ namespace CSMDoc
|
|||
///< Messages resulting from this stage will be appended to \a messages.
|
||||
};
|
||||
|
||||
|
||||
class WriteLandCollectionStage : public Stage
|
||||
{
|
||||
Document& mDocument;
|
||||
SavingState& mState;
|
||||
|
||||
public:
|
||||
|
||||
WriteLandCollectionStage (Document& document, SavingState& state);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, Messages& messages);
|
||||
///< Messages resulting from this stage will be appended to \a messages.
|
||||
};
|
||||
|
||||
|
||||
class WriteLandTextureCollectionStage : public Stage
|
||||
{
|
||||
Document& mDocument;
|
||||
SavingState& mState;
|
||||
|
||||
public:
|
||||
|
||||
WriteLandTextureCollectionStage (Document& document, SavingState& state);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, Messages& messages);
|
||||
///< Messages resulting from this stage will be appended to \a messages.
|
||||
};
|
||||
|
||||
class CloseSaveStage : public Stage
|
||||
{
|
||||
SavingState& mState;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
#include "stage.hpp"
|
||||
|
||||
CSMDoc::Stage::~Stage() {}
|
||||
CSMDoc::Stage::~Stage() {}
|
||||
|
|
|
@ -12,4 +12,4 @@ bool CSMFilter::BooleanNode::test (const CSMWorld::IdTableBase& table, int row,
|
|||
std::string CSMFilter::BooleanNode::toString (bool numericColumns) const
|
||||
{
|
||||
return mTrue ? "true" : "false";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,4 +26,4 @@ namespace CSMFilter
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
|
||||
CSMFilter::Node::Node() {}
|
||||
|
||||
CSMFilter::Node::~Node() {}
|
||||
CSMFilter::Node::~Node() {}
|
||||
|
|
|
@ -7,4 +7,4 @@ bool CSMFilter::NotNode::test (const CSMWorld::IdTableBase& table, int row,
|
|||
const std::map<int, int>& columns) const
|
||||
{
|
||||
return !getChild().test (table, row, columns);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,4 +82,4 @@ std::string CSMFilter::TextNode::toString (bool numericColumns) const
|
|||
stream << ", \"" << mText << "\")";
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,4 +23,4 @@ std::vector<int> CSMFilter::UnaryNode::getReferencedColumns() const
|
|||
std::string CSMFilter::UnaryNode::toString (bool numericColumns) const
|
||||
{
|
||||
return mName + " " + mChild->toString (numericColumns);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,4 +94,4 @@ std::string CSMFilter::ValueNode::toString (bool numericColumns) const
|
|||
stream << ")";
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,4 +41,4 @@ void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messag
|
|||
/// \todo test if the texture exists
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,4 +32,4 @@ namespace CSMTools
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -65,4 +65,4 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
messages.push_back (std::make_pair (id,
|
||||
ESM::Skill::indexToId (iter->first) + " is listed more than once"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,4 +20,4 @@ void CSMTools::MandatoryIdStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
if (mIdCollection.searchId (mIds.at (stage))==-1 ||
|
||||
mIdCollection.getRecord (mIds.at (stage)).isDeleted())
|
||||
messages.add (mCollectionId, "Missing mandatory record: " + mIds.at (stage));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,4 +70,4 @@ void CSMTools::RaceCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
performFinal (messages);
|
||||
else
|
||||
performPerRecord (stage, messages);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,10 +48,6 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message
|
|||
}
|
||||
}
|
||||
|
||||
// Check if referenced object is in valid cell
|
||||
if (mCells.searchId(cellRef.mCell) == -1)
|
||||
messages.push_back(std::make_pair(id, " is referencing object from non existing cell " + cellRef.mCell));
|
||||
|
||||
// If object have owner, check if that owner reference is valid
|
||||
if (!cellRef.mOwner.empty() && mReferencables.searchId(cellRef.mOwner) == -1)
|
||||
messages.push_back(std::make_pair(id, " has non existing owner " + cellRef.mOwner));
|
||||
|
@ -70,9 +66,9 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message
|
|||
|
||||
// Check item's faction rank
|
||||
if (hasFaction && cellRef.mFactionRank < -1)
|
||||
messages.push_back(std::make_pair(id, " has faction set but has invalid faction rank " + cellRef.mFactionRank));
|
||||
messages.push_back(std::make_pair(id, " has faction set but has invalid faction rank " + boost::lexical_cast<std::string>(cellRef.mFactionRank)));
|
||||
else if (!hasFaction && cellRef.mFactionRank != -2)
|
||||
messages.push_back(std::make_pair(id, " has invalid faction rank " + cellRef.mFactionRank));
|
||||
messages.push_back(std::make_pair(id, " has invalid faction rank " + boost::lexical_cast<std::string>(cellRef.mFactionRank)));
|
||||
|
||||
// If door have destination cell, check if that reference is valid
|
||||
if (!cellRef.mDestCell.empty())
|
||||
|
|
|
@ -26,4 +26,4 @@ namespace CSMTools
|
|||
};
|
||||
}
|
||||
|
||||
#endif // CSM_TOOLS_REFERENCECHECK_H
|
||||
#endif // CSM_TOOLS_REFERENCECHECK_H
|
||||
|
|
|
@ -35,4 +35,4 @@ void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
/// \todo test that the ID in mSleeplist exists
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,4 +78,4 @@ const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) con
|
|||
std::string CSMTools::ReportModel::getHint (int row) const
|
||||
{
|
||||
return mRows.at (row).second.second;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,4 +98,4 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
}
|
||||
|
||||
mMessages = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,4 +39,4 @@ void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
|
||||
if (skill.mDescription.empty())
|
||||
messages.push_back (std::make_pair (id, skill.mId + " has an empty description"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,4 +31,4 @@ void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
messages.push_back (std::make_pair (id, "Maximum range larger than minimum range"));
|
||||
|
||||
/// \todo check, if the sound file exists
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,4 +37,4 @@ void CSMTools::SpellCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
messages.push_back (std::make_pair (id, spell.mId + " has a negative spell costs"));
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
||||
}
|
||||
|
|
31
apps/opencs/model/tools/startscriptcheck.cpp
Normal file
31
apps/opencs/model/tools/startscriptcheck.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include "startscriptcheck.hpp"
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
CSMTools::StartScriptCheckStage::StartScriptCheckStage (
|
||||
const CSMWorld::IdCollection<ESM::StartScript>& startScripts,
|
||||
const CSMWorld::IdCollection<ESM::Script>& scripts)
|
||||
: mStartScripts (startScripts), mScripts (scripts)
|
||||
{}
|
||||
|
||||
void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
||||
{
|
||||
const CSMWorld::Record<ESM::StartScript>& record = mStartScripts.getRecord (stage);
|
||||
|
||||
if (record.isDeleted())
|
||||
return;
|
||||
|
||||
std::string scriptId = record.get().mId;
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_StartScript, scriptId);
|
||||
|
||||
if (mScripts.searchId (Misc::StringUtils::lowerCase (scriptId))==-1)
|
||||
messages.push_back (
|
||||
std::make_pair (id, "Start script " + scriptId + " does not exist"));
|
||||
}
|
||||
|
||||
int CSMTools::StartScriptCheckStage::setup()
|
||||
{
|
||||
return mStartScripts.getSize();
|
||||
}
|
28
apps/opencs/model/tools/startscriptcheck.hpp
Normal file
28
apps/opencs/model/tools/startscriptcheck.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef CSM_TOOLS_STARTSCRIPTCHECK_H
|
||||
#define CSM_TOOLS_STARTSCRIPTCHECK_H
|
||||
|
||||
#include <components/esm/loadsscr.hpp>
|
||||
#include <components/esm/loadscpt.hpp>
|
||||
|
||||
#include "../doc/stage.hpp"
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
class StartScriptCheckStage : public CSMDoc::Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::StartScript>& mStartScripts;
|
||||
const CSMWorld::IdCollection<ESM::Script>& mScripts;
|
||||
|
||||
public:
|
||||
|
||||
StartScriptCheckStage (const CSMWorld::IdCollection<ESM::StartScript>& startScripts,
|
||||
const CSMWorld::IdCollection<ESM::Script>& scripts);
|
||||
|
||||
virtual void perform(int stage, CSMDoc::Messages& messages);
|
||||
virtual int setup();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -24,31 +24,32 @@
|
|||
#include "scriptcheck.hpp"
|
||||
#include "bodypartcheck.hpp"
|
||||
#include "referencecheck.hpp"
|
||||
#include "startscriptcheck.hpp"
|
||||
|
||||
CSMDoc::Operation *CSMTools::Tools::get (int type)
|
||||
CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case CSMDoc::State_Verifying: return mVerifier;
|
||||
case CSMDoc::State_Verifying: return &mVerifier;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const CSMDoc::Operation *CSMTools::Tools::get (int type) const
|
||||
const CSMDoc::OperationHolder *CSMTools::Tools::get (int type) const
|
||||
{
|
||||
return const_cast<Tools *> (this)->get (type);
|
||||
}
|
||||
|
||||
CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
||||
CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
|
||||
{
|
||||
if (!mVerifier)
|
||||
if (!mVerifierOperation)
|
||||
{
|
||||
mVerifier = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
|
||||
mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
|
||||
|
||||
connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
||||
connect (mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||
connect (mVerifier,
|
||||
connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
||||
connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||
connect (&mVerifier,
|
||||
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
||||
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
||||
|
||||
|
@ -58,48 +59,49 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
|||
mandatoryIds.push_back ("GameHour");
|
||||
mandatoryIds.push_back ("Month");
|
||||
mandatoryIds.push_back ("PCRace");
|
||||
mandatoryIds.push_back ("PCVampire");
|
||||
mandatoryIds.push_back ("PCWerewolf");
|
||||
mandatoryIds.push_back ("PCYear");
|
||||
|
||||
mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(),
|
||||
mVerifierOperation->appendStage (new MandatoryIdStage (mData.getGlobals(),
|
||||
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
|
||||
|
||||
mVerifier->appendStage (new SkillCheckStage (mData.getSkills()));
|
||||
mVerifierOperation->appendStage (new SkillCheckStage (mData.getSkills()));
|
||||
|
||||
mVerifier->appendStage (new ClassCheckStage (mData.getClasses()));
|
||||
mVerifierOperation->appendStage (new ClassCheckStage (mData.getClasses()));
|
||||
|
||||
mVerifier->appendStage (new FactionCheckStage (mData.getFactions()));
|
||||
mVerifierOperation->appendStage (new FactionCheckStage (mData.getFactions()));
|
||||
|
||||
mVerifier->appendStage (new RaceCheckStage (mData.getRaces()));
|
||||
mVerifierOperation->appendStage (new RaceCheckStage (mData.getRaces()));
|
||||
|
||||
mVerifier->appendStage (new SoundCheckStage (mData.getSounds()));
|
||||
mVerifierOperation->appendStage (new SoundCheckStage (mData.getSounds()));
|
||||
|
||||
mVerifier->appendStage (new RegionCheckStage (mData.getRegions()));
|
||||
mVerifierOperation->appendStage (new RegionCheckStage (mData.getRegions()));
|
||||
|
||||
mVerifier->appendStage (new BirthsignCheckStage (mData.getBirthsigns()));
|
||||
mVerifierOperation->appendStage (new BirthsignCheckStage (mData.getBirthsigns()));
|
||||
|
||||
mVerifier->appendStage (new SpellCheckStage (mData.getSpells()));
|
||||
mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells()));
|
||||
|
||||
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
||||
mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
||||
|
||||
mVerifier->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions()));
|
||||
mVerifierOperation->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions()));
|
||||
|
||||
mVerifier->appendStage (new ScriptCheckStage (mDocument));
|
||||
mVerifierOperation->appendStage (new ScriptCheckStage (mDocument));
|
||||
|
||||
mVerifier->appendStage(
|
||||
mVerifierOperation->appendStage (new StartScriptCheckStage (mData.getStartScripts(), mData.getScripts()));
|
||||
|
||||
mVerifierOperation->appendStage(
|
||||
new BodyPartCheckStage(
|
||||
mData.getBodyParts(),
|
||||
mData.getResources(
|
||||
CSMWorld::UniversalId( CSMWorld::UniversalId::Type_Meshes )),
|
||||
mData.getRaces() ));
|
||||
|
||||
mVerifier.setOperation (mVerifierOperation);
|
||||
}
|
||||
|
||||
return mVerifier;
|
||||
return &mVerifier;
|
||||
}
|
||||
|
||||
CSMTools::Tools::Tools (CSMDoc::Document& document)
|
||||
: mDocument (document), mData (document.getData()), mVerifier (0), mNextReportNumber (0)
|
||||
: mDocument (document), mData (document.getData()), mVerifierOperation (0), mNextReportNumber (0)
|
||||
{
|
||||
// index 0: load error log
|
||||
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
|
||||
|
@ -108,7 +110,11 @@ CSMTools::Tools::Tools (CSMDoc::Document& document)
|
|||
|
||||
CSMTools::Tools::~Tools()
|
||||
{
|
||||
delete mVerifier;
|
||||
if (mVerifierOperation)
|
||||
{
|
||||
mVerifier.abortAndWait();
|
||||
delete mVerifierOperation;
|
||||
}
|
||||
|
||||
for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter)
|
||||
delete iter->second;
|
||||
|
@ -126,7 +132,7 @@ CSMWorld::UniversalId CSMTools::Tools::runVerifier()
|
|||
|
||||
void CSMTools::Tools::abortOperation (int type)
|
||||
{
|
||||
if (CSMDoc::Operation *operation = get (type))
|
||||
if (CSMDoc::OperationHolder *operation = get (type))
|
||||
operation->abort();
|
||||
}
|
||||
|
||||
|
@ -141,7 +147,7 @@ int CSMTools::Tools::getRunningOperations() const
|
|||
int result = 0;
|
||||
|
||||
for (int i=0; sOperations[i]!=-1; ++i)
|
||||
if (const CSMDoc::Operation *operation = get (sOperations[i]))
|
||||
if (const CSMDoc::OperationHolder *operation = get (sOperations[i]))
|
||||
if (operation->isRunning())
|
||||
result |= sOperations[i];
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
#include "../doc/operationholder.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data;
|
||||
|
@ -27,7 +29,8 @@ namespace CSMTools
|
|||
|
||||
CSMDoc::Document& mDocument;
|
||||
CSMWorld::Data& mData;
|
||||
CSMDoc::Operation *mVerifier;
|
||||
CSMDoc::Operation *mVerifierOperation;
|
||||
CSMDoc::OperationHolder mVerifier;
|
||||
std::map<int, ReportModel *> mReports;
|
||||
int mNextReportNumber;
|
||||
std::map<int, int> mActiveReports; // type, report number
|
||||
|
@ -36,12 +39,12 @@ namespace CSMTools
|
|||
Tools (const Tools&);
|
||||
Tools& operator= (const Tools&);
|
||||
|
||||
CSMDoc::Operation *getVerifier();
|
||||
CSMDoc::OperationHolder *getVerifier();
|
||||
|
||||
CSMDoc::Operation *get (int type);
|
||||
CSMDoc::OperationHolder *get (int type);
|
||||
///< Returns a 0-pointer, if operation hasn't been used yet.
|
||||
|
||||
const CSMDoc::Operation *get (int type) const;
|
||||
const CSMDoc::OperationHolder *get (int type) const;
|
||||
///< Returns a 0-pointer, if operation hasn't been used yet.
|
||||
|
||||
public:
|
||||
|
|
|
@ -21,4 +21,4 @@ namespace CSMWorld
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -28,4 +28,4 @@ int CSMWorld::CollectionBase::findColumnIndex (Columns::ColumnId id) const
|
|||
throw std::logic_error ("invalid column index");
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,4 +106,4 @@ namespace CSMWorld
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -22,4 +22,4 @@ std::string CSMWorld::ColumnBase::getTitle() const
|
|||
int CSMWorld::ColumnBase::getId() const
|
||||
{
|
||||
return mColumnId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,4 +264,4 @@ void CSMWorld::CommandDispatcher::executeExtendedRevert()
|
|||
|
||||
if (mExtendedTypes.size()>1)
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,4 +170,4 @@ void CSMWorld::CloneCommand::redo()
|
|||
void CSMWorld::CloneCommand::undo()
|
||||
{
|
||||
mModel.removeRow (mModel.getModelIndex (mId, 0).row());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace CSMWorld
|
|||
{
|
||||
class IdTable;
|
||||
class IdTable;
|
||||
class RecordBase;
|
||||
struct RecordBase;
|
||||
|
||||
class ModifyCommand : public QUndoCommand
|
||||
{
|
||||
|
@ -141,4 +141,4 @@ namespace CSMWorld
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -254,6 +254,10 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
|
|||
mPathgrids.addColumn (new RecordStateColumn<Pathgrid>);
|
||||
mPathgrids.addColumn (new FixedRecordTypeColumn<Pathgrid> (UniversalId::Type_Pathgrid));
|
||||
|
||||
mStartScripts.addColumn (new StringIdColumn<ESM::StartScript>);
|
||||
mStartScripts.addColumn (new RecordStateColumn<ESM::StartScript>);
|
||||
mStartScripts.addColumn (new FixedRecordTypeColumn<ESM::StartScript> (UniversalId::Type_StartScript));
|
||||
|
||||
mRefs.addColumn (new StringIdColumn<CellRef> (true));
|
||||
mRefs.addColumn (new RecordStateColumn<CellRef>);
|
||||
mRefs.addColumn (new FixedRecordTypeColumn<CellRef> (UniversalId::Type_Reference));
|
||||
|
@ -327,6 +331,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
|
|||
addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen);
|
||||
addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect);
|
||||
addModel (new IdTable (&mPathgrids), UniversalId::Type_Pathgrid);
|
||||
addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript);
|
||||
addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview),
|
||||
UniversalId::Type_Referenceable);
|
||||
addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference);
|
||||
|
@ -620,6 +625,16 @@ CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& CSMWorld::Data::getPathgrids()
|
|||
return mPathgrids;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::StartScript>& CSMWorld::Data::getStartScripts() const
|
||||
{
|
||||
return mStartScripts;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::StartScript>& CSMWorld::Data::getStartScripts()
|
||||
{
|
||||
return mStartScripts;
|
||||
}
|
||||
|
||||
const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id) const
|
||||
{
|
||||
return mResourcesManager.get (id.getType());
|
||||
|
@ -724,6 +739,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||
case ESM::REC_SNDG: mSoundGens.load (*mReader, mBase); break;
|
||||
case ESM::REC_MGEF: mMagicEffects.load (*mReader, mBase); break;
|
||||
case ESM::REC_PGRD: mPathgrids.load (*mReader, mBase); break;
|
||||
case ESM::REC_SSCR: mStartScripts.load (*mReader, mBase); break;
|
||||
|
||||
case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break;
|
||||
|
||||
|
@ -734,7 +750,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||
if (index!=-1 && !mBase)
|
||||
mLand.getRecord (index).mModified.mLand->loadData (
|
||||
ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR |
|
||||
ESM::Land::DATA_VTEX);
|
||||
ESM::Land::DATA_VTEX | ESM::Land::DATA_WNAM);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <components/esm/loadbody.hpp>
|
||||
#include <components/esm/loadsndg.hpp>
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
#include <components/esm/loadsscr.hpp>
|
||||
#include <components/esm/debugprofile.hpp>
|
||||
#include <components/esm/filter.hpp>
|
||||
|
||||
|
@ -87,6 +88,7 @@ namespace CSMWorld
|
|||
SubCellCollection<Pathgrid> mPathgrids;
|
||||
IdCollection<ESM::DebugProfile> mDebugProfiles;
|
||||
IdCollection<ESM::SoundGenerator> mSoundGens;
|
||||
IdCollection<ESM::StartScript> mStartScripts;
|
||||
InfoCollection mTopicInfos;
|
||||
InfoCollection mJournalInfos;
|
||||
IdCollection<Cell> mCells;
|
||||
|
@ -238,6 +240,10 @@ namespace CSMWorld
|
|||
|
||||
SubCellCollection<Pathgrid>& getPathgrids();
|
||||
|
||||
const IdCollection<ESM::StartScript>& getStartScripts() const;
|
||||
|
||||
IdCollection<ESM::StartScript>& getStartScripts();
|
||||
|
||||
/// Throws an exception, if \a id does not match a resources list.
|
||||
const Resources& getResources (const UniversalId& id) const;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
namespace CSMWorld
|
||||
{
|
||||
class CollectionBase;
|
||||
class RecordBase;
|
||||
struct RecordBase;
|
||||
|
||||
class IdTable : public IdTableBase
|
||||
{
|
||||
|
|
|
@ -6,4 +6,4 @@ CSMWorld::IdTableBase::IdTableBase (unsigned int features) : mFeatures (features
|
|||
unsigned int CSMWorld::IdTableBase::getFeatures() const
|
||||
{
|
||||
return mFeatures;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base)
|
|||
|
||||
if (!record2.get().mPrev.empty())
|
||||
{
|
||||
index = getIndex (record2.get().mPrev, topic);
|
||||
index = getInfoIndex (record2.get().mPrev, topic);
|
||||
|
||||
if (index!=-1)
|
||||
++index;
|
||||
|
@ -34,7 +34,7 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base)
|
|||
|
||||
if (index==-1 && !record2.get().mNext.empty())
|
||||
{
|
||||
index = getIndex (record2.get().mNext, topic);
|
||||
index = getInfoIndex (record2.get().mNext, topic);
|
||||
}
|
||||
|
||||
if (index==-1)
|
||||
|
@ -60,7 +60,7 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base)
|
|||
}
|
||||
}
|
||||
|
||||
int CSMWorld::InfoCollection::getIndex (const std::string& id, const std::string& topic) const
|
||||
int CSMWorld::InfoCollection::getInfoIndex (const std::string& id, const std::string& topic) const
|
||||
{
|
||||
std::string fullId = Misc::StringUtils::lowerCase (topic) + "#" + id;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace ESM
|
||||
{
|
||||
class Dialogue;
|
||||
struct Dialogue;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
|
@ -22,7 +22,7 @@ namespace CSMWorld
|
|||
|
||||
void load (const Info& record, bool base);
|
||||
|
||||
int getIndex (const std::string& id, const std::string& topic) const;
|
||||
int getInfoIndex (const std::string& id, const std::string& topic) const;
|
||||
///< Return index for record \a id or -1 (if not present; deleted records are considered)
|
||||
///
|
||||
/// \param id info ID without topic prefix
|
||||
|
@ -47,4 +47,4 @@ namespace CSMWorld
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -26,4 +26,4 @@ namespace CSMWorld
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -18,4 +18,4 @@ bool CSMWorld::RecordBase::isErased() const
|
|||
bool CSMWorld::RecordBase::isModified() const
|
||||
{
|
||||
return mState==State_Modified || mState==State_ModifiedOnly;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ namespace CSMWorld
|
|||
|
||||
virtual RecordBase *clone() const = 0;
|
||||
|
||||
virtual RecordBase *modifiedCopy() const = 0;
|
||||
|
||||
virtual void assign (const RecordBase& record) = 0;
|
||||
///< Will throw an exception if the types don't match.
|
||||
|
||||
|
@ -38,8 +40,15 @@ namespace CSMWorld
|
|||
ESXRecordT mBase;
|
||||
ESXRecordT mModified;
|
||||
|
||||
Record();
|
||||
|
||||
Record(State state,
|
||||
const ESXRecordT *base = 0, const ESXRecordT *modified = 0);
|
||||
|
||||
virtual RecordBase *clone() const;
|
||||
|
||||
virtual RecordBase *modifiedCopy() const;
|
||||
|
||||
virtual void assign (const RecordBase& record);
|
||||
|
||||
const ESXRecordT& get() const;
|
||||
|
@ -58,6 +67,29 @@ namespace CSMWorld
|
|||
///< Merge modified into base.
|
||||
};
|
||||
|
||||
template <typename ESXRecordT>
|
||||
Record<ESXRecordT>::Record()
|
||||
: mBase(), mModified()
|
||||
{ }
|
||||
|
||||
template <typename ESXRecordT>
|
||||
Record<ESXRecordT>::Record(State state, const ESXRecordT *base, const ESXRecordT *modified)
|
||||
{
|
||||
if(base)
|
||||
mBase = *base;
|
||||
|
||||
if(modified)
|
||||
mModified = *modified;
|
||||
|
||||
this->mState = state;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
RecordBase *Record<ESXRecordT>::modifiedCopy() const
|
||||
{
|
||||
return new Record<ESXRecordT> (State_ModifiedOnly, 0, &(this->get()));
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
RecordBase *Record<ESXRecordT>::clone() const
|
||||
{
|
||||
|
|
|
@ -5,4 +5,4 @@ CSMWorld::CellRef::CellRef()
|
|||
{
|
||||
mRefNum.mIndex = 0;
|
||||
mRefNum.mContentFile = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Cell;
|
||||
|
||||
/// \brief Wrapper for CellRef sub record
|
||||
struct CellRef : public ESM::CellRef
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
namespace CSMWorld
|
||||
{
|
||||
struct Cell;
|
||||
struct UniversalId;
|
||||
class UniversalId;
|
||||
|
||||
/// \brief References in cells
|
||||
class RefCollection : public Collection<CellRef>
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
|
||||
CSMWorld::RefIdAdapter::RefIdAdapter() {}
|
||||
|
||||
CSMWorld::RefIdAdapter::~RefIdAdapter() {}
|
||||
CSMWorld::RefIdAdapter::~RefIdAdapter() {}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace CSMWorld
|
|||
{
|
||||
class RefIdColumn;
|
||||
class RefIdData;
|
||||
class RecordBase;
|
||||
struct RecordBase;
|
||||
|
||||
class RefIdAdapter
|
||||
{
|
||||
|
@ -35,4 +35,4 @@ namespace CSMWorld
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -156,10 +156,16 @@ namespace CSMWorld
|
|||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
RecordT record2 = record.get();
|
||||
if (column==mModel.mModel)
|
||||
record.get().mModel = value.toString().toUtf8().constData();
|
||||
record2.mModel = value.toString().toUtf8().constData();
|
||||
else
|
||||
{
|
||||
BaseRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(record2);
|
||||
}
|
||||
|
||||
struct NameColumns : public ModelColumns
|
||||
|
@ -216,12 +222,18 @@ namespace CSMWorld
|
|||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
RecordT record2 = record.get();
|
||||
if (column==mName.mName)
|
||||
record.get().mName = value.toString().toUtf8().constData();
|
||||
record2.mName = value.toString().toUtf8().constData();
|
||||
else if (column==mName.mScript)
|
||||
record.get().mScript = value.toString().toUtf8().constData();
|
||||
record2.mScript = value.toString().toUtf8().constData();
|
||||
else
|
||||
{
|
||||
ModelRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(record2);
|
||||
}
|
||||
|
||||
struct InventoryColumns : public NameColumns
|
||||
|
@ -283,14 +295,20 @@ namespace CSMWorld
|
|||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
RecordT record2 = record.get();
|
||||
if (column==mInventory.mIcon)
|
||||
record.get().mIcon = value.toString().toUtf8().constData();
|
||||
record2.mIcon = value.toString().toUtf8().constData();
|
||||
else if (column==mInventory.mWeight)
|
||||
record.get().mData.mWeight = value.toFloat();
|
||||
record2.mData.mWeight = value.toFloat();
|
||||
else if (column==mInventory.mValue)
|
||||
record.get().mData.mValue = value.toInt();
|
||||
record2.mData.mValue = value.toInt();
|
||||
else
|
||||
{
|
||||
NameRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(record2);
|
||||
}
|
||||
|
||||
class PotionRefIdAdapter : public InventoryRefIdAdapter<ESM::Potion>
|
||||
|
@ -364,12 +382,18 @@ namespace CSMWorld
|
|||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
RecordT record2 = record.get();
|
||||
if (column==mEnchantable.mEnchantment)
|
||||
record.get().mEnchant = value.toString().toUtf8().constData();
|
||||
record2.mEnchant = value.toString().toUtf8().constData();
|
||||
else if (column==mEnchantable.mEnchantmentPoints)
|
||||
record.get().mData.mEnchant = value.toInt();
|
||||
record2.mData.mEnchant = value.toInt();
|
||||
else
|
||||
{
|
||||
InventoryRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(record2);
|
||||
}
|
||||
|
||||
struct ToolColumns : public InventoryColumns
|
||||
|
@ -426,12 +450,18 @@ namespace CSMWorld
|
|||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
RecordT record2 = record.get();
|
||||
if (column==mTools.mQuality)
|
||||
record.get().mData.mQuality = value.toFloat();
|
||||
record2.mData.mQuality = value.toFloat();
|
||||
else if (column==mTools.mUses)
|
||||
record.get().mData.mUses = value.toInt();
|
||||
record2.mData.mUses = value.toInt();
|
||||
else
|
||||
{
|
||||
InventoryRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(record2);
|
||||
}
|
||||
|
||||
struct ActorColumns : public NameColumns
|
||||
|
@ -508,16 +538,17 @@ namespace CSMWorld
|
|||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
RecordT record2 = record.get();
|
||||
if (column==mActors.mHasAi)
|
||||
record.get().mHasAI = value.toInt();
|
||||
record2.mHasAI = value.toInt();
|
||||
else if (column==mActors.mHello)
|
||||
record.get().mAiData.mHello = value.toInt();
|
||||
record2.mAiData.mHello = value.toInt();
|
||||
else if (column==mActors.mFlee)
|
||||
record.get().mAiData.mFlee = value.toInt();
|
||||
record2.mAiData.mFlee = value.toInt();
|
||||
else if (column==mActors.mFight)
|
||||
record.get().mAiData.mFight = value.toInt();
|
||||
record2.mAiData.mFight = value.toInt();
|
||||
else if (column==mActors.mAlarm)
|
||||
record.get().mAiData.mAlarm = value.toInt();
|
||||
record2.mAiData.mAlarm = value.toInt();
|
||||
else
|
||||
{
|
||||
typename std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
|
@ -525,13 +556,18 @@ namespace CSMWorld
|
|||
if (iter!=mActors.mServices.end())
|
||||
{
|
||||
if (value.toInt()!=0)
|
||||
record.get().mAiData.mServices |= iter->second;
|
||||
record2.mAiData.mServices |= iter->second;
|
||||
else
|
||||
record.get().mAiData.mServices &= ~iter->second;
|
||||
record2.mAiData.mServices &= ~iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
NameRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
record.setModified(record2);
|
||||
}
|
||||
|
||||
class ApparatusRefIdAdapter : public InventoryRefIdAdapter<ESM::Apparatus>
|
||||
|
|
|
@ -470,8 +470,7 @@ void CSMWorld::RefIdCollection::cloneRecord(const std::string& origin,
|
|||
const std::string& destination,
|
||||
const CSMWorld::UniversalId::Type type)
|
||||
{
|
||||
std::auto_ptr<RecordBase> newRecord(mData.getRecord(mData.searchId(origin)).clone());
|
||||
newRecord->mState = RecordBase::State_ModifiedOnly;
|
||||
std::auto_ptr<RecordBase> newRecord(mData.getRecord(mData.searchId(origin)).modifiedCopy());
|
||||
mAdapters.find(type)->second->setId(*newRecord, destination);
|
||||
mData.insertRecord(*newRecord, type, destination);
|
||||
}
|
||||
|
|
|
@ -503,4 +503,4 @@ void CSMWorld::RegionMap::cellsChanged (const QModelIndex& topLeft, const QModel
|
|||
// columns we are interested in. If not we can exit the function here and avoid all updating.
|
||||
|
||||
addCells (topLeft.row(), bottomRight.row());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,4 +143,4 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::ResourceTable::view (int
|
|||
bool CSMWorld::ResourceTable::isDeleted (const std::string& id) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,4 +22,4 @@ CSMWorld::Scope CSMWorld::getScopeFromId (const std::string& id)
|
|||
return Scope_Session;
|
||||
|
||||
return Scope_Content;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,4 +120,4 @@ void CSMWorld::ScriptContext::clear()
|
|||
mIds.clear();
|
||||
mIdsUpdated = false;
|
||||
mLocals.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_SoundGens, "Sound Generators", 0 },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MagicEffects, "Magic Effects", 0 },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Pathgrids, "Pathgrids", 0 },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_StartScripts, "Start Scripts", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
@ -118,6 +119,7 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_SoundGen, "Sound Generator", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MagicEffect, "Magic Effect", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_StartScript, "Start Script", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
|
|
@ -128,6 +128,8 @@ namespace CSMWorld
|
|||
Type_MagicEffect,
|
||||
Type_Pathgrids,
|
||||
Type_Pathgrid,
|
||||
Type_StartScripts,
|
||||
Type_StartScript,
|
||||
Type_RunLog
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
@ -72,8 +73,11 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
|
|||
{
|
||||
boost::filesystem::path path (name.toUtf8().data());
|
||||
|
||||
bool isLegacyPath = (path.extension() == ".esm" ||
|
||||
path.extension() == ".esp");
|
||||
std::string extension = path.extension().string();
|
||||
boost::algorithm::to_lower(extension);
|
||||
|
||||
bool isLegacyPath = (extension == ".esm" ||
|
||||
extension == ".esp");
|
||||
|
||||
bool isFilePathChanged = (path.parent_path().string() != mLocalData.string());
|
||||
|
||||
|
|
|
@ -147,17 +147,19 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(int)
|
|||
|
||||
void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool)
|
||||
{
|
||||
bool success = (mSelector->selectedFiles().size() > 0);
|
||||
bool success = !mSelector->selectedFiles().empty();
|
||||
|
||||
bool isNew = (mAction == ContentAction_New);
|
||||
|
||||
if (isNew)
|
||||
success = success && !(name.isEmpty());
|
||||
else
|
||||
else if (success)
|
||||
{
|
||||
ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back();
|
||||
mAdjusterWidget->setName (file->filePath(), !file->isGameFile());
|
||||
}
|
||||
else
|
||||
mAdjusterWidget->setName ("", true);
|
||||
|
||||
ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success);
|
||||
}
|
||||
|
|
|
@ -90,4 +90,4 @@ void CSVDoc::GlobalDebugProfileMenu::profileChanged (const QModelIndex& topLeft,
|
|||
void CSVDoc::GlobalDebugProfileMenu::actionTriggered (QAction *action)
|
||||
{
|
||||
emit triggered (std::string (action->text().toUtf8().constData()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event)
|
|||
CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document)
|
||||
: mDocument (document), mAborted (false), mMessages (0), mTotalRecords (0)
|
||||
{
|
||||
setWindowTitle (("Opening " + document->getSavePath().filename().string()).c_str());
|
||||
setWindowTitle (QString::fromUtf8((std::string("Opening ") + document->getSavePath().filename().string()).c_str()));
|
||||
|
||||
setMinimumWidth (400);
|
||||
|
||||
|
|
|
@ -17,4 +17,4 @@ CSVDoc::RunLogSubView::RunLogSubView (const CSMWorld::UniversalId& id,
|
|||
void CSVDoc::RunLogSubView::setEditLock (bool locked)
|
||||
{
|
||||
// ignored since this SubView does not have editing
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ QWidget *CSVDoc::StartupDialogue::createTools()
|
|||
|
||||
CSVDoc::StartupDialogue::StartupDialogue() : mWidth (0), mColumn (2)
|
||||
{
|
||||
setWindowTitle ("Open CS");
|
||||
setWindowTitle ("OpenMW-CS");
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout (this);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ void CSVDoc::SubView::updateUserSetting (const QString &, const QStringList &)
|
|||
void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id)
|
||||
{
|
||||
mUniversalId = id;
|
||||
setWindowTitle (mUniversalId.toString().c_str());
|
||||
setWindowTitle (QString::fromUtf8(mUniversalId.toString().c_str()));
|
||||
}
|
||||
|
||||
void CSVDoc::SubView::closeEvent (QCloseEvent *event)
|
||||
|
|
|
@ -35,4 +35,4 @@ CSVDoc::SubView *CSVDoc::SubViewFactoryManager::makeSubView (const CSMWorld::Uni
|
|||
throw std::runtime_error ("Failed to create a sub view for: " + id.toString());
|
||||
|
||||
return iter->second->makeSubView (id, document);
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue