Merge branch 'master' into osgshadow-test-vdsm

pull/541/head
AnyOldName3 6 years ago
commit e2515f6db7

1
.gitignore vendored

@ -81,5 +81,4 @@ moc_*.cxx
*ui_playpage.h *ui_playpage.h
*.[ao] *.[ao]
*.so *.so
openmw.appdata.xml
venv/ venv/

@ -15,8 +15,8 @@ Debian:
- apt-get update -yq - apt-get update -yq
- apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt4-dev libopenal-dev libopenscenegraph-3.4-dev libunshield-dev libtinyxml-dev - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt4-dev libopenal-dev libopenscenegraph-3.4-dev libunshield-dev libtinyxml-dev
# - apt-get install -y libmygui-dev libbullet-dev # to be updated to latest below because stretch is too old # - apt-get install -y libmygui-dev libbullet-dev # to be updated to latest below because stretch is too old
- curl -L http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet-dev_2.87+dfsg-2_amd64.deb -o libbullet-dev_2.87+dfsg-2_amd64.deb - curl -L http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet-dev_2.87+dfsg-3_amd64.deb -o libbullet-dev_2.87+dfsg-3_amd64.deb
- curl -L http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet2.87_2.87+dfsg-2_amd64.deb -o libbullet2.87_2.87+dfsg-2_amd64.deb - curl -L http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet2.87_2.87+dfsg-3_amd64.deb -o libbullet2.87_2.87+dfsg-3_amd64.deb
- curl -L https://http.kali.org/pool/main/m/mygui/libmygui.openglplatform0debian1v5_3.2.2+dfsg-1_amd64.deb -o libmygui.openglplatform0debian1v5_3.2.2+dfsg-1_amd64.deb - curl -L https://http.kali.org/pool/main/m/mygui/libmygui.openglplatform0debian1v5_3.2.2+dfsg-1_amd64.deb -o libmygui.openglplatform0debian1v5_3.2.2+dfsg-1_amd64.deb
- curl -L https://http.kali.org/pool/main/m/mygui/libmyguiengine3debian1v5_3.2.2+dfsg-1_amd64.deb -o libmyguiengine3debian1v5_3.2.2+dfsg-1_amd64.deb - curl -L https://http.kali.org/pool/main/m/mygui/libmyguiengine3debian1v5_3.2.2+dfsg-1_amd64.deb -o libmyguiengine3debian1v5_3.2.2+dfsg-1_amd64.deb
- curl -L https://http.kali.org/pool/main/m/mygui/libmygui-dev_3.2.2+dfsg-1_amd64.deb -o libmygui-dev_3.2.2+dfsg-1_amd64.deb - curl -L https://http.kali.org/pool/main/m/mygui/libmygui-dev_3.2.2+dfsg-1_amd64.deb -o libmygui-dev_3.2.2+dfsg-1_amd64.deb

@ -8,9 +8,14 @@
Bug #4715: "Cannot get class of an empty object" exception after pressing ESC in the dialogue mode Bug #4715: "Cannot get class of an empty object" exception after pressing ESC in the dialogue mode
Bug #4720: Inventory avatar has shield with two-handed weapon during [un]equipping animation Bug #4720: Inventory avatar has shield with two-handed weapon during [un]equipping animation
Bug #4723: ResetActors command works incorrectly Bug #4723: ResetActors command works incorrectly
Bug #4745: Editor: Interior cell lighting field values are not displayed as colors
Bug #4746: Non-solid player can't run or sneak
Bug #4750: Sneaking doesn't work in first person view if the player is in attack ready state
Feature #2229: Improve pathfinding AI Feature #2229: Improve pathfinding AI
Feature #3442: Default values for fallbacks from ini file Feature #3442: Default values for fallbacks from ini file
Feature #3610: Option to invert X axis
Feature #4673: Weapon sheathing Feature #4673: Weapon sheathing
Feature #4730: Native animated containers support
Task #4686: Upgrade media decoder to a more current FFmpeg API Task #4686: Upgrade media decoder to a more current FFmpeg API
0.45.0 0.45.0

@ -31,6 +31,7 @@ SKIP_EXTRACT=""
KEEP="" KEEP=""
UNITY_BUILD="" UNITY_BUILD=""
VS_VERSION="" VS_VERSION=""
NMAKE=""
PLATFORM="" PLATFORM=""
CONFIGURATION="" CONFIGURATION=""
@ -66,6 +67,9 @@ while [ $# -gt 0 ]; do
VS_VERSION=$1 VS_VERSION=$1
shift ;; shift ;;
n )
NMAKE=true ;;
p ) p )
PLATFORM=$1 PLATFORM=$1
shift ;; shift ;;
@ -94,6 +98,8 @@ Options:
Configure for unity builds. Configure for unity builds.
-v <2013/2015/2017> -v <2013/2015/2017>
Choose the Visual Studio version to use. Choose the Visual Studio version to use.
-n
Produce NMake makefiles instead of a Visual Studio solution.
-V -V
Run verbosely Run verbosely
EOF EOF
@ -108,6 +114,10 @@ EOF
done done
done done
if [ -n "$NMAKE" ]; then
command -v nmake -? >/dev/null 2>&1 || { echo "Error: nmake (NMake) is not on the path. Make sure you have the necessary environment variables set for command-line C++ development (for example, by starting from a Developer Command Prompt)."; exit 1; }
fi
if [ -z $VERBOSE ]; then if [ -z $VERBOSE ]; then
STRIP="> /dev/null 2>&1" STRIP="> /dev/null 2>&1"
fi fi
@ -267,18 +277,12 @@ case $PLATFORM in
ARCHNAME="x86-64" ARCHNAME="x86-64"
ARCHSUFFIX="64" ARCHSUFFIX="64"
BITS="64" BITS="64"
BASE_OPTS="-G\"$GENERATOR Win64\""
add_cmake_opts "-G\"$GENERATOR Win64\""
;; ;;
x32|x86|i686|i386|win32|Win32 ) x32|x86|i686|i386|win32|Win32 )
ARCHNAME="x86" ARCHNAME="x86"
ARCHSUFFIX="86" ARCHSUFFIX="86"
BITS="32" BITS="32"
BASE_OPTS="-G\"$GENERATOR\""
add_cmake_opts "-G\"$GENERATOR\""
;; ;;
* ) * )
@ -304,14 +308,24 @@ case $CONFIGURATION in
;; ;;
esac esac
if ! [ -z $UNITY_BUILD ]; then
add_cmake_opts "-DOPENMW_UNITY_BUILD=True"
fi
if [ ${BITS} -eq 64 ]; then if [ ${BITS} -eq 64 ]; then
GENERATOR="${GENERATOR} Win64" GENERATOR="${GENERATOR} Win64"
fi fi
if [ -n "$NMAKE" ]; then
GENERATOR="NMake Makefiles"
fi
add_cmake_opts "-G\"$GENERATOR\""
if [ -n "$NMAKE" ]; then
add_cmake_opts "-DCMAKE_BUILD_TYPE=${BUILD_CONFIG}"
fi
if ! [ -z $UNITY_BUILD ]; then
add_cmake_opts "-DOPENMW_UNITY_BUILD=True"
fi
echo echo
echo "===================================" echo "==================================="
echo "Starting prebuild on MSVC${MSVC_DISPLAY_YEAR} WIN${BITS}" echo "Starting prebuild on MSVC${MSVC_DISPLAY_YEAR} WIN${BITS}"
@ -387,6 +401,11 @@ cd .. #/..
# Set up dependencies # Set up dependencies
BUILD_DIR="MSVC${MSVC_DISPLAY_YEAR}_${BITS}" BUILD_DIR="MSVC${MSVC_DISPLAY_YEAR}_${BITS}"
if [ -n "$NMAKE" ]; then
BUILD_DIR="${BUILD_DIR}_NMake_${BUILD_CONFIG}"
fi
if [ -z $KEEP ]; then if [ -z $KEEP ]; then
echo echo
echo "(Re)Creating build directory." echo "(Re)Creating build directory."
@ -696,7 +715,11 @@ fi
# NOTE: Disable this when/if we want to run test cases # NOTE: Disable this when/if we want to run test cases
#if [ -z $CI ]; then #if [ -z $CI ]; then
echo "- Copying Runtime DLLs..." echo "- Copying Runtime DLLs..."
mkdir -p $BUILD_CONFIG DLL_PREFIX=""
if [ -z $NMAKE ]; then
mkdir -p $BUILD_CONFIG
DLL_PREFIX="$BUILD_CONFIG/"
fi
for DLL in $RUNTIME_DLLS; do for DLL in $RUNTIME_DLLS; do
TARGET="$(basename "$DLL")" TARGET="$(basename "$DLL")"
if [[ "$DLL" == *":"* ]]; then if [[ "$DLL" == *":"* ]]; then
@ -705,21 +728,21 @@ fi
TARGET=${SPLIT[1]} TARGET=${SPLIT[1]}
fi fi
echo " ${TARGET}." echo " ${TARGET}."
cp "$DLL" "$BUILD_CONFIG/$TARGET" cp "$DLL" "${DLL_PREFIX}$TARGET"
done done
echo echo
echo "- OSG Plugin DLLs..." echo "- OSG Plugin DLLs..."
mkdir -p $BUILD_CONFIG/osgPlugins-3.4.1 mkdir -p ${DLL_PREFIX}osgPlugins-3.4.1
for DLL in $OSG_PLUGINS; do for DLL in $OSG_PLUGINS; do
echo " $(basename $DLL)." echo " $(basename $DLL)."
cp "$DLL" $BUILD_CONFIG/osgPlugins-3.4.1 cp "$DLL" ${DLL_PREFIX}osgPlugins-3.4.1
done done
echo echo
echo "- Qt Platform DLLs..." echo "- Qt Platform DLLs..."
mkdir -p ${BUILD_CONFIG}/platforms mkdir -p ${DLL_PREFIX}platforms
for DLL in $QT_PLATFORMS; do for DLL in $QT_PLATFORMS; do
echo " $(basename $DLL)" echo " $(basename $DLL)"
cp "$DLL" "${BUILD_CONFIG}/platforms" cp "$DLL" "${DLL_PREFIX}platforms"
done done
echo echo
#fi #fi

@ -59,6 +59,7 @@ set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_VERSION_COMMITHASH "") set(OPENMW_VERSION_COMMITHASH "")
set(OPENMW_VERSION_TAGHASH "") set(OPENMW_VERSION_TAGHASH "")
set(OPENMW_VERSION_COMMITDATE "")
set(OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") set(OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
@ -71,6 +72,18 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git)
else(GIT_FOUND) else(GIT_FOUND)
message(WARNING "Git executable not found") message(WARNING "Git executable not found")
endif(GIT_FOUND) endif(GIT_FOUND)
if(GIT_FOUND)
execute_process (
COMMAND ${GIT_EXECUTABLE} log -1 --format='%aI'
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE EXITCODE3
OUTPUT_VARIABLE OPENMW_VERSION_COMMITDATE
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT EXITCODE3)
string(SUBSTRING ${OPENMW_VERSION_COMMITDATE} 1 10 OPENMW_VERSION_COMMITDATE)
endif(NOT EXITCODE3)
endif(GIT_FOUND)
endif(EXISTS ${PROJECT_SOURCE_DIR}/.git) endif(EXISTS ${PROJECT_SOURCE_DIR}/.git)
# Macros # Macros
@ -256,8 +269,14 @@ set(USED_OSG_PLUGINS
osgdb_tga osgdb_tga
) )
get_filename_component(OSG_LIB_DIR ${OSGDB_LIBRARY} DIRECTORY) set(OSGPlugins_LIB_DIR "")
set(OSGPlugins_LIB_DIR "${OSG_LIB_DIR}/osgPlugins-${OPENSCENEGRAPH_VERSION}") foreach(OSGDB_LIB ${OSGDB_LIBRARY})
# Skip library type names
if(EXISTS ${OSGDB_LIB} AND NOT IS_DIRECTORY ${OSGDB_LIB})
get_filename_component(OSG_LIB_DIR ${OSGDB_LIB} DIRECTORY)
list(APPEND OSGPlugins_LIB_DIR "${OSG_LIB_DIR}/osgPlugins-${OPENSCENEGRAPH_VERSION}")
endif()
endforeach(OSGDB_LIB)
if(OSG_STATIC) if(OSG_STATIC)
add_definitions(-DOSG_LIBRARY_STATIC) add_definitions(-DOSG_LIBRARY_STATIC)
@ -346,6 +365,9 @@ endif (APPLE)
configure_resource_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg configure_resource_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
"${OpenMW_BINARY_DIR}" "settings-default.cfg") "${OpenMW_BINARY_DIR}" "settings-default.cfg")
configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw.appdata.xml
"${OpenMW_BINARY_DIR}" "openmw.appdata.xml")
if (NOT APPLE) if (NOT APPLE)
configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
"${OpenMW_BINARY_DIR}" "openmw.cfg") "${OpenMW_BINARY_DIR}" "openmw.cfg")
@ -807,15 +829,24 @@ if (OPENMW_OSX_DEPLOYMENT AND APPLE AND DESIRED_QT_VERSION MATCHES 5)
set(ABSOLUTE_PLUGINS "") set(ABSOLUTE_PLUGINS "")
set(OSGPlugins_DONT_FIND_DEPENDENCIES 1)
find_package(OSGPlugins REQUIRED COMPONENTS ${USED_OSG_PLUGINS})
foreach (PLUGIN_NAME ${USED_OSG_PLUGINS}) foreach (PLUGIN_NAME ${USED_OSG_PLUGINS})
set(PLUGIN_ABS "${OSGPlugins_LIB_DIR}/${PLUGIN_NAME}.so") string(TOUPPER ${PLUGIN_NAME} PLUGIN_NAME_UC)
set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS}) if(${PLUGIN_NAME_UC}_LIBRARY_RELEASE)
set(PLUGIN_ABS ${${PLUGIN_NAME_UC}_LIBRARY_RELEASE})
elseif(${PLUGIN_NAME_UC}_LIBRARY)
set(PLUGIN_ABS ${${PLUGIN_NAME_UC}_LIBRARY})
else()
message(FATAL_ERROR "Can't find library file for ${PLUGIN_NAME}")
# We used to construct the path manually from OSGPlugins_LIB_DIR and the plugin name.
# Maybe that could be restored as a fallback?
endif()
set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS})
endforeach () endforeach ()
get_filename_component(OSG_PLUGIN_PREFIX_DIR "${OSGPlugins_LIB_DIR}" NAME) set(OSG_PLUGIN_PREFIX_DIR "osgPlugins-${OPENSCENEGRAPH_VERSION}")
if (NOT OSG_PLUGIN_PREFIX_DIR)
message(FATAL_ERROR "Can't get directory name for OSG plugins from '${OSGPlugins_LIB_DIR}'")
endif()
# installs used plugins in bundle at given path (bundle_path must be relative to ${CMAKE_INSTALL_PREFIX}) # installs used plugins in bundle at given path (bundle_path must be relative to ${CMAKE_INSTALL_PREFIX})
# and returns list of install paths for all installed plugins # and returns list of install paths for all installed plugins

@ -406,13 +406,10 @@ int load(Arguments& info)
} catch(std::exception &e) { } catch(std::exception &e) {
std::cout << "\nERROR:\n\n " << e.what() << std::endl; std::cout << "\nERROR:\n\n " << e.what() << std::endl;
typedef std::deque<EsmTool::RecordBase *> RecStore; for (const EsmTool::RecordBase* record : info.data.mRecords)
RecStore &store = info.data.mRecords; delete record;
for (RecStore::iterator it = store.begin(); it != store.end(); ++it)
{ info.data.mRecords.clear();
delete *it;
}
store.clear();
return 1; return 1;
} }
@ -444,15 +441,12 @@ int clone(Arguments& info)
std::cout << "Loaded " << recordCount << " records:" << std::endl << std::endl; std::cout << "Loaded " << recordCount << " records:" << std::endl << std::endl;
int i = 0; int i = 0;
typedef std::map<int, int> Stats; for (std::pair<int, int> stat : info.data.mRecordStats)
Stats &stats = info.data.mRecordStats;
for (Stats::iterator it = stats.begin(); it != stats.end(); ++it)
{ {
ESM::NAME name; ESM::NAME name;
name.intval = it->first; name.intval = stat.first;
int amount = it->second; int amount = stat.second;
std::cout << std::setw(digitCount) << amount << " " << name.toString() << " "; std::cout << std::setw(digitCount) << amount << " " << name.toString() << " ";
if (++i % 3 == 0) if (++i % 3 == 0)
std::cout << std::endl; std::cout << std::endl;
} }
@ -470,18 +464,18 @@ int clone(Arguments& info)
esm.setVersion(info.data.version); esm.setVersion(info.data.version);
esm.setRecordCount (recordCount); esm.setRecordCount (recordCount);
for (std::vector<ESM::Header::MasterData>::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it) for (const ESM::Header::MasterData &master : info.data.masters)
esm.addMaster(it->name, it->size); esm.addMaster(master.name, master.size);
std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary); std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary);
esm.save(save); esm.save(save);
int saved = 0; int saved = 0;
typedef std::deque<EsmTool::RecordBase *> Records; for (EsmTool::RecordBase* record : info.data.mRecords)
Records &records = info.data.mRecords;
for (Records::iterator it = records.begin(); it != records.end() && i > 0; ++it)
{ {
EsmTool::RecordBase *record = *it; if (i <= 0)
break;
const ESM::NAME& typeName = record->getType(); const ESM::NAME& typeName = record->getType();
esm.startRecord(typeName.toString(), record->getFlags()); esm.startRecord(typeName.toString(), record->getFlags());
@ -489,13 +483,10 @@ int clone(Arguments& info)
record->save(esm); record->save(esm);
if (typeName.intval == ESM::REC_CELL) { if (typeName.intval == ESM::REC_CELL) {
ESM::Cell *ptr = &record->cast<ESM::Cell>()->get(); ESM::Cell *ptr = &record->cast<ESM::Cell>()->get();
if (!info.data.mCellRefs[ptr].empty()) { if (!info.data.mCellRefs[ptr].empty())
typedef std::deque<std::pair<ESM::CellRef, bool> > RefList; {
RefList &refs = info.data.mCellRefs[ptr]; for (std::pair<ESM::CellRef, bool> &ref : info.data.mCellRefs[ptr])
for (RefList::iterator refIt = refs.begin(); refIt != refs.end(); ++refIt) ref.first.save(esm, ref.second);
{
refIt->first.save(esm, refIt->second);
}
} }
} }
@ -558,8 +549,5 @@ int comp(Arguments& info)
return 1; return 1;
} }
return 0; return 0;
} }

@ -651,7 +651,7 @@ std::string ruleFunction(int idx)
std::string bodyPartFlags(int flags) std::string bodyPartFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::BodyPart::BPF_Female) properties += "Female "; if (flags & ESM::BodyPart::BPF_Female) properties += "Female ";
if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable "; if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable ";
@ -665,7 +665,7 @@ std::string bodyPartFlags(int flags)
std::string cellFlags(int flags) std::string cellFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::Cell::HasWater) properties += "HasWater "; if (flags & ESM::Cell::HasWater) properties += "HasWater ";
if (flags & ESM::Cell::Interior) properties += "Interior "; if (flags & ESM::Cell::Interior) properties += "Interior ";
@ -686,7 +686,7 @@ std::string cellFlags(int flags)
std::string containerFlags(int flags) std::string containerFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::Container::Unknown) properties += "Unknown "; if (flags & ESM::Container::Unknown) properties += "Unknown ";
if (flags & ESM::Container::Organic) properties += "Organic "; if (flags & ESM::Container::Organic) properties += "Organic ";
@ -702,7 +702,7 @@ std::string containerFlags(int flags)
std::string creatureFlags(int flags) std::string creatureFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::Creature::None) properties += "All "; if (flags & ESM::Creature::None) properties += "All ";
if (flags & ESM::Creature::Walks) properties += "Walks "; if (flags & ESM::Creature::Walks) properties += "Walks ";
@ -732,7 +732,7 @@ std::string creatureFlags(int flags)
std::string landFlags(int flags) std::string landFlags(int flags)
{ {
std::string properties = ""; std::string properties;
// The ESM component says that this first four bits are used, but // The ESM component says that this first four bits are used, but
// only the first three bits are used as far as I can tell. // only the first three bits are used as far as I can tell.
// There's also no enumeration of the bit in the ESM component. // There's also no enumeration of the bit in the ESM component.
@ -747,7 +747,7 @@ std::string landFlags(int flags)
std::string itemListFlags(int flags) std::string itemListFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::ItemLevList::AllLevels) properties += "AllLevels "; if (flags & ESM::ItemLevList::AllLevels) properties += "AllLevels ";
if (flags & ESM::ItemLevList::Each) properties += "Each "; if (flags & ESM::ItemLevList::Each) properties += "Each ";
@ -761,7 +761,7 @@ std::string itemListFlags(int flags)
std::string creatureListFlags(int flags) std::string creatureListFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::CreatureLevList::AllLevels) properties += "AllLevels "; if (flags & ESM::CreatureLevList::AllLevels) properties += "AllLevels ";
int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels); int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels);
@ -800,7 +800,7 @@ std::string lightFlags(int flags)
std::string magicEffectFlags(int flags) std::string magicEffectFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::MagicEffect::TargetAttribute) properties += "TargetAttribute "; if (flags & ESM::MagicEffect::TargetAttribute) properties += "TargetAttribute ";
if (flags & ESM::MagicEffect::TargetSkill) properties += "TargetSkill "; if (flags & ESM::MagicEffect::TargetSkill) properties += "TargetSkill ";
@ -826,7 +826,7 @@ std::string magicEffectFlags(int flags)
std::string npcFlags(int flags) std::string npcFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
// Mythicmods and the ESM component differ. Mythicmods says // Mythicmods and the ESM component differ. Mythicmods says
// 0x8=None and 0x10=AutoCalc, while our code previously defined // 0x8=None and 0x10=AutoCalc, while our code previously defined
@ -860,7 +860,7 @@ std::string npcFlags(int flags)
std::string raceFlags(int flags) std::string raceFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
// All races have the playable flag set in Bethesda files. // All races have the playable flag set in Bethesda files.
if (flags & ESM::Race::Playable) properties += "Playable "; if (flags & ESM::Race::Playable) properties += "Playable ";
@ -875,7 +875,7 @@ std::string raceFlags(int flags)
std::string spellFlags(int flags) std::string spellFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::Spell::F_Autocalc) properties += "Autocalc "; if (flags & ESM::Spell::F_Autocalc) properties += "Autocalc ";
if (flags & ESM::Spell::F_PCStart) properties += "PCStart "; if (flags & ESM::Spell::F_PCStart) properties += "PCStart ";
@ -891,7 +891,7 @@ std::string spellFlags(int flags)
std::string weaponFlags(int flags) std::string weaponFlags(int flags)
{ {
std::string properties = ""; std::string properties;
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
// The interpretation of the flags are still unclear to me. // The interpretation of the flags are still unclear to me.
// Apparently you can't be Silver without being Magical? Many of // Apparently you can't be Silver without being Magical? Many of

@ -49,7 +49,7 @@ void printAIPackage(ESM::AIPackage p)
std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl; std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl;
} }
if (p.mCellName != "") if (!p.mCellName.empty())
std::cout << " Cell Name: " << p.mCellName << std::endl; std::cout << " Cell Name: " << p.mCellName << std::endl;
} }
@ -130,43 +130,41 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
void printEffectList(ESM::EffectList effects) void printEffectList(ESM::EffectList effects)
{ {
int i = 0; int i = 0;
std::vector<ESM::ENAMstruct>::iterator eit; for (const ESM::ENAMstruct& effect : effects.mList)
for (eit = effects.mList.begin(); eit != effects.mList.end(); ++eit) {
{ std::cout << " Effect[" << i << "]: " << magicEffectLabel(effect.mEffectID)
std::cout << " Effect[" << i << "]: " << magicEffectLabel(eit->mEffectID) << " (" << effect.mEffectID << ")" << std::endl;
<< " (" << eit->mEffectID << ")" << std::endl; if (effect.mSkill != -1)
if (eit->mSkill != -1) std::cout << " Skill: " << skillLabel(effect.mSkill)
std::cout << " Skill: " << skillLabel(eit->mSkill) << " (" << (int)effect.mSkill << ")" << std::endl;
<< " (" << (int)eit->mSkill << ")" << std::endl; if (effect.mAttribute != -1)
if (eit->mAttribute != -1) std::cout << " Attribute: " << attributeLabel(effect.mAttribute)
std::cout << " Attribute: " << attributeLabel(eit->mAttribute) << " (" << (int)effect.mAttribute << ")" << std::endl;
<< " (" << (int)eit->mAttribute << ")" << std::endl; std::cout << " Range: " << rangeTypeLabel(effect.mRange)
std::cout << " Range: " << rangeTypeLabel(eit->mRange) << " (" << effect.mRange << ")" << std::endl;
<< " (" << eit->mRange << ")" << std::endl;
// Area is always zero if range type is "Self" // Area is always zero if range type is "Self"
if (eit->mRange != ESM::RT_Self) if (effect.mRange != ESM::RT_Self)
std::cout << " Area: " << eit->mArea << std::endl; std::cout << " Area: " << effect.mArea << std::endl;
std::cout << " Duration: " << eit->mDuration << std::endl; std::cout << " Duration: " << effect.mDuration << std::endl;
std::cout << " Magnitude: " << eit->mMagnMin << "-" << eit->mMagnMax << std::endl; std::cout << " Magnitude: " << effect.mMagnMin << "-" << effect.mMagnMax << std::endl;
i++; i++;
} }
} }
void printTransport(const std::vector<ESM::Transport::Dest>& transport) void printTransport(const std::vector<ESM::Transport::Dest>& transport)
{ {
std::vector<ESM::Transport::Dest>::const_iterator dit; for (const ESM::Transport::Dest& dest : transport)
for (dit = transport.begin(); dit != transport.end(); ++dit)
{ {
std::cout << " Destination Position: " std::cout << " Destination Position: "
<< boost::format("%12.3f") % dit->mPos.pos[0] << "," << boost::format("%12.3f") % dest.mPos.pos[0] << ","
<< boost::format("%12.3f") % dit->mPos.pos[1] << "," << boost::format("%12.3f") % dest.mPos.pos[1] << ","
<< boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; << boost::format("%12.3f") % dest.mPos.pos[2] << ")" << std::endl;
std::cout << " Destination Rotation: " std::cout << " Destination Rotation: "
<< boost::format("%9.6f") % dit->mPos.rot[0] << "," << boost::format("%9.6f") % dest.mPos.rot[0] << ","
<< boost::format("%9.6f") % dit->mPos.rot[1] << "," << boost::format("%9.6f") % dest.mPos.rot[1] << ","
<< boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; << boost::format("%9.6f") % dest.mPos.rot[2] << ")" << std::endl;
if (dit->mCellName != "") if (!dest.mCellName.empty())
std::cout << " Destination Cell: " << dit->mCellName << std::endl; std::cout << " Destination Cell: " << dest.mCellName << std::endl;
} }
} }
@ -414,7 +412,7 @@ void Record<ESM::Potion>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
@ -429,9 +427,9 @@ void Record<ESM::Armor>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
if (mData.mEnchant != "") if (!mData.mEnchant.empty())
std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Enchantment: " << mData.mEnchant << std::endl;
std::cout << " Type: " << armorTypeLabel(mData.mData.mType) std::cout << " Type: " << armorTypeLabel(mData.mData.mType)
<< " (" << mData.mData.mType << ")" << std::endl; << " (" << mData.mData.mType << ")" << std::endl;
@ -440,15 +438,15 @@ void Record<ESM::Armor>::print()
std::cout << " Health: " << mData.mData.mHealth << std::endl; std::cout << " Health: " << mData.mData.mHealth << std::endl;
std::cout << " Armor: " << mData.mData.mArmor << std::endl; std::cout << " Armor: " << mData.mData.mArmor << std::endl;
std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl;
std::vector<ESM::PartReference>::iterator pit; for (const ESM::PartReference &part : mData.mParts.mParts)
for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); ++pit)
{ {
std::cout << " Body Part: " << bodyPartLabel(pit->mPart) std::cout << " Body Part: " << bodyPartLabel(part.mPart)
<< " (" << (int)(pit->mPart) << ")" << std::endl; << " (" << (int)(part.mPart) << ")" << std::endl;
std::cout << " Male Name: " << pit->mMale << std::endl; std::cout << " Male Name: " << part.mMale << std::endl;
if (pit->mFemale != "") if (!part.mFemale.empty())
std::cout << " Female Name: " << pit->mFemale << std::endl; std::cout << " Female Name: " << part.mFemale << std::endl;
} }
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -487,9 +485,9 @@ void Record<ESM::Book>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
if (mData.mEnchant != "") if (!mData.mEnchant.empty())
std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Enchantment: " << mData.mEnchant << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
@ -516,9 +514,8 @@ void Record<ESM::BirthSign>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Texture: " << mData.mTexture << std::endl; std::cout << " Texture: " << mData.mTexture << std::endl;
std::cout << " Description: " << mData.mDescription << std::endl; std::cout << " Description: " << mData.mDescription << std::endl;
std::vector<std::string>::iterator pit; for (const std::string &power : mData.mPowers.mList)
for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); ++pit) std::cout << " Power: " << power << std::endl;
std::cout << " Power: " << *pit << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -526,9 +523,9 @@ template<>
void Record<ESM::Cell>::print() void Record<ESM::Cell>::print()
{ {
// None of the cells have names... // None of the cells have names...
if (mData.mName != "") if (!mData.mName.empty())
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
if (mData.mRegion != "") if (!mData.mRegion.empty())
std::cout << " Region: " << mData.mRegion << std::endl; std::cout << " Region: " << mData.mRegion << std::endl;
std::cout << " Flags: " << cellFlags(mData.mData.mFlags) << std::endl; std::cout << " Flags: " << cellFlags(mData.mData.mFlags) << std::endl;
@ -580,23 +577,22 @@ void Record<ESM::Clothing>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
if (mData.mEnchant != "") if (!mData.mEnchant.empty())
std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Enchantment: " << mData.mEnchant << std::endl;
std::cout << " Type: " << clothingTypeLabel(mData.mData.mType) std::cout << " Type: " << clothingTypeLabel(mData.mData.mType)
<< " (" << mData.mData.mType << ")" << std::endl; << " (" << mData.mData.mType << ")" << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl;
std::vector<ESM::PartReference>::iterator pit; for (const ESM::PartReference &part : mData.mParts.mParts)
for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); ++pit)
{ {
std::cout << " Body Part: " << bodyPartLabel(pit->mPart) std::cout << " Body Part: " << bodyPartLabel(part.mPart)
<< " (" << (int)(pit->mPart) << ")" << std::endl; << " (" << (int)(part.mPart) << ")" << std::endl;
std::cout << " Male Name: " << pit->mMale << std::endl; std::cout << " Male Name: " << part.mMale << std::endl;
if (pit->mFemale != "") if (!part.mFemale.empty())
std::cout << " Female Name: " << pit->mFemale << std::endl; std::cout << " Female Name: " << part.mFemale << std::endl;
} }
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -606,14 +602,13 @@ void Record<ESM::Container>::print()
{ {
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl; std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl;
std::cout << " Weight: " << mData.mWeight << std::endl; std::cout << " Weight: " << mData.mWeight << std::endl;
std::vector<ESM::ContItem>::iterator cit; for (const ESM::ContItem &item : mData.mInventory.mList)
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit) std::cout << " Inventory: Count: " << boost::format("%4d") % item.mCount
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount << " Item: " << item.mItem.toString() << std::endl;
<< " Item: " << cit->mItem.toString() << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -656,14 +651,12 @@ void Record<ESM::Creature>::print()
<< "-" << mData.mData.mAttack[5] << std::endl; << "-" << mData.mData.mAttack[5] << std::endl;
std::cout << " Gold: " << mData.mData.mGold << std::endl; std::cout << " Gold: " << mData.mData.mGold << std::endl;
std::vector<ESM::ContItem>::iterator cit; for (const ESM::ContItem &item : mData.mInventory.mList)
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit) std::cout << " Inventory: Count: " << boost::format("%4d") % item.mCount
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount << " Item: " << item.mItem.toString() << std::endl;
<< " Item: " << cit->mItem.toString() << std::endl;
std::vector<std::string>::iterator sit; for (const std::string &spell : mData.mSpells.mList)
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) std::cout << " Spell: " << spell << std::endl;
std::cout << " Spell: " << *sit << std::endl;
printTransport(mData.getTransport()); printTransport(mData.getTransport());
@ -678,9 +671,8 @@ void Record<ESM::Creature>::print()
std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl; std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl;
std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl;
std::vector<ESM::AIPackage>::iterator pit; for (const ESM::AIPackage &package : mData.mAiPackage.mList)
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit) printAIPackage(package);
printAIPackage(*pit);
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -693,9 +685,8 @@ void Record<ESM::Dialogue>::print()
// Sadly, there are no DialInfos, because the loader dumps as it // Sadly, there are no DialInfos, because the loader dumps as it
// loads, rather than loading and then dumping. :-( Anyone mind if // loads, rather than loading and then dumping. :-( Anyone mind if
// I change this? // I change this?
ESM::Dialogue::InfoContainer::iterator iit; for (const ESM::DialInfo &info : mData.mInfo)
for (iit = mData.mInfo.begin(); iit != mData.mInfo.end(); ++iit) std::cout << "INFO!" << info.mId << std::endl;
std::cout << "INFO!" << iit->mId << std::endl;
} }
template<> template<>
@ -735,7 +726,7 @@ void Record<ESM::Faction>::print()
std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i]) std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i])
<< " (" << mData.mData.mSkills[i] << ")" << std::endl; << " (" << mData.mData.mSkills[i] << ")" << std::endl;
for (int i = 0; i != 10; i++) for (int i = 0; i != 10; i++)
if (mData.mRanks[i] != "") if (!mData.mRanks[i].empty())
{ {
std::cout << " Rank: " << mData.mRanks[i] << std::endl; std::cout << " Rank: " << mData.mRanks[i] << std::endl;
std::cout << " Attribute1 Requirement: " std::cout << " Attribute1 Requirement: "
@ -749,9 +740,8 @@ void Record<ESM::Faction>::print()
std::cout << " Faction Reaction: " std::cout << " Faction Reaction: "
<< mData.mData.mRankData[i].mFactReaction << std::endl; << mData.mData.mRankData[i].mFactReaction << std::endl;
} }
std::map<std::string, int>::iterator rit; for (const std::pair<std::string, int> &reaction : mData.mReactions)
for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); ++rit) std::cout << " Reaction: " << reaction.second << " = " << reaction.first << std::endl;
std::cout << " Reaction: " << rit->second << " = " << rit->first << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -772,34 +762,34 @@ template<>
void Record<ESM::DialInfo>::print() void Record<ESM::DialInfo>::print()
{ {
std::cout << " Id: " << mData.mId << std::endl; std::cout << " Id: " << mData.mId << std::endl;
if (mData.mPrev != "") if (!mData.mPrev.empty())
std::cout << " Previous ID: " << mData.mPrev << std::endl; std::cout << " Previous ID: " << mData.mPrev << std::endl;
if (mData.mNext != "") if (!mData.mNext.empty())
std::cout << " Next ID: " << mData.mNext << std::endl; std::cout << " Next ID: " << mData.mNext << std::endl;
std::cout << " Text: " << mData.mResponse << std::endl; std::cout << " Text: " << mData.mResponse << std::endl;
if (mData.mActor != "") if (!mData.mActor.empty())
std::cout << " Actor: " << mData.mActor << std::endl; std::cout << " Actor: " << mData.mActor << std::endl;
if (mData.mRace != "") if (!mData.mRace.empty())
std::cout << " Race: " << mData.mRace << std::endl; std::cout << " Race: " << mData.mRace << std::endl;
if (mData.mClass != "") if (!mData.mClass.empty())
std::cout << " Class: " << mData.mClass << std::endl; std::cout << " Class: " << mData.mClass << std::endl;
std::cout << " Factionless: " << mData.mFactionLess << std::endl; std::cout << " Factionless: " << mData.mFactionLess << std::endl;
if (mData.mFaction != "") if (!mData.mFaction.empty())
std::cout << " NPC Faction: " << mData.mFaction << std::endl; std::cout << " NPC Faction: " << mData.mFaction << std::endl;
if (mData.mData.mRank != -1) if (mData.mData.mRank != -1)
std::cout << " NPC Rank: " << (int)mData.mData.mRank << std::endl; std::cout << " NPC Rank: " << (int)mData.mData.mRank << std::endl;
if (mData.mPcFaction != "") if (!mData.mPcFaction.empty())
std::cout << " PC Faction: " << mData.mPcFaction << std::endl; std::cout << " PC Faction: " << mData.mPcFaction << std::endl;
// CHANGE? non-standard capitalization mPCrank -> mPCRank (mPcRank?) // CHANGE? non-standard capitalization mPCrank -> mPCRank (mPcRank?)
if (mData.mData.mPCrank != -1) if (mData.mData.mPCrank != -1)
std::cout << " PC Rank: " << (int)mData.mData.mPCrank << std::endl; std::cout << " PC Rank: " << (int)mData.mData.mPCrank << std::endl;
if (mData.mCell != "") if (!mData.mCell.empty())
std::cout << " Cell: " << mData.mCell << std::endl; std::cout << " Cell: " << mData.mCell << std::endl;
if (mData.mData.mDisposition > 0) if (mData.mData.mDisposition > 0)
std::cout << " Disposition/Journal index: " << mData.mData.mDisposition << std::endl; std::cout << " Disposition/Journal index: " << mData.mData.mDisposition << std::endl;
if (mData.mData.mGender != ESM::DialInfo::NA) if (mData.mData.mGender != ESM::DialInfo::NA)
std::cout << " Gender: " << mData.mData.mGender << std::endl; std::cout << " Gender: " << mData.mData.mGender << std::endl;
if (mData.mSound != "") if (!mData.mSound.empty())
std::cout << " Sound File: " << mData.mSound << std::endl; std::cout << " Sound File: " << mData.mSound << std::endl;
@ -808,11 +798,10 @@ void Record<ESM::DialInfo>::print()
std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl; std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl;
std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl; std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl;
std::vector<ESM::DialInfo::SelectStruct>::iterator sit; for (const ESM::DialInfo::SelectStruct &rule : mData.mSelects)
for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); ++sit) std::cout << " Select Rule: " << ruleString(rule) << std::endl;
std::cout << " Select Rule: " << ruleString(*sit) << std::endl;
if (mData.mResultScript != "") if (!mData.mResultScript.empty())
{ {
if (mPrintPlain) if (mPrintPlain)
{ {
@ -835,7 +824,7 @@ void Record<ESM::Ingredient>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
@ -877,10 +866,9 @@ void Record<ESM::CreatureLevList>::print()
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl; std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl;
std::cout << " Number of items: " << mData.mList.size() << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl;
std::vector<ESM::LevelledListBase::LevelItem>::iterator iit; for (const ESM::LevelledListBase::LevelItem &item : mData.mList)
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit) std::cout << " Creature: Level: " << item.mLevel
std::cout << " Creature: Level: " << iit->mLevel << " Creature: " << item.mId << std::endl;
<< " Creature: " << iit->mId << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -890,23 +878,22 @@ void Record<ESM::ItemLevList>::print()
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl; std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl;
std::cout << " Number of items: " << mData.mList.size() << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl;
std::vector<ESM::LevelledListBase::LevelItem>::iterator iit; for (const ESM::LevelledListBase::LevelItem &item : mData.mList)
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit) std::cout << " Inventory: Level: " << item.mLevel
std::cout << " Inventory: Level: " << iit->mLevel << " Item: " << item.mId << std::endl;
<< " Item: " << iit->mId << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
template<> template<>
void Record<ESM::Light>::print() void Record<ESM::Light>::print()
{ {
if (mData.mName != "") if (!mData.mName.empty())
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
if (mData.mModel != "") if (!mData.mModel.empty())
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
if (mData.mIcon != "") if (!mData.mIcon.empty())
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Flags: " << lightFlags(mData.mData.mFlags) << std::endl; std::cout << " Flags: " << lightFlags(mData.mData.mFlags) << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
@ -924,7 +911,7 @@ void Record<ESM::Lockpick>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
@ -939,7 +926,7 @@ void Record<ESM::Probe>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
@ -954,7 +941,7 @@ void Record<ESM::Repair>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
@ -981,21 +968,21 @@ void Record<ESM::MagicEffect>::print()
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
std::cout << " Flags: " << magicEffectFlags(mData.mData.mFlags) << std::endl; std::cout << " Flags: " << magicEffectFlags(mData.mData.mFlags) << std::endl;
std::cout << " Particle Texture: " << mData.mParticle << std::endl; std::cout << " Particle Texture: " << mData.mParticle << std::endl;
if (mData.mCasting != "") if (!mData.mCasting.empty())
std::cout << " Casting Static: " << mData.mCasting << std::endl; std::cout << " Casting Static: " << mData.mCasting << std::endl;
if (mData.mCastSound != "") if (!mData.mCastSound.empty())
std::cout << " Casting Sound: " << mData.mCastSound << std::endl; std::cout << " Casting Sound: " << mData.mCastSound << std::endl;
if (mData.mBolt != "") if (!mData.mBolt.empty())
std::cout << " Bolt Static: " << mData.mBolt << std::endl; std::cout << " Bolt Static: " << mData.mBolt << std::endl;
if (mData.mBoltSound != "") if (!mData.mBoltSound.empty())
std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl;
if (mData.mHit != "") if (!mData.mHit.empty())
std::cout << " Hit Static: " << mData.mHit << std::endl; std::cout << " Hit Static: " << mData.mHit << std::endl;
if (mData.mHitSound != "") if (!mData.mHitSound.empty())
std::cout << " Hit Sound: " << mData.mHitSound << std::endl; std::cout << " Hit Sound: " << mData.mHitSound << std::endl;
if (mData.mArea != "") if (!mData.mArea.empty())
std::cout << " Area Static: " << mData.mArea << std::endl; std::cout << " Area Static: " << mData.mArea << std::endl;
if (mData.mAreaSound != "") if (!mData.mAreaSound.empty())
std::cout << " Area Sound: " << mData.mAreaSound << std::endl; std::cout << " Area Sound: " << mData.mAreaSound << std::endl;
std::cout << " School: " << schoolLabel(mData.mData.mSchool) std::cout << " School: " << schoolLabel(mData.mData.mSchool)
<< " (" << mData.mData.mSchool << ")" << std::endl; << " (" << mData.mData.mSchool << ")" << std::endl;
@ -1015,7 +1002,7 @@ void Record<ESM::Miscellaneous>::print()
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
@ -1032,9 +1019,9 @@ void Record<ESM::NPC>::print()
std::cout << " Head Model: " << mData.mHead << std::endl; std::cout << " Head Model: " << mData.mHead << std::endl;
std::cout << " Race: " << mData.mRace << std::endl; std::cout << " Race: " << mData.mRace << std::endl;
std::cout << " Class: " << mData.mClass << std::endl; std::cout << " Class: " << mData.mClass << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
if (mData.mFaction != "") if (!mData.mFaction.empty())
std::cout << " Faction: " << mData.mFaction << std::endl; std::cout << " Faction: " << mData.mFaction << std::endl;
std::cout << " Flags: " << npcFlags(mData.mFlags) << std::endl; std::cout << " Flags: " << npcFlags(mData.mFlags) << std::endl;
@ -1083,14 +1070,12 @@ void Record<ESM::NPC>::print()
std::cout << " Gold: " << mData.mNpdt.mGold << std::endl; std::cout << " Gold: " << mData.mNpdt.mGold << std::endl;
} }
std::vector<ESM::ContItem>::iterator cit; for (const ESM::ContItem &item : mData.mInventory.mList)
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit) std::cout << " Inventory: Count: " << boost::format("%4d") % item.mCount
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount << " Item: " << item.mItem.toString() << std::endl;
<< " Item: " << cit->mItem.toString() << std::endl;
std::vector<std::string>::iterator sit; for (const std::string &spell : mData.mSpells.mList)
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) std::cout << " Spell: " << spell << std::endl;
std::cout << " Spell: " << *sit << std::endl;
printTransport(mData.getTransport()); printTransport(mData.getTransport());
@ -1105,9 +1090,8 @@ void Record<ESM::NPC>::print()
std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl; std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl;
std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl;
std::vector<ESM::AIPackage>::iterator pit; for (const ESM::AIPackage &package : mData.mAiPackage.mList)
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit) printAIPackage(package);
printAIPackage(*pit);
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -1124,23 +1108,22 @@ void Record<ESM::Pathgrid>::print()
std::cout << " Edge Count: " << mData.mEdges.size() << std::endl; std::cout << " Edge Count: " << mData.mEdges.size() << std::endl;
int i = 0; int i = 0;
ESM::Pathgrid::PointList::iterator pit; for (const ESM::Pathgrid::Point &point : mData.mPoints)
for (pit = mData.mPoints.begin(); pit != mData.mPoints.end(); ++pit)
{ {
std::cout << " Point[" << i << "]:" << std::endl; std::cout << " Point[" << i << "]:" << std::endl;
std::cout << " Coordinates: (" << pit->mX << "," std::cout << " Coordinates: (" << point.mX << ","
<< pit->mY << "," << pit->mZ << ")" << std::endl; << point.mY << "," << point.mZ << ")" << std::endl;
std::cout << " Auto-Generated: " << (int)pit->mAutogenerated << std::endl; std::cout << " Auto-Generated: " << (int)point.mAutogenerated << std::endl;
std::cout << " Connections: " << (int)pit->mConnectionNum << std::endl; std::cout << " Connections: " << (int)point.mConnectionNum << std::endl;
std::cout << " Unknown: " << pit->mUnknown << std::endl; std::cout << " Unknown: " << point.mUnknown << std::endl;
i++; i++;
} }
i = 0; i = 0;
ESM::Pathgrid::EdgeList::iterator eit; for (const ESM::Pathgrid::Edge &edge : mData.mEdges)
for (eit = mData.mEdges.begin(); eit != mData.mEdges.end(); ++eit)
{ {
std::cout << " Edge[" << i << "]: " << eit->mV0 << " -> " << eit->mV1 << std::endl; std::cout << " Edge[" << i << "]: " << edge.mV0 << " -> " << edge.mV1 << std::endl;
if (eit->mV0 >= mData.mData.mS2 || eit->mV1 >= mData.mData.mS2) if (edge.mV0 >= mData.mData.mS2 || edge.mV1 >= mData.mData.mS2)
std::cout << " BAD POINT IN EDGE!" << std::endl; std::cout << " BAD POINT IN EDGE!" << std::endl;
i++; i++;
} }
@ -1183,9 +1166,8 @@ void Record<ESM::Race>::print()
<< " (" << mData.mData.mBonus[i].mSkill << ") = " << " (" << mData.mData.mBonus[i].mSkill << ") = "
<< mData.mData.mBonus[i].mBonus << std::endl; << mData.mData.mBonus[i].mBonus << std::endl;
std::vector<std::string>::iterator sit; for (const std::string &power : mData.mPowers.mList)
for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); ++sit) std::cout << " Power: " << power << std::endl;
std::cout << " Power: " << *sit << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }
@ -1207,11 +1189,10 @@ void Record<ESM::Region>::print()
std::cout << " UnknownA: " << (int)mData.mData.mA << std::endl; std::cout << " UnknownA: " << (int)mData.mData.mA << std::endl;
std::cout << " UnknownB: " << (int)mData.mData.mB << std::endl; std::cout << " UnknownB: " << (int)mData.mData.mB << std::endl;
std::cout << " Map Color: " << mData.mMapColor << std::endl; std::cout << " Map Color: " << mData.mMapColor << std::endl;
if (mData.mSleepList != "") if (!mData.mSleepList.empty())
std::cout << " Sleep List: " << mData.mSleepList << std::endl; std::cout << " Sleep List: " << mData.mSleepList << std::endl;
std::vector<ESM::Region::SoundRef>::iterator sit; for (const ESM::Region::SoundRef &soundref : mData.mSoundList)
for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); ++sit) std::cout << " Sound: " << (int)soundref.mChance << " = " << soundref.mSound.toString() << std::endl;
std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl;
} }
template<> template<>
@ -1225,15 +1206,12 @@ void Record<ESM::Script>::print()
std::cout << " Script Data Size: " << mData.mData.mScriptDataSize << std::endl; std::cout << " Script Data Size: " << mData.mData.mScriptDataSize << std::endl;
std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl; std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl;
for (const std::string &variable : mData.mVarNames)
std::vector<std::string>::iterator vit; std::cout << " Variable: " << variable << std::endl;
for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); ++vit)
std::cout << " Variable: " << *vit << std::endl;
std::cout << " ByteCode: "; std::cout << " ByteCode: ";
std::vector<unsigned char>::iterator cit; for (const unsigned char &byte : mData.mScriptData)
for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); ++cit) std::cout << boost::format("%02X") % (int)(byte);
std::cout << boost::format("%02X") % (int)(*cit);
std::cout << std::endl; std::cout << std::endl;
if (mPrintPlain) if (mPrintPlain)
@ -1268,7 +1246,8 @@ void Record<ESM::Skill>::print()
template<> template<>
void Record<ESM::SoundGenerator>::print() void Record<ESM::SoundGenerator>::print()
{ {
std::cout << " Creature: " << mData.mCreature << std::endl; if (!mData.mCreature.empty())
std::cout << " Creature: " << mData.mCreature << std::endl;
std::cout << " Sound: " << mData.mSound << std::endl; std::cout << " Sound: " << mData.mSound << std::endl;
std::cout << " Type: " << soundTypeLabel(mData.mType) std::cout << " Type: " << soundTypeLabel(mData.mType)
<< " (" << mData.mType << ")" << std::endl; << " (" << mData.mType << ")" << std::endl;
@ -1316,15 +1295,15 @@ template<>
void Record<ESM::Weapon>::print() void Record<ESM::Weapon>::print()
{ {
// No names on VFX bolts // No names on VFX bolts
if (mData.mName != "") if (!mData.mName.empty())
std::cout << " Name: " << mData.mName << std::endl; std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Model: " << mData.mModel << std::endl;
// No icons on VFX bolts or magic bolts // No icons on VFX bolts or magic bolts
if (mData.mIcon != "") if (!mData.mIcon.empty())
std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl;
if (mData.mScript != "") if (!mData.mScript.empty())
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
if (mData.mEnchant != "") if (!mData.mEnchant.empty())
std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Enchantment: " << mData.mEnchant << std::endl;
std::cout << " Type: " << weaponTypeLabel(mData.mData.mType) std::cout << " Type: " << weaponTypeLabel(mData.mData.mType)
<< " (" << mData.mData.mType << ")" << std::endl; << " (" << mData.mData.mType << ")" << std::endl;
@ -1356,25 +1335,25 @@ std::string Record<ESM::Cell>::getId() const
template<> template<>
std::string Record<ESM::Land>::getId() const std::string Record<ESM::Land>::getId() const
{ {
return ""; // No ID for Land record return std::string(); // No ID for Land record
} }
template<> template<>
std::string Record<ESM::MagicEffect>::getId() const std::string Record<ESM::MagicEffect>::getId() const
{ {
return ""; // No ID for MagicEffect record return std::string(); // No ID for MagicEffect record
} }
template<> template<>
std::string Record<ESM::Pathgrid>::getId() const std::string Record<ESM::Pathgrid>::getId() const
{ {
return ""; // No ID for Pathgrid record return std::string(); // No ID for Pathgrid record
} }
template<> template<>
std::string Record<ESM::Skill>::getId() const std::string Record<ESM::Skill>::getId() const
{ {
return ""; // No ID for Skill record return std::string(); // No ID for Skill record
} }
} // end namespace } // end namespace

@ -6,7 +6,7 @@
#ifndef Q_MOC_RUN #ifndef Q_MOC_RUN
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#endif
#include <components/process/processinvoker.hpp> #include <components/process/processinvoker.hpp>
@ -14,7 +14,7 @@
#include <components/config/launchersettings.hpp> #include <components/config/launchersettings.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#endif
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
class QListWidgetItem; class QListWidgetItem;

@ -326,11 +326,11 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat
new NestedChildColumn (Columns::ColumnId_Interior, ColumnBase::Display_Boolean, new NestedChildColumn (Columns::ColumnId_Interior, ColumnBase::Display_Boolean,
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
mCells.getNestableColumn(index)->addColumn( mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_Ambient, ColumnBase::Display_Integer)); new NestedChildColumn (Columns::ColumnId_Ambient, ColumnBase::Display_Colour));
mCells.getNestableColumn(index)->addColumn( mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_Sunlight, ColumnBase::Display_Integer)); new NestedChildColumn (Columns::ColumnId_Sunlight, ColumnBase::Display_Colour));
mCells.getNestableColumn(index)->addColumn( mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_Fog, ColumnBase::Display_Integer)); new NestedChildColumn (Columns::ColumnId_Fog, ColumnBase::Display_Colour));
mCells.getNestableColumn(index)->addColumn( mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_FogDensity, ColumnBase::Display_Float)); new NestedChildColumn (Columns::ColumnId_FogDensity, ColumnBase::Display_Float));
mCells.getNestableColumn(index)->addColumn( mCells.getNestableColumn(index)->addColumn(

@ -4,6 +4,8 @@
#include <QDialog> #include <QDialog>
#include <QModelIndex> #include <QModelIndex>
#ifndef Q_MOC_RUN
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include "adjusterwidget.hpp" #include "adjusterwidget.hpp"
@ -12,6 +14,8 @@
Q_DECLARE_METATYPE (boost::filesystem::path) Q_DECLARE_METATYPE (boost::filesystem::path)
#endif #endif
#endif
#include "ui_filedialog.h" #include "ui_filedialog.h"
namespace ContentSelectorView namespace ContentSelectorView

@ -8,6 +8,7 @@
#include <QWidget> #include <QWidget>
#include <QEvent> #include <QEvent>
#ifndef Q_MOC_RUN
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/land.hpp" #include "../../model/world/land.hpp"
@ -15,6 +16,7 @@
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/landtexture.hpp" #include "../../model/world/landtexture.hpp"
#endif
namespace CSVWidget namespace CSVWidget
{ {

@ -3,7 +3,9 @@
#include <QWidget> #include <QWidget>
#ifndef Q_MOC_RUN
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#endif
class QPushButton; class QPushButton;
class QListWidget; class QListWidget;

@ -14,9 +14,11 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QPushButton> #include <QPushButton>
#ifndef Q_MOC_RUN
#include "scenetool.hpp" #include "scenetool.hpp"
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#endif
class QTableWidget; class QTableWidget;

@ -5,10 +5,12 @@
#include <QWidget> #include <QWidget>
#ifndef Q_MOC_RUN
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/scope.hpp" #include "../../model/world/scope.hpp"
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#endif
namespace CSMDoc namespace CSMDoc
{ {

@ -8,11 +8,13 @@
#include <QAbstractItemDelegate> #include <QAbstractItemDelegate>
#include <QScrollArea> #include <QScrollArea>
#ifndef Q_MOC_RUN
#include "../doc/subview.hpp" #include "../doc/subview.hpp"
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"
#include "../../model/world/commanddispatcher.hpp" #include "../../model/world/commanddispatcher.hpp"
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#endif
class QDataWidgetMapper; class QDataWidgetMapper;
class QSize; class QSize;

@ -6,8 +6,11 @@
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#ifndef Q_MOC_RUN
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#endif
class QUndoStack; class QUndoStack;

@ -237,6 +237,9 @@ namespace MWBase
virtual float getActorsProcessingRange() const = 0; virtual float getActorsProcessingRange() const = 0;
virtual bool onOpen(const MWWorld::Ptr& ptr) = 0;
virtual void onClose(const MWWorld::Ptr& ptr) = 0;
/// Check if the target actor was detected by an observer /// Check if the target actor was detected by an observer
/// If the observer is a non-NPC, check all actors in AI processing distance as observers /// If the observer is a non-NPC, check all actors in AI processing distance as observers
virtual bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) = 0; virtual bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) = 0;

@ -303,6 +303,8 @@ namespace MWBase
///< Queues movement for \a ptr (in local space), to be applied in the next call to ///< Queues movement for \a ptr (in local space), to be applied in the next call to
/// doPhysics. /// doPhysics.
virtual void updateAnimatedCollisionShape(const MWWorld::Ptr &ptr) = 0;
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) = 0; virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) = 0;
///< cast a Ray and return true if there is an object in the ray path. ///< cast a Ray and return true if there is an object in the ray path.

@ -162,6 +162,8 @@ namespace MWGui
if (mModel) if (mModel)
mModel->onClose(); mModel->onClose();
MWBase::Environment::get().getMechanicsManager()->onClose(mPtr);
} }
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)

@ -52,6 +52,7 @@ namespace MWInput
, mUserFile(userFile) , mUserFile(userFile)
, mDragDrop(false) , mDragDrop(false)
, mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input"))
, mInvertX (Settings::Manager::getBool("invert x axis", "Input"))
, mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mInvertY (Settings::Manager::getBool("invert y axis", "Input"))
, mControlsDisabled(false) , mControlsDisabled(false)
, mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input"))
@ -467,7 +468,7 @@ namespace MWInput
float rot[3]; float rot[3];
rot[0] = yAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; rot[0] = yAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier;
rot[1] = 0.0f; rot[1] = 0.0f;
rot[2] = xAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f); rot[2] = xAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1);
// Only actually turn player when we're not in vanity mode // Only actually turn player when we're not in vanity mode
if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot)) if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot))
@ -646,6 +647,9 @@ namespace MWInput
for (Settings::CategorySettingVector::const_iterator it = changed.begin(); for (Settings::CategorySettingVector::const_iterator it = changed.begin();
it != changed.end(); ++it) it != changed.end(); ++it)
{ {
if (it->first == "Input" && it->second == "invert x axis")
mInvertX = Settings::Manager::getBool("invert x axis", "Input");
if (it->first == "Input" && it->second == "invert y axis") if (it->first == "Input" && it->second == "invert y axis")
mInvertY = Settings::Manager::getBool("invert y axis", "Input"); mInvertY = Settings::Manager::getBool("invert y axis", "Input");
@ -827,7 +831,7 @@ namespace MWInput
{ {
resetIdleTime(); resetIdleTime();
float x = arg.xrel * mCameraSensitivity * (1.0f/256.f); float x = arg.xrel * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1);
float y = arg.yrel * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; float y = arg.yrel * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier;
float rot[3]; float rot[3];
@ -1169,7 +1173,7 @@ namespace MWInput
void InputManager::toggleWalking() void InputManager::toggleWalking()
{ {
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; if (MWBase::Environment::get().getWindowManager()->isGuiMode() || SDL_IsTextInputActive()) return;
mAlwaysRunActive = !mAlwaysRunActive; mAlwaysRunActive = !mAlwaysRunActive;
Settings::Manager::setBool("always run", "Input", mAlwaysRunActive); Settings::Manager::setBool("always run", "Input", mAlwaysRunActive);

@ -175,6 +175,7 @@ namespace MWInput
bool mGrabCursor; bool mGrabCursor;
bool mInvertX;
bool mInvertY; bool mInvertY;
bool mControlsDisabled; bool mControlsDisabled;

@ -413,5 +413,5 @@ DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld::
bool MWMechanics::AiPackage::canActorMoveByZAxis(const MWWorld::Ptr& actor) const bool MWMechanics::AiPackage::canActorMoveByZAxis(const MWWorld::Ptr& actor) const
{ {
MWBase::World* world = MWBase::Environment::get().getWorld(); MWBase::World* world = MWBase::Environment::get().getWorld();
return (actor.getClass().canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor); return (actor.getClass().canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor) || !world->isActorCollisionEnabled(actor);
} }

@ -209,7 +209,8 @@ namespace MWMechanics
} }
bool actorCanMoveByZ = (actor.getClass().canSwim(actor) && MWBase::Environment::get().getWorld()->isSwimming(actor)) bool actorCanMoveByZ = (actor.getClass().canSwim(actor) && MWBase::Environment::get().getWorld()->isSwimming(actor))
|| MWBase::Environment::get().getWorld()->isFlying(actor); || MWBase::Environment::get().getWorld()->isFlying(actor)
|| !MWBase::Environment::get().getWorld()->isActorCollisionEnabled(actor);
if(actorCanMoveByZ && mDistance > 0) { if(actorCanMoveByZ && mDistance > 0) {
// Typically want to idle for a short time before the next wander // Typically want to idle for a short time before the next wander

@ -419,6 +419,43 @@ void CharacterController::refreshJumpAnims(const WeaponInfo* weap, JumpingState
} }
} }
bool CharacterController::onOpen()
{
if (mPtr.getTypeName() == typeid(ESM::Container).name())
{
if (!mAnimation->hasAnimation("containeropen"))
return true;
if (mAnimation->isPlaying("containeropen"))
return false;
if (mAnimation->isPlaying("containerclose"))
return false;
mAnimation->play("containeropen", Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", 0.f, 0);
if (mAnimation->isPlaying("containeropen"))
return false;
}
return true;
}
void CharacterController::onClose()
{
if (mPtr.getTypeName() == typeid(ESM::Container).name())
{
if (!mAnimation->hasAnimation("containerclose"))
return;
float complete, startPoint = 0.f;
bool animPlaying = mAnimation->getInfo("containeropen", &complete);
if (animPlaying)
startPoint = 1.f - complete;
mAnimation->play("containerclose", Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", startPoint, 0);
}
}
void CharacterController::refreshMovementAnims(const WeaponInfo* weap, CharacterState movement, CharacterState& idle, bool force) void CharacterController::refreshMovementAnims(const WeaponInfo* weap, CharacterState movement, CharacterState& idle, bool force)
{ {
if (movement == mMovementState && idle == mIdleState && !force) if (movement == mMovementState && idle == mIdleState && !force)
@ -446,11 +483,10 @@ void CharacterController::refreshMovementAnims(const WeaponInfo* weap, Character
if(!mAnimation->hasAnimation(movementAnimName)) if(!mAnimation->hasAnimation(movementAnimName))
{ {
movemask = MWRender::Animation::BlendMask_LowerBody;
movementAnimName = movestate->groupname; movementAnimName = movestate->groupname;
if (swimpos == std::string::npos) if (swimpos == std::string::npos)
{ {
movemask = MWRender::Animation::BlendMask_LowerBody;
// Since we apply movement only for lower body, do not reset idle animations. // Since we apply movement only for lower body, do not reset idle animations.
// For upper body there will be idle animation. // For upper body there will be idle animation.
if (idle == CharState_None) if (idle == CharState_None)
@ -462,7 +498,11 @@ void CharacterController::refreshMovementAnims(const WeaponInfo* weap, Character
} }
else if (idle == CharState_None) else if (idle == CharState_None)
{ {
idle = CharState_IdleSwim; // In the 1st-person mode use ground idle animations as fallback
if (mPtr == getPlayer() && MWBase::Environment::get().getWorld()->isFirstPerson())
idle = CharState_Idle;
else
idle = CharState_IdleSwim;
} }
} }
} }
@ -1076,6 +1116,8 @@ void CharacterController::handleTextKey(const std::string &groupname, const std:
else if (groupname == "shield" && evt.compare(off, len, "block hit") == 0) else if (groupname == "shield" && evt.compare(off, len, "block hit") == 0)
mPtr.getClass().block(mPtr); mPtr.getClass().block(mPtr);
else if (groupname == "containeropen" && evt.compare(off, len, "loot") == 0)
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container, mPtr);
} }
void CharacterController::updatePtr(const MWWorld::Ptr &ptr) void CharacterController::updatePtr(const MWWorld::Ptr &ptr)
@ -1247,6 +1289,7 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
std::string upSoundId; std::string upSoundId;
std::string downSoundId; std::string downSoundId;
bool weaponChanged = false;
if (mPtr.getClass().hasInventoryStore(mPtr)) if (mPtr.getClass().hasInventoryStore(mPtr))
{ {
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
@ -1264,7 +1307,13 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
if(weapon == inv.end() && !mWeapon.isEmpty() && weaptype == WeapType_HandToHand && mWeaponType != WeapType_Spell) if(weapon == inv.end() && !mWeapon.isEmpty() && weaptype == WeapType_HandToHand && mWeaponType != WeapType_Spell)
downSoundId = mWeapon.getClass().getDownSoundId(mWeapon); downSoundId = mWeapon.getClass().getDownSoundId(mWeapon);
mWeapon = weapon != inv.end() ? *weapon : MWWorld::Ptr(); MWWorld::Ptr newWeapon = weapon != inv.end() ? *weapon : MWWorld::Ptr();
if (mWeapon != newWeapon)
{
mWeapon = newWeapon;
weaponChanged = true;
}
} }
// Use blending only with 3d-person movement animations for bipedal actors // Use blending only with 3d-person movement animations for bipedal actors
@ -1299,9 +1348,8 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
&& mUpperBodyState != UpperCharState_UnEquipingWeap && mUpperBodyState != UpperCharState_UnEquipingWeap
&& !isStillWeapon) && !isStillWeapon)
{ {
// We can not play un-equip animation when we switch to HtH // We can not play un-equip animation if weapon changed since last update
// because we already un-equipped weapon if (!weaponChanged)
if (weaptype != WeapType_HandToHand || mWeaponType == WeapType_Spell)
{ {
// Note: we do not disable unequipping animation automatically to avoid body desync // Note: we do not disable unequipping animation automatically to avoid body desync
getWeaponGroup(mWeaponType, weapgroup); getWeaponGroup(mWeaponType, weapgroup);
@ -1613,13 +1661,13 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
} }
} }
// We should reset player's idle animation in the first-person mode. // We should not break swim and sneak animations
if (resetIdle && mPtr == player && MWBase::Environment::get().getWorld()->isFirstPerson()) if (resetIdle &&
idle = CharState_None; idle != CharState_IdleSneak && idle != CharState_IdleSwim &&
mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim)
// In other cases we should not break swim and sneak animations {
if (resetIdle && mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim)
idle = CharState_None; idle = CharState_None;
}
animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete);
if(mUpperBodyState == UpperCharState_MinAttackToMaxAttack && !isKnockedDown()) if(mUpperBodyState == UpperCharState_MinAttackToMaxAttack && !isKnockedDown())
@ -1873,6 +1921,7 @@ void CharacterController::update(float duration, bool animationOnly)
bool incapacitated = (cls.getCreatureStats(mPtr).isParalyzed() || cls.getCreatureStats(mPtr).getKnockedDown()); bool incapacitated = (cls.getCreatureStats(mPtr).isParalyzed() || cls.getCreatureStats(mPtr).getKnockedDown());
bool inwater = world->isSwimming(mPtr); bool inwater = world->isSwimming(mPtr);
bool flying = world->isFlying(mPtr); bool flying = world->isFlying(mPtr);
bool solid = world->isActorCollisionEnabled(mPtr);
// Can't run and sneak while flying (see speed formula in Npc/Creature::getSpeed) // Can't run and sneak while flying (see speed formula in Npc/Creature::getSpeed)
bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !flying; bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !flying;
bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !flying; bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !flying;
@ -1881,7 +1930,7 @@ void CharacterController::update(float duration, bool animationOnly)
//Force Jump Logic //Force Jump Logic
bool isMoving = (std::abs(cls.getMovementSettings(mPtr).mPosition[0]) > .5 || std::abs(cls.getMovementSettings(mPtr).mPosition[1]) > .5); bool isMoving = (std::abs(cls.getMovementSettings(mPtr).mPosition[0]) > .5 || std::abs(cls.getMovementSettings(mPtr).mPosition[1]) > .5);
if(!inwater && !flying) if(!inwater && !flying && solid)
{ {
//Force Jump //Force Jump
if(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceJump)) if(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceJump))
@ -1989,11 +2038,12 @@ void CharacterController::update(float duration, bool animationOnly)
cls.getCreatureStats(mPtr).setFatigue(fatigue); cls.getCreatureStats(mPtr).setFatigue(fatigue);
} }
if(sneak || inwater || flying || incapacitated) if(sneak || inwater || flying || incapacitated || !solid)
vec.z() = 0.0f; vec.z() = 0.0f;
bool inJump = true; bool inJump = true;
if(!onground && !flying && !inwater) bool playLandingSound = false;
if(!onground && !flying && !inwater && solid)
{ {
// In the air (either getting up —ascending part of jump— or falling). // In the air (either getting up —ascending part of jump— or falling).
@ -2046,7 +2096,7 @@ void CharacterController::update(float duration, bool animationOnly)
} }
} }
} }
else if(mJumpState == JumpState_InAir && !inwater && !flying) else if(mJumpState == JumpState_InAir && !inwater && !flying && solid)
{ {
forcestateupdate = true; forcestateupdate = true;
jumpstate = JumpState_Landing; jumpstate = JumpState_Landing;
@ -2080,20 +2130,14 @@ void CharacterController::update(float duration, bool animationOnly)
} }
} }
// Play landing sound for NPCs
if (mPtr.getClass().isNpc()) if (mPtr.getClass().isNpc())
{ playLandingSound = true;
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
std::string sound = "DefaultLand";
osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3());
if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr))
sound = "DefaultLandWater";
sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal);
}
} }
else else
{ {
if(mPtr.getClass().isNpc() && mJumpState == JumpState_InAir && !flying && solid)
playLandingSound = true;
jumpstate = mAnimation->isPlaying(mCurrentJump) ? JumpState_Landing : JumpState_None; jumpstate = mAnimation->isPlaying(mCurrentJump) ? JumpState_Landing : JumpState_None;
vec.z() = 0.0f; vec.z() = 0.0f;
@ -2143,6 +2187,17 @@ void CharacterController::update(float duration, bool animationOnly)
} }
} }
if (playLandingSound)
{
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
std::string sound = "DefaultLand";
osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3());
if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr))
sound = "DefaultLandWater";
sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal);
}
// Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering // Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering
if (isPlayer) if (isPlayer)
{ {

@ -259,6 +259,9 @@ public:
void update(float duration, bool animationOnly=false); void update(float duration, bool animationOnly=false);
bool onOpen();
void onClose();
void persistAnimationState(); void persistAnimationState();
void unpersistAnimationState(); void unpersistAnimationState();

@ -845,6 +845,20 @@ namespace MWMechanics
return false; return false;
} }
bool MechanicsManager::onOpen(const MWWorld::Ptr& ptr)
{
if(ptr.getClass().isActor())
return true;
else
return mObjects.onOpen(ptr);
}
void MechanicsManager::onClose(const MWWorld::Ptr& ptr)
{
if(!ptr.getClass().isActor())
mObjects.onClose(ptr);
}
void MechanicsManager::persistAnimationStates() void MechanicsManager::persistAnimationStates()
{ {
mActors.persistAnimationStates(); mActors.persistAnimationStates();

@ -182,6 +182,9 @@ namespace MWMechanics
virtual void playerLoaded() override; virtual void playerLoaded() override;
virtual bool onOpen(const MWWorld::Ptr& ptr) override;
virtual void onClose(const MWWorld::Ptr& ptr) override;
virtual int countSavedGameRecords() const override; virtual int countSavedGameRecords() const override;
virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const override; virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const override;

@ -1,8 +1,10 @@
#include "objects.hpp" #include "objects.hpp"
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/esm/loadcont.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "movement.hpp" #include "movement.hpp"
@ -77,6 +79,40 @@ void Objects::update(float duration, bool paused)
for(PtrControllerMap::iterator iter(mObjects.begin());iter != mObjects.end();++iter) for(PtrControllerMap::iterator iter(mObjects.begin());iter != mObjects.end();++iter)
iter->second->update(duration); iter->second->update(duration);
} }
else
{
// We still should play container opening animation in the Container GUI mode.
MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode();
if(mode != MWGui::GM_Container)
return;
for(PtrControllerMap::iterator iter(mObjects.begin());iter != mObjects.end();++iter)
{
if (iter->first.getTypeName() != typeid(ESM::Container).name())
continue;
if (iter->second->isAnimPlaying("containeropen"))
{
iter->second->update(duration);
MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(iter->first);
}
}
}
}
bool Objects::onOpen(const MWWorld::Ptr& ptr)
{
PtrControllerMap::iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
return iter->second->onOpen();
return false;
}
void Objects::onClose(const MWWorld::Ptr& ptr)
{
PtrControllerMap::iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
iter->second->onClose();
} }
bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist) bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist)

@ -38,6 +38,9 @@ namespace MWMechanics
void update(float duration, bool paused); void update(float duration, bool paused);
///< Update object animations ///< Update object animations
bool onOpen(const MWWorld::Ptr& ptr);
void onClose(const MWWorld::Ptr& ptr);
bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist=false); bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist=false);
void skipAnimation(const MWWorld::Ptr& ptr); void skipAnimation(const MWWorld::Ptr& ptr);
void persistAnimationStates(); void persistAnimationStates();

@ -1363,6 +1363,13 @@ namespace MWPhysics
#endif #endif
} }
void PhysicsSystem::updateAnimatedCollisionShape(const MWWorld::Ptr& object)
{
ObjectMap::iterator found = mObjects.find(object);
if (found != mObjects.end())
found->second->animateCollisionShapes(mCollisionWorld);
}
void PhysicsSystem::debugDraw() void PhysicsSystem::debugDraw()
{ {
if (mDebugDrawer.get()) if (mDebugDrawer.get())

@ -178,6 +178,8 @@ namespace MWPhysics
bool isOnSolidGround (const MWWorld::Ptr& actor) const; bool isOnSolidGround (const MWWorld::Ptr& actor) const;
void updateAnimatedCollisionShape(const MWWorld::Ptr& object);
template <class Function> template <class Function>
void forEachAnimatedObject(Function&& function) const void forEachAnimatedObject(Function&& function) const
{ {

@ -1,6 +1,7 @@
#include "actionopen.hpp" #include "actionopen.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwmechanics/disease.hpp" #include "../mwmechanics/disease.hpp"
@ -20,6 +21,9 @@ namespace MWWorld
if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory))
return; return;
if (!MWBase::Environment::get().getMechanicsManager()->onOpen(getTarget()))
return;
MWMechanics::diseaseContact(actor, getTarget()); MWMechanics::diseaseContact(actor, getTarget());
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container, getTarget()); MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container, getTarget());

@ -150,7 +150,7 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr,
} }
if (mListener) if (mListener)
mListener->itemAdded(itemPtr, count); mListener->itemAdded(*retVal, count);
return retVal; return retVal;
} }

@ -1059,11 +1059,11 @@ namespace MWWorld
{ {
// Load default marker definitions, if game files do not have them for some reason // Load default marker definitions, if game files do not have them for some reason
std::pair<std::string, std::string> markers[] = { std::pair<std::string, std::string> markers[] = {
std::make_pair("DivineMarker", "marker_divine.nif"), std::make_pair("divinemarker", "marker_divine.nif"),
std::make_pair("DoorMarker", "marker_arrow.nif"), std::make_pair("doormarker", "marker_arrow.nif"),
std::make_pair("NorthMarker", "marker_north.nif"), std::make_pair("northmarker", "marker_north.nif"),
std::make_pair("TempleMarker", "marker_temple.nif"), std::make_pair("templemarker", "marker_temple.nif"),
std::make_pair("TravelMarker", "marker_travel.nif") std::make_pair("travelmarker", "marker_travel.nif")
}; };
for (const std::pair<std::string, std::string> marker : markers) for (const std::pair<std::string, std::string> marker : markers)
@ -1085,7 +1085,7 @@ namespace MWWorld
{ {
// Load default Door type marker definitions // Load default Door type marker definitions
std::pair<std::string, std::string> markers[] = { std::pair<std::string, std::string> markers[] = {
std::make_pair("PrisonMarker", "marker_prison.nif") std::make_pair("prisonmarker", "marker_prison.nif")
}; };
for (const std::pair<std::string, std::string> marker : markers) for (const std::pair<std::string, std::string> marker : markers)

@ -1385,7 +1385,7 @@ namespace MWWorld
pos.z() += 20; // place slightly above. will snap down to ground with code below pos.z() += 20; // place slightly above. will snap down to ground with code below
if (force || !isFlying(ptr)) if (force || !ptr.getClass().isActor() || (!isFlying(ptr) && isActorCollisionEnabled(ptr)))
{ {
osg::Vec3f traced = mPhysics->traceDown(ptr, pos, Constants::CellSizeInUnits); osg::Vec3f traced = mPhysics->traceDown(ptr, pos, Constants::CellSizeInUnits);
if (traced.z() < pos.z()) if (traced.z() < pos.z())
@ -1527,6 +1527,11 @@ namespace MWWorld
mPhysics->queueObjectMovement(ptr, velocity); mPhysics->queueObjectMovement(ptr, velocity);
} }
void World::updateAnimatedCollisionShape(const Ptr &ptr)
{
mPhysics->updateAnimatedCollisionShape(ptr);
}
void World::doPhysics(float duration) void World::doPhysics(float duration)
{ {
mPhysics->stepSimulation(duration); mPhysics->stepSimulation(duration);
@ -2229,11 +2234,11 @@ namespace MWWorld
bool World::isFlying(const MWWorld::Ptr &ptr) const bool World::isFlying(const MWWorld::Ptr &ptr) const
{ {
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if(!ptr.getClass().isActor()) if(!ptr.getClass().isActor())
return false; return false;
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if (stats.isDead()) if (stats.isDead())
return false; return false;
@ -2245,7 +2250,7 @@ namespace MWWorld
return true; return true;
const MWPhysics::Actor* actor = mPhysics->getActor(ptr); const MWPhysics::Actor* actor = mPhysics->getActor(ptr);
if(!actor || !actor->getCollisionMode()) if(!actor)
return true; return true;
return false; return false;

@ -412,6 +412,8 @@ namespace MWWorld
///< Queues movement for \a ptr (in local space), to be applied in the next call to ///< Queues movement for \a ptr (in local space), to be applied in the next call to
/// doPhysics. /// doPhysics.
void updateAnimatedCollisionShape(const Ptr &ptr) override;
bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) override; bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) override;
///< cast a Ray and return true if there is an object in the ray path. ///< cast a Ray and return true if there is an object in the ray path.

@ -9,9 +9,10 @@
#ifndef Q_MOC_RUN #ifndef Q_MOC_RUN
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#endif
#include <components/config/gamesettings.hpp> #include <components/config/gamesettings.hpp>
#include <components/config/launchersettings.hpp> #include <components/config/launchersettings.hpp>
#endif
namespace Wizard namespace Wizard
{ {

@ -1,5 +1,6 @@
# This module accepts the following env variable # This module accepts the following env variable
# OSGPlugins_LIB_DIR - <OpenSceneGraph>/lib/osgPlugins-<X.X.X> , path to search plugins # OSGPlugins_LIB_DIR - <OpenSceneGraph>/lib/osgPlugins-<X.X.X> , path to search plugins
# OSGPlugins_DONT_FIND_DEPENDENCIES - Set to skip also finding png, zlib and jpeg
# #
# Once done this will define # Once done this will define
# OSGPlugins_FOUND - System has the all required components. # OSGPlugins_FOUND - System has the all required components.
@ -41,10 +42,12 @@ foreach(_library ${OSGPlugins_FIND_COMPONENTS})
list(APPEND OSGPlugins_PROCESS_LIBS ${_component}_LIBRARY) list(APPEND OSGPlugins_PROCESS_LIBS ${_component}_LIBRARY)
endforeach() endforeach()
foreach(_dependency PNG ZLIB JPEG) # needed by osgdb_png or osgdb_jpeg if(NOT DEFINED OSGPlugins_DONT_FIND_DEPENDENCIES)
libfind_package(OSGPlugins ${_dependency}) foreach(_dependency PNG ZLIB JPEG) # needed by osgdb_png or osgdb_jpeg
set(${_dependency}_LIBRARY_OPTS ${_dependency}_LIBRARY) libfind_package(OSGPlugins ${_dependency})
#list(APPEND OSGPlugins_PROCESS_LIBS ${_dependency}_LIBRARY) set(${_dependency}_LIBRARY_OPTS ${_dependency}_LIBRARY)
endforeach() #list(APPEND OSGPlugins_PROCESS_LIBS ${_dependency}_LIBRARY)
endforeach()
endif()
libfind_process(OSGPlugins) libfind_process(OSGPlugins)

@ -2,8 +2,42 @@
#include <components/crashcatcher/crashcatcher.hpp> #include <components/crashcatcher/crashcatcher.hpp>
#ifdef _WIN32
# undef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
namespace Debug namespace Debug
{ {
#ifdef _WIN32
bool attachParentConsole()
{
if (GetConsoleWindow() != nullptr)
return true;
if (AttachConsole(ATTACH_PARENT_PROCESS))
{
fflush(stdout);
fflush(stderr);
std::cout.flush();
std::cerr.flush();
// this looks dubious but is really the right way
_wfreopen(L"CON", L"w", stdout);
_wfreopen(L"CON", L"w", stderr);
_wfreopen(L"CON", L"r", stdin);
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
freopen("CON", "r", stdin);
return true;
}
return false;
}
#endif
std::streamsize DebugOutputBase::write(const char *str, std::streamsize size) std::streamsize DebugOutputBase::write(const char *str, std::streamsize size)
{ {
// Skip debug level marker // Skip debug level marker
@ -52,6 +86,10 @@ namespace Debug
int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, char *argv[], const std::string& appName) int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, char *argv[], const std::string& appName)
{ {
#if defined _WIN32
(void)Debug::attachParentConsole();
#endif
// Some objects used to redirect cout and cerr // Some objects used to redirect cout and cerr
// Scope must be here, so this still works inside the catch block for logging exceptions // Scope must be here, so this still works inside the catch block for logging exceptions
std::streambuf* cout_rdbuf = std::cout.rdbuf (); std::streambuf* cout_rdbuf = std::cout.rdbuf ();

@ -10,6 +10,12 @@
#include "debuglog.hpp" #include "debuglog.hpp"
#if defined _WIN32 && defined _DEBUG
# undef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
namespace Debug namespace Debug
{ {
// ANSI colors for terminal // ANSI colors for terminal
@ -43,11 +49,11 @@ namespace Debug
} }
}; };
#if defined(_WIN32) && defined(_DEBUG) #ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN bool attachParentConsole();
#define WIN32_LEAN_AND_MEAN 1 #endif
#endif // !WIN32_LEAN_AND_MEAN
#include <Windows.h> #if defined _WIN32 && defined _DEBUG
class DebugOutput : public DebugOutputBase class DebugOutput : public DebugOutputBase
{ {
public: public:

@ -56,12 +56,12 @@ namespace DetourNavigator
Value(Value&& other) Value(Value&& other)
: mOwner(other.mOwner), mIterator(other.mIterator) : mOwner(other.mOwner), mIterator(other.mIterator)
{ {
other.mIterator = ItemIterator(); other.mOwner = nullptr;
} }
~Value() ~Value()
{ {
if (mIterator != ItemIterator()) if (mOwner)
mOwner->releaseItem(mIterator); mOwner->releaseItem(mIterator);
} }
@ -69,16 +69,13 @@ namespace DetourNavigator
Value& operator =(Value&& other) Value& operator =(Value&& other)
{ {
if (mIterator == other.mIterator) if (mOwner)
return *this;
if (mIterator != ItemIterator())
mOwner->releaseItem(mIterator); mOwner->releaseItem(mIterator);
mOwner = other.mOwner; mOwner = other.mOwner;
mIterator = other.mIterator; mIterator = other.mIterator;
other.mIterator = ItemIterator(); other.mOwner = nullptr;
return *this; return *this;
} }
@ -90,7 +87,7 @@ namespace DetourNavigator
operator bool() const operator bool() const
{ {
return mIterator != ItemIterator(); return mOwner;
} }
private: private:

@ -94,6 +94,20 @@ meaning that it should remain set at 1.0 unless the player desires to have diffe
This setting can only be configured by editing the settings configuration file. This setting can only be configured by editing the settings configuration file.
invert x axis
-------------
:Type: boolean
:Range: True/False
:Default: False
Invert the horizontal axis while not in GUI mode.
If this setting is true, moving the mouse to the left will cause the view to rotate counter-clockwise,
while moving it to the right will cause the view to rotate clockwise. This setting does not affect cursor movement in GUI mode.
This setting can be toggled in game with the Invert X Axis button in the Controls panel of the Options menu.
invert y axis invert y axis
------------- -------------

@ -4,6 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <string>
#include <OpenThreads/Thread> #include <OpenThreads/Thread>
#include <OpenThreads/Mutex> #include <OpenThreads/Mutex>

@ -214,6 +214,16 @@
<Property key="Caption" value="#{sControlsMenu1}"/> <Property key="Caption" value="#{sControlsMenu1}"/>
</Widget> </Widget>
<Widget type="HBox" skin="" position="4 224 300 24" align="Left Bottom"> <Widget type="HBox" skin="" position="4 224 300 24" align="Left Bottom">
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 24 24" align="Left Bottom">
<UserString key="SettingCategory" value="Input"/>
<UserString key="SettingName" value="invert x axis"/>
<UserString key="SettingType" value="CheckButton"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" position="28 4 78 16" align="Left Bottom">
<Property key="Caption" value="Invert X Axis"/>
</Widget>
</Widget>
<Widget type="HBox" skin="" position="4 254 300 24" align="Left Bottom">
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 24 24" align="Left Bottom"> <Widget type="AutoSizedButton" skin="MW_Button" position="0 0 24 24" align="Left Bottom">
<UserString key="SettingCategory" value="Input"/> <UserString key="SettingCategory" value="Input"/>
<UserString key="SettingName" value="invert y axis"/> <UserString key="SettingName" value="invert y axis"/>
@ -223,10 +233,10 @@
<Property key="Caption" value="#{sMouseFlip}"/> <Property key="Caption" value="#{sMouseFlip}"/>
</Widget> </Widget>
</Widget> </Widget>
<Widget type="TextBox" skin="NormalText" position="4 254 336 18" align="Left Bottom"> <Widget type="TextBox" skin="NormalText" position="4 284 336 18" align="Left Bottom">
<Property key="Caption" value="Camera Sensitivity"/> <Property key="Caption" value="Camera Sensitivity"/>
</Widget> </Widget>
<Widget type="MWScrollBar" skin="MW_HScroll" position="4 278 336 18" align="HStretch Bottom"> <Widget type="MWScrollBar" skin="MW_HScroll" position="4 308 336 18" align="HStretch Bottom">
<Property key="Range" value="10000"/> <Property key="Range" value="10000"/>
<Property key="Page" value="300"/> <Property key="Page" value="300"/>
<UserString key="SettingType" value="Slider"/> <UserString key="SettingType" value="Slider"/>
@ -236,11 +246,11 @@
<UserString key="SettingMin" value="0.2"/> <UserString key="SettingMin" value="0.2"/>
<UserString key="SettingMax" value="5.0"/> <UserString key="SettingMax" value="5.0"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="4 302 336 18" align="Left Bottom"> <Widget type="TextBox" skin="SandText" position="4 332 336 18" align="Left Bottom">
<Property key="Caption" value="#{sLow}"/> <Property key="Caption" value="#{sLow}"/>
<Property key="TextAlign" value="Left"/> <Property key="TextAlign" value="Left"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="4 302 336 18" align="Right Bottom"> <Widget type="TextBox" skin="SandText" position="4 332 336 18" align="Right Bottom">
<Property key="Caption" value="#{sHigh}"/> <Property key="Caption" value="#{sHigh}"/>
<Property key="TextAlign" value="Right"/> <Property key="TextAlign" value="Right"/>
</Widget> </Widget>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright 2015 Alexandre Moine <nobrakal@gmail.com> Copyright 2015 Alexandre Moine <nobrakal@gmail.com>
Copyright 2017 Bret Curtis <psi29a@gmail.com> Copyright 2018 Bret Curtis <psi29a@gmail.com>
--> -->
<component type="desktop"> <component type="desktop">
<id>org.openmw.desktop</id> <id>org.openmw.desktop</id>
@ -43,9 +43,9 @@ Copyright 2017 Bret Curtis <psi29a@gmail.com>
<category>RolePlaying</category> <category>RolePlaying</category>
</categories> </categories>
<releases> <releases>
<release version="0.46.0" date="2017-12-05"/> <release version="@OPENMW_VERSION@" date="@OPENMW_VERSION_COMMITDATE@"/>
</releases> </releases>
<url type="homepage">https://openmw.org</url> <url type="homepage">https://openmw.org</url>
<url type="bugtracker">https://bugs.openmw.org/</url> <url type="bugtracker">https://gitlab.com/OpenMW/openmw/issues</url>
<url type="faq">https://openmw.org/faq/</url> <url type="faq">https://openmw.org/faq/</url>
</component> </component>

@ -333,6 +333,9 @@ camera sensitivity = 1.0
# (>0.0, Because it's a multiplier values should be near 1.0) # (>0.0, Because it's a multiplier values should be near 1.0)
camera y multiplier = 1.0 camera y multiplier = 1.0
# Invert the horizontal axis while not in GUI mode.
invert x axis = false
# Invert the vertical axis while not in GUI mode. # Invert the vertical axis while not in GUI mode.
invert y axis = false invert y axis = false

Loading…
Cancel
Save