1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-30 06:36:44 +00:00

Merge branch 'master' into feature-color-picking

This commit is contained in:
Stanislav Bas 2015-06-16 22:39:12 +03:00
commit 850f612c8b
104 changed files with 867 additions and 399 deletions

View file

@ -38,7 +38,7 @@ before_script:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi
script: script:
- cd ./build - cd ./build
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j4; fi - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j2; fi
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi - if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
after_script: after_script:
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi

View file

@ -98,25 +98,29 @@ endif()
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
# Sound setup # Sound setup
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE)
unset(FFMPEG_LIBRARIES CACHE) unset(FFMPEG_LIBRARIES CACHE)
find_package(FFmpeg)
find_package(FFmpeg REQUIRED)
set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARY})
if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND ) if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND )
message(FATAL_ERROR "FFmpeg component required, but not found!") message(FATAL_ERROR "FFmpeg component required, but not found!")
endif() endif()
set(SOUND_INPUT_INCLUDES ${FFMPEG_INCLUDE_DIRS}) set(SOUND_INPUT_INCLUDES ${FFMPEG_INCLUDE_DIRS})
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARIES})
if( SWRESAMPLE_FOUND ) if( SWRESAMPLE_FOUND )
add_definitions(-DHAVE_LIBSWRESAMPLE) add_definitions(-DHAVE_LIBSWRESAMPLE)
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES}) set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES})
else() else()
if( AVRESAMPLE_FOUND ) if( AVRESAMPLE_FOUND )
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES}) set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES})
else() else()
message(FATAL_ERROR "Install either libswresample (FFmpeg) or libavresample (Libav).") message(FATAL_ERROR "Install either libswresample (FFmpeg) or libavresample (Libav).")
endif() endif()
endif() endif()
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES})
# TinyXML # TinyXML
option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF) option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF)
if(USE_SYSTEM_TINYXML) if(USE_SYSTEM_TINYXML)
@ -151,6 +155,19 @@ endif()
# Dependencies # Dependencies
set(DESIRED_QT_VERSION 4 CACHE STRING "The QT version OpenMW should use (4 or 5)")
message(STATUS "Using Qt${DESIRED_QT_VERSION}")
if (DESIRED_QT_VERSION MATCHES 4)
find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork)
else()
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5Network REQUIRED)
# Instruct CMake to run moc automatically when needed.
#set(CMAKE_AUTOMOC ON)
endif()
# Fix for not visible pthreads functions for linker with glibc 2.15 # Fix for not visible pthreads functions for linker with glibc 2.15
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
find_package (Threads) find_package (Threads)
@ -171,7 +188,7 @@ if (HAVE_UNORDERED_MAP)
endif () endif ()
set(BOOST_COMPONENTS system filesystem program_options) set(BOOST_COMPONENTS system filesystem program_options thread wave)
if(WIN32) if(WIN32)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale) set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale)
endif(WIN32) endif(WIN32)

View file

@ -9,7 +9,8 @@ add_executable(bsatool
) )
target_link_libraries(bsatool target_link_libraries(bsatool
${Boost_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
components components
) )

View file

@ -13,7 +13,7 @@ add_executable(esmtool
) )
target_link_libraries(esmtool target_link_libraries(esmtool
${Boost_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY}
components components
) )

View file

@ -119,7 +119,7 @@ std::string clothingTypeLabel(int idx)
} }
std::string armorTypeLabel(int idx) std::string armorTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 10) if (idx >= 0 && idx <= 10)
{ {
static const char *armorTypeLabels[] = { static const char *armorTypeLabels[] = {
@ -645,7 +645,7 @@ std::string ruleFunction(int idx)
else else
return "Invalid"; return "Invalid";
} }
// The "unused flag bits" should probably be defined alongside the // The "unused flag bits" should probably be defined alongside the
// defined bits in the ESM component. The names of the flag bits are // defined bits in the ESM component. The names of the flag bits are
// very inconsistent. // very inconsistent.
@ -653,7 +653,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 ";
int unused = (0xFFFFFFFF ^ int unused = (0xFFFFFFFF ^
@ -667,7 +667,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 ";
if (flags & ESM::Cell::NoSleep) properties += "NoSleep "; if (flags & ESM::Cell::NoSleep) properties += "NoSleep ";
@ -830,12 +830,12 @@ 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 defines 0x8 as // 0x8=None and 0x10=AutoCalc, while our code previously defined
// AutoCalc. The former seems to be correct. All Bethesda // 0x8 as AutoCalc. The former seems to be correct. All Bethesda
// records have bit 0x8 set. A suspiciously large portion of // records have bit 0x8 set. Previously, suspiciously large portion
// females have autocalc turned off. // of females had autocalc turned off.
if (flags & ESM::NPC::Autocalc) properties += "Unknown "; if (flags & 0x00000008) properties += "Unknown ";
if (flags & 0x00000010) properties += "Autocalc "; if (flags & ESM::NPC::Autocalc) properties += "Autocalc ";
if (flags & ESM::NPC::Female) properties += "Female "; if (flags & ESM::NPC::Female) properties += "Female ";
if (flags & ESM::NPC::Respawn) properties += "Respawn "; if (flags & ESM::NPC::Respawn) properties += "Respawn ";
if (flags & ESM::NPC::Essential) properties += "Essential "; if (flags & ESM::NPC::Essential) properties += "Essential ";
@ -847,8 +847,8 @@ std::string npcFlags(int flags)
// however the only unknown bit occurs on ALL records, and // however the only unknown bit occurs on ALL records, and
// relatively few NPCs have this bit set. // relatively few NPCs have this bit set.
int unused = (0xFFFFFFFF ^ int unused = (0xFFFFFFFF ^
(ESM::NPC::Autocalc| (0x00000008|
0x00000010| ESM::NPC::Autocalc|
ESM::NPC::Female| ESM::NPC::Female|
ESM::NPC::Respawn| ESM::NPC::Respawn|
ESM::NPC::Essential| ESM::NPC::Essential|

View file

@ -33,7 +33,8 @@ add_executable(openmw-essimporter
) )
target_link_libraries(openmw-essimporter target_link_libraries(openmw-essimporter
${Boost_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
components components
) )

View file

@ -57,7 +57,6 @@ set(LAUNCHER_UI
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER}) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER})
find_package(Qt4 REQUIRED)
set(QT_USE_QTGUI 1) set(QT_USE_QTGUI 1)
# Set some platform specific settings # Set some platform specific settings
@ -66,12 +65,17 @@ if(WIN32)
set(QT_USE_QTMAIN TRUE) set(QT_USE_QTMAIN TRUE)
endif(WIN32) endif(WIN32)
QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc) if (DESIRED_QT_VERSION MATCHES 4)
QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC}) include(${QT_USE_FILE})
QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI}) QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc)
QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI})
else()
QT5_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc)
QT5_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
QT5_WRAP_UI(UI_HDRS ${LAUNCHER_UI})
endif()
include(${QT_USE_FILE})
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(NOT WIN32) if(NOT WIN32)
include_directories(${LIBUNSHIELD_INCLUDE_DIR}) include_directories(${LIBUNSHIELD_INCLUDE_DIR})
@ -88,17 +92,27 @@ add_executable(openmw-launcher
) )
target_link_libraries(openmw-launcher target_link_libraries(openmw-launcher
${Boost_LIBRARIES}
${OGRE_LIBRARIES} ${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS} ${OGRE_STATIC_PLUGINS}
${SDL2_LIBRARY_ONLY} ${SDL2_LIBRARY_ONLY}
${QT_LIBRARIES}
components components
) )
if (DESIRED_QT_VERSION MATCHES 4)
target_link_libraries(openmw-launcher ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
if(WIN32)
target_link_libraries(openmw-launcher ${QT_QTMAIN_LIBRARY})
endif(WIN32)
else()
qt5_use_modules(openmw-launcher Widgets Core)
if (WIN32)
target_link_libraries(Qt5::WinMain)
endif()
endif()
if (BUILD_WITH_CODE_COVERAGE) if (BUILD_WITH_CODE_COVERAGE)
add_definitions (--coverage) add_definitions (--coverage)
target_link_libraries(openmw-launcher gcov) target_link_libraries(openmw-launcher gcov)
endif() endif()

View file

@ -54,9 +54,6 @@ int main(int argc, char *argv[])
QDir::setCurrent(dir.absolutePath()); QDir::setCurrent(dir.absolutePath());
// Support non-latin characters
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
Launcher::MainDialog mainWin; Launcher::MainDialog mainWin;
Launcher::FirstRunDialogResult result = mainWin.showFirstRunDialog(); Launcher::FirstRunDialogResult result = mainWin.showFirstRunDialog();

View file

@ -14,10 +14,16 @@ add_executable(openmw-iniimporter
) )
target_link_libraries(openmw-iniimporter target_link_libraries(openmw-iniimporter
${Boost_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
components components
) )
if (WIN32)
target_link_libraries(openmw-iniimporter
${Boost_LOCALE_LIBRARY})
endif()
if (MINGW) if (MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode")
endif() endif()

View file

@ -41,7 +41,7 @@ opencs_units (model/tools
opencs_units_noqt (model/tools opencs_units_noqt (model/tools
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck
startscriptcheck search searchoperation searchstage pathgridcheck startscriptcheck search searchoperation searchstage pathgridcheck soundgencheck
) )
@ -154,19 +154,16 @@ if(WIN32)
set(QT_USE_QTMAIN TRUE) set(QT_USE_QTMAIN TRUE)
endif(WIN32) endif(WIN32)
set(BOOST_COMPONENTS system filesystem program_options thread wave) if (DESIRED_QT_VERSION MATCHES 4)
if(WIN32) include(${QT_USE_FILE})
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale) qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
endif(WIN32) qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) else()
qt5_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED) qt5_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
include(${QT_USE_FILE}) qt5_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
endif()
qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
# for compiled .ui files # for compiled .ui files
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
@ -207,12 +204,36 @@ target_link_libraries(openmw-cs
${OGRE_Overlay_LIBRARIES} ${OGRE_Overlay_LIBRARIES}
${OGRE_STATIC_PLUGINS} ${OGRE_STATIC_PLUGINS}
${SHINY_LIBRARIES} ${SHINY_LIBRARIES}
${Boost_LIBRARIES} ${Boost_SYSTEM_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_WAVE_LIBRARY}
${BULLET_LIBRARIES} ${BULLET_LIBRARIES}
${QT_LIBRARIES}
components components
) )
if (DESIRED_QT_VERSION MATCHES 4)
target_link_libraries(openmw-cs
${QT_QTGUI_LIBRARY}
${QT_QTCORE_LIBRARY}
${QT_QTNETWORK_LIBRARY})
if (WIN32)
target_link_libraries(openmw-cs ${QT_QTMAIN_LIBRARY})
endif()
else()
qt5_use_modules(openmw-cs Widgets Core Network)
if (WIN32)
target_link_libraries(Qt5::WinMain)
endif()
endif()
if (WIN32)
target_link_libraries(openmw-cs ${Boost_LOCALE_LIBRARY})
endif()
if(APPLE) if(APPLE)
INSTALL(TARGETS openmw-cs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE) INSTALL(TARGETS openmw-cs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE)
endif() endif()

View file

@ -95,7 +95,7 @@ void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
} }
} }
std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfig() std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfig(bool quiet)
{ {
boost::program_options::variables_map variables; boost::program_options::variables_map variables;
boost::program_options::options_description desc("Syntax: openmw-cs <options>\nAllowed options"); boost::program_options::options_description desc("Syntax: openmw-cs <options>\nAllowed options");
@ -115,7 +115,7 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
boost::program_options::notify(variables); boost::program_options::notify(variables);
mCfgMgr.readConfiguration(variables, desc); mCfgMgr.readConfiguration(variables, desc, quiet);
mDocumentManager.setEncoding ( mDocumentManager.setEncoding (
ToUTF8::calculateEncoding (variables["encoding"].as<std::string>())); ToUTF8::calculateEncoding (variables["encoding"].as<std::string>()));
@ -195,6 +195,11 @@ void CS::Editor::cancelCreateGame()
void CS::Editor::createAddon() void CS::Editor::createAddon()
{ {
mStartup.hide(); mStartup.hide();
mFileDialog.clearFiles();
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig(/*quiet*/true);
setupDataFiles (config.first);
mFileDialog.showDialog (CSVDoc::ContentAction_New); mFileDialog.showDialog (CSVDoc::ContentAction_New);
} }
@ -215,6 +220,11 @@ void CS::Editor::cancelFileDialog()
void CS::Editor::loadDocument() void CS::Editor::loadDocument()
{ {
mStartup.hide(); mStartup.hide();
mFileDialog.clearFiles();
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig(/*quiet*/true);
setupDataFiles (config.first);
mFileDialog.showDialog (CSVDoc::ContentAction_Edit); mFileDialog.showDialog (CSVDoc::ContentAction_Edit);
} }
@ -307,12 +317,12 @@ bool CS::Editor::makeIPCServer()
mServer->close(); mServer->close();
fullPath.remove(QRegExp("dummy$")); fullPath.remove(QRegExp("dummy$"));
fullPath += mIpcServerName; fullPath += mIpcServerName;
if(boost::filesystem::exists(fullPath.toStdString().c_str())) if(boost::filesystem::exists(fullPath.toUtf8().constData()))
{ {
// TODO: compare pid of the current process with that in the file // TODO: compare pid of the current process with that in the file
std::cout << "Detected unclean shutdown." << std::endl; std::cout << "Detected unclean shutdown." << std::endl;
// delete the stale file // delete the stale file
if(remove(fullPath.toStdString().c_str())) if(remove(fullPath.toUtf8().constData()))
std::cerr << "ERROR removing stale connection file" << std::endl; std::cerr << "ERROR removing stale connection file" << std::endl;
} }
} }

View file

@ -62,7 +62,7 @@ namespace CS
void setupDataFiles (const Files::PathContainer& dataDirs); void setupDataFiles (const Files::PathContainer& dataDirs);
std::pair<Files::PathContainer, std::vector<std::string> > readConfig(); std::pair<Files::PathContainer, std::vector<std::string> > readConfig(bool quiet=false);
///< \return data paths ///< \return data paths
// not implemented // not implemented

View file

@ -2272,7 +2272,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
if (boost::filesystem::exists (customFiltersPath)) if (boost::filesystem::exists (customFiltersPath))
{ {
destination << std::ifstream(customFiltersPath.c_str(), std::ios::binary).rdbuf(); destination << std::ifstream(customFiltersPath.string().c_str(), std::ios::binary).rdbuf();
} }
else else
{ {

View file

@ -648,7 +648,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated
{ {
if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0008 = autocalculated flag if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0010 = autocalculated flag
{ {
messages.push_back (std::make_pair (id, npc.mId + " mNpdtType or flags mismatch!")); //should not happend? messages.push_back (std::make_pair (id, npc.mId + " mNpdtType or flags mismatch!")); //should not happend?
return; return;

View file

@ -0,0 +1,53 @@
#include "soundgencheck.hpp"
#include <sstream>
#include "../world/refiddata.hpp"
#include "../world/universalid.hpp"
CSMTools::SoundGenCheckStage::SoundGenCheckStage(const CSMWorld::IdCollection<ESM::SoundGenerator> &soundGens,
const CSMWorld::IdCollection<ESM::Sound> &sounds,
const CSMWorld::RefIdCollection &referenceables)
: mSoundGens(soundGens),
mSounds(sounds),
mReferenceables(referenceables)
{}
int CSMTools::SoundGenCheckStage::setup()
{
return mSoundGens.getSize();
}
void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages)
{
const CSMWorld::Record<ESM::SoundGenerator> &record = mSoundGens.getRecord(stage);
if (record.isDeleted())
{
return;
}
const ESM::SoundGenerator soundGen = record.get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_SoundGen, soundGen.mId);
if (!soundGen.mCreature.empty())
{
CSMWorld::RefIdData::LocalIndex creatureIndex = mReferenceables.getDataSet().searchId(soundGen.mCreature);
if (creatureIndex.first == -1)
{
messages.push_back(std::make_pair(id, "No such creature '" + soundGen.mCreature + "'"));
}
else if (creatureIndex.second != CSMWorld::UniversalId::Type_Creature)
{
messages.push_back(std::make_pair(id, "'" + soundGen.mCreature + "' is not a creature"));
}
}
if (soundGen.mSound.empty())
{
messages.push_back(std::make_pair(id, "Sound is not specified"));
}
else if (mSounds.searchId(soundGen.mSound) == -1)
{
messages.push_back(std::make_pair(id, "No such sound '" + soundGen.mSound + "'"));
}
}

View file

@ -0,0 +1,30 @@
#ifndef CSM_TOOLS_SOUNDGENCHECK_HPP
#define CSM_TOOLS_SOUNDGENCHECK_HPP
#include "../world/data.hpp"
#include "../doc/stage.hpp"
namespace CSMTools
{
/// \brief VerifyStage: make sure that sound gen records are internally consistent
class SoundGenCheckStage : public CSMDoc::Stage
{
const CSMWorld::IdCollection<ESM::SoundGenerator> &mSoundGens;
const CSMWorld::IdCollection<ESM::Sound> &mSounds;
const CSMWorld::RefIdCollection &mReferenceables;
public:
SoundGenCheckStage(const CSMWorld::IdCollection<ESM::SoundGenerator> &soundGens,
const CSMWorld::IdCollection<ESM::Sound> &sounds,
const CSMWorld::RefIdCollection &referenceables);
virtual int setup();
///< \return number of steps
virtual void perform(int stage, CSMDoc::Messages &messages);
///< Messages resulting from this stage will be appended to \a messages.
};
}
#endif

View file

@ -27,6 +27,7 @@
#include "startscriptcheck.hpp" #include "startscriptcheck.hpp"
#include "searchoperation.hpp" #include "searchoperation.hpp"
#include "pathgridcheck.hpp" #include "pathgridcheck.hpp"
#include "soundgencheck.hpp"
CSMDoc::OperationHolder *CSMTools::Tools::get (int type) CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
{ {
@ -99,6 +100,10 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
mVerifierOperation->appendStage (new PathgridCheckStage (mData.getPathgrids())); mVerifierOperation->appendStage (new PathgridCheckStage (mData.getPathgrids()));
mVerifierOperation->appendStage (new SoundGenCheckStage (mData.getSoundGens(),
mData.getSounds(),
mData.getReferenceables()));
mVerifier.setOperation (mVerifierOperation); mVerifier.setOperation (mVerifierOperation);
} }

View file

@ -52,9 +52,10 @@ QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, i
void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr<CSMFilter::Node>& filter) void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr<CSMFilter::Node>& filter)
{ {
beginResetModel();
mFilter = filter; mFilter = filter;
updateColumnMap(); updateColumnMap();
reset(); endResetModel();
} }
bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const

View file

@ -37,10 +37,18 @@ void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData
Record<ESM::Potion>& record = static_cast<Record<ESM::Potion>&> ( Record<ESM::Potion>& record = static_cast<Record<ESM::Potion>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion)));
ESM::Potion potion = record.get();
if (column==mAutoCalc) if (column==mAutoCalc)
record.get().mData.mAutoCalc = value.toInt(); potion.mData.mAutoCalc = value.toInt();
else else
{
InventoryRefIdAdapter<ESM::Potion>::setData (column, data, index, value); InventoryRefIdAdapter<ESM::Potion>::setData (column, data, index, value);
return;
}
record.setModified(potion);
} }
@ -71,12 +79,19 @@ void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdD
Record<ESM::Apparatus>& record = static_cast<Record<ESM::Apparatus>&> ( Record<ESM::Apparatus>& record = static_cast<Record<ESM::Apparatus>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus)));
ESM::Apparatus apparatus = record.get();
if (column==mType) if (column==mType)
record.get().mData.mType = value.toInt(); apparatus.mData.mType = value.toInt();
else if (column==mQuality) else if (column==mQuality)
record.get().mData.mQuality = value.toFloat(); apparatus.mData.mQuality = value.toFloat();
else else
{
InventoryRefIdAdapter<ESM::Apparatus>::setData (column, data, index, value); InventoryRefIdAdapter<ESM::Apparatus>::setData (column, data, index, value);
return;
}
record.setModified(apparatus);
} }
@ -114,14 +129,22 @@ void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
Record<ESM::Armor>& record = static_cast<Record<ESM::Armor>&> ( Record<ESM::Armor>& record = static_cast<Record<ESM::Armor>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor)));
ESM::Armor armor = record.get();
if (column==mType) if (column==mType)
record.get().mData.mType = value.toInt(); armor.mData.mType = value.toInt();
else if (column==mHealth) else if (column==mHealth)
record.get().mData.mHealth = value.toInt(); armor.mData.mHealth = value.toInt();
else if (column==mArmor) else if (column==mArmor)
record.get().mData.mArmor = value.toInt(); armor.mData.mArmor = value.toInt();
else else
{
EnchantableRefIdAdapter<ESM::Armor>::setData (column, data, index, value); EnchantableRefIdAdapter<ESM::Armor>::setData (column, data, index, value);
return;
}
record.setModified(armor);
} }
CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns, CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns,
@ -151,12 +174,20 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
Record<ESM::Book>& record = static_cast<Record<ESM::Book>&> ( Record<ESM::Book>& record = static_cast<Record<ESM::Book>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book)));
ESM::Book book = record.get();
if (column==mScroll) if (column==mScroll)
record.get().mData.mIsScroll = value.toInt(); book.mData.mIsScroll = value.toInt();
else if (column==mSkill) else if (column==mSkill)
record.get().mData.mSkillID = value.toInt(); book.mData.mSkillID = value.toInt();
else else
{
EnchantableRefIdAdapter<ESM::Book>::setData (column, data, index, value); EnchantableRefIdAdapter<ESM::Book>::setData (column, data, index, value);
return;
}
record.setModified(book);
} }
CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns, CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns,
@ -186,10 +217,18 @@ void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
Record<ESM::Clothing>& record = static_cast<Record<ESM::Clothing>&> ( Record<ESM::Clothing>& record = static_cast<Record<ESM::Clothing>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing)));
ESM::Clothing clothing = record.get();
if (column==mType) if (column==mType)
record.get().mData.mType = value.toInt(); clothing.mData.mType = value.toInt();
else else
{
EnchantableRefIdAdapter<ESM::Clothing>::setData (column, data, index, value); EnchantableRefIdAdapter<ESM::Clothing>::setData (column, data, index, value);
return;
}
record.setModified(clothing);
} }
CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns, CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns,
@ -226,24 +265,32 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD
Record<ESM::Container>& record = static_cast<Record<ESM::Container>&> ( Record<ESM::Container>& record = static_cast<Record<ESM::Container>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
ESM::Container container = record.get();
if (column==mWeight) if (column==mWeight)
record.get().mWeight = value.toFloat(); container.mWeight = value.toFloat();
else if (column==mOrganic) else if (column==mOrganic)
{ {
if (value.toInt()) if (value.toInt())
record.get().mFlags |= ESM::Container::Organic; container.mFlags |= ESM::Container::Organic;
else else
record.get().mFlags &= ~ESM::Container::Organic; container.mFlags &= ~ESM::Container::Organic;
} }
else if (column==mRespawn) else if (column==mRespawn)
{ {
if (value.toInt()) if (value.toInt())
record.get().mFlags |= ESM::Container::Respawn; container.mFlags |= ESM::Container::Respawn;
else else
record.get().mFlags &= ~ESM::Container::Respawn; container.mFlags &= ~ESM::Container::Respawn;
} }
else else
{
NameRefIdAdapter<ESM::Container>::setData (column, data, index, value); NameRefIdAdapter<ESM::Container>::setData (column, data, index, value);
return;
}
record.setModified(container);
} }
CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns) CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns)
@ -303,20 +350,22 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
Record<ESM::Creature>& record = static_cast<Record<ESM::Creature>&> ( Record<ESM::Creature>& record = static_cast<Record<ESM::Creature>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
ESM::Creature creature = record.get();
if (column==mColumns.mType) if (column==mColumns.mType)
record.get().mData.mType = value.toInt(); creature.mData.mType = value.toInt();
else if (column==mColumns.mSoul) else if (column==mColumns.mSoul)
record.get().mData.mSoul = value.toInt(); creature.mData.mSoul = value.toInt();
else if (column==mColumns.mScale) else if (column==mColumns.mScale)
record.get().mScale = value.toFloat(); creature.mScale = value.toFloat();
else if (column==mColumns.mOriginal) else if (column==mColumns.mOriginal)
record.get().mOriginal = value.toString().toUtf8().constData(); creature.mOriginal = value.toString().toUtf8().constData();
else if (column==mColumns.mCombat) else if (column==mColumns.mCombat)
record.get().mData.mCombat = value.toInt(); creature.mData.mCombat = value.toInt();
else if (column==mColumns.mMagic) else if (column==mColumns.mMagic)
record.get().mData.mMagic = value.toInt(); creature.mData.mMagic = value.toInt();
else if (column==mColumns.mStealth) else if (column==mColumns.mStealth)
record.get().mData.mStealth = value.toInt(); creature.mData.mStealth = value.toInt();
else else
{ {
std::map<const RefIdColumn *, unsigned int>::const_iterator iter = std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
@ -325,13 +374,19 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
if (iter!=mColumns.mFlags.end()) if (iter!=mColumns.mFlags.end())
{ {
if (value.toInt()!=0) if (value.toInt()!=0)
record.get().mFlags |= iter->second; creature.mFlags |= iter->second;
else else
record.get().mFlags &= ~iter->second; creature.mFlags &= ~iter->second;
} }
else else
{
ActorRefIdAdapter<ESM::Creature>::setData (column, data, index, value); ActorRefIdAdapter<ESM::Creature>::setData (column, data, index, value);
return;
}
} }
record.setModified(creature);
} }
CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns, CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns,
@ -361,12 +416,20 @@ void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
Record<ESM::Door>& record = static_cast<Record<ESM::Door>&> ( Record<ESM::Door>& record = static_cast<Record<ESM::Door>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door)));
ESM::Door door = record.get();
if (column==mOpenSound) if (column==mOpenSound)
record.get().mOpenSound = value.toString().toUtf8().constData(); door.mOpenSound = value.toString().toUtf8().constData();
else if (column==mCloseSound) else if (column==mCloseSound)
record.get().mCloseSound = value.toString().toUtf8().constData(); door.mCloseSound = value.toString().toUtf8().constData();
else else
{
NameRefIdAdapter<ESM::Door>::setData (column, data, index, value); NameRefIdAdapter<ESM::Door>::setData (column, data, index, value);
return;
}
record.setModified(door);
} }
CSMWorld::LightColumns::LightColumns (const InventoryColumns& columns) CSMWorld::LightColumns::LightColumns (const InventoryColumns& columns)
@ -409,14 +472,16 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
Record<ESM::Light>& record = static_cast<Record<ESM::Light>&> ( Record<ESM::Light>& record = static_cast<Record<ESM::Light>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light)));
ESM::Light light = record.get();
if (column==mColumns.mTime) if (column==mColumns.mTime)
record.get().mData.mTime = value.toInt(); light.mData.mTime = value.toInt();
else if (column==mColumns.mRadius) else if (column==mColumns.mRadius)
record.get().mData.mRadius = value.toInt(); light.mData.mRadius = value.toInt();
else if (column==mColumns.mColor) else if (column==mColumns.mColor)
record.get().mData.mColor = value.toInt(); light.mData.mColor = value.toInt();
else if (column==mColumns.mSound) else if (column==mColumns.mSound)
record.get().mSound = value.toString().toUtf8().constData(); light.mSound = value.toString().toUtf8().constData();
else else
{ {
std::map<const RefIdColumn *, unsigned int>::const_iterator iter = std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
@ -425,13 +490,19 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
if (iter!=mColumns.mFlags.end()) if (iter!=mColumns.mFlags.end())
{ {
if (value.toInt()!=0) if (value.toInt()!=0)
record.get().mData.mFlags |= iter->second; light.mData.mFlags |= iter->second;
else else
record.get().mData.mFlags &= ~iter->second; light.mData.mFlags &= ~iter->second;
} }
else else
{
InventoryRefIdAdapter<ESM::Light>::setData (column, data, index, value); InventoryRefIdAdapter<ESM::Light>::setData (column, data, index, value);
return;
}
} }
record.setModified (light);
} }
CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key) CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key)
@ -456,10 +527,18 @@ void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
Record<ESM::Miscellaneous>& record = static_cast<Record<ESM::Miscellaneous>&> ( Record<ESM::Miscellaneous>& record = static_cast<Record<ESM::Miscellaneous>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous)));
ESM::Miscellaneous misc = record.get();
if (column==mKey) if (column==mKey)
record.get().mData.mIsKey = value.toInt(); misc.mData.mIsKey = value.toInt();
else else
{
InventoryRefIdAdapter<ESM::Miscellaneous>::setData (column, data, index, value); InventoryRefIdAdapter<ESM::Miscellaneous>::setData (column, data, index, value);
return;
}
record.setModified(misc);
} }
CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns)
@ -525,16 +604,18 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d
Record<ESM::NPC>& record = static_cast<Record<ESM::NPC>&> ( Record<ESM::NPC>& record = static_cast<Record<ESM::NPC>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
ESM::NPC npc = record.get();
if (column==mColumns.mRace) if (column==mColumns.mRace)
record.get().mRace = value.toString().toUtf8().constData(); npc.mRace = value.toString().toUtf8().constData();
else if (column==mColumns.mClass) else if (column==mColumns.mClass)
record.get().mClass = value.toString().toUtf8().constData(); npc.mClass = value.toString().toUtf8().constData();
else if (column==mColumns.mFaction) else if (column==mColumns.mFaction)
record.get().mFaction = value.toString().toUtf8().constData(); npc.mFaction = value.toString().toUtf8().constData();
else if (column==mColumns.mHair) else if (column==mColumns.mHair)
record.get().mHair = value.toString().toUtf8().constData(); npc.mHair = value.toString().toUtf8().constData();
else if (column==mColumns.mHead) else if (column==mColumns.mHead)
record.get().mHead = value.toString().toUtf8().constData(); npc.mHead = value.toString().toUtf8().constData();
else else
{ {
std::map<const RefIdColumn *, unsigned int>::const_iterator iter = std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
@ -543,13 +624,23 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d
if (iter!=mColumns.mFlags.end()) if (iter!=mColumns.mFlags.end())
{ {
if (value.toInt()!=0) if (value.toInt()!=0)
record.get().mFlags |= iter->second; npc.mFlags |= iter->second;
else else
record.get().mFlags &= ~iter->second; npc.mFlags &= ~iter->second;
if (iter->second == ESM::NPC::Autocalc)
npc.mNpdtType = (value.toInt() != 0) ? ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS
: ESM::NPC::NPC_DEFAULT;
} }
else else
{
ActorRefIdAdapter<ESM::NPC>::setData (column, data, index, value); ActorRefIdAdapter<ESM::NPC>::setData (column, data, index, value);
return;
}
} }
record.setModified (npc);
} }
CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter () CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter ()

View file

@ -334,9 +334,9 @@ QVariant CSMWorld::RegionMap::data (const QModelIndex& index, int role) const
mColours.find (Misc::StringUtils::lowerCase (cell->second.mRegion)); mColours.find (Misc::StringUtils::lowerCase (cell->second.mRegion));
if (iter!=mColours.end()) if (iter!=mColours.end())
return QBrush ( return QBrush (QColor (iter->second & 0xff,
QColor (iter->second>>24, (iter->second>>16) & 255, (iter->second>>8) & 255, (iter->second >> 8) & 0xff,
iter->second & 255)); (iter->second >> 16) & 0xff));
if (cell->second.mRegion.empty()) if (cell->second.mRegion.empty())
return QBrush (Qt::Dense6Pattern); // no region return QBrush (Qt::Dense6Pattern); // no region

View file

@ -33,6 +33,11 @@ void CSVDoc::FileDialog::addFiles(const QString &path)
mSelector->addFiles(path); mSelector->addFiles(path);
} }
void CSVDoc::FileDialog::clearFiles()
{
mSelector->clearFiles();
}
QStringList CSVDoc::FileDialog::selectedFilePaths() QStringList CSVDoc::FileDialog::selectedFilePaths()
{ {
QStringList filePaths; QStringList filePaths;
@ -105,7 +110,6 @@ void CSVDoc::FileDialog::buildNewFileView()
connect (mFileWidget, SIGNAL (nameChanged(const QString &, bool)), connect (mFileWidget, SIGNAL (nameChanged(const QString &, bool)),
this, SLOT (slotUpdateAcceptButton(const QString &, bool))); this, SLOT (slotUpdateAcceptButton(const QString &, bool)));
} }
ui.projectGroupBoxLayout->insertWidget (0, mFileWidget); ui.projectGroupBoxLayout->insertWidget (0, mFileWidget);
@ -139,7 +143,7 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(int)
{ {
QString name = ""; QString name = "";
if (mAction == ContentAction_New) if (mFileWidget && mAction == ContentAction_New)
name = mFileWidget->getName(); name = mFileWidget->getName();
slotUpdateAcceptButton (name, true); slotUpdateAcceptButton (name, true);

View file

@ -45,6 +45,7 @@ namespace CSVDoc
void showDialog (ContentAction action); void showDialog (ContentAction action);
void addFiles (const QString &path); void addFiles (const QString &path);
void clearFiles ();
QString filename() const; QString filename() const;
QStringList selectedFilePaths(); QStringList selectedFilePaths();

View file

@ -7,7 +7,7 @@
#include <QMenuBar> #include <QMenuBar>
#include <QMdiArea> #include <QMdiArea>
#include <QDockWidget> #include <QDockWidget>
#include <QtGui/QApplication> #include <QApplication>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QScrollArea> #include <QScrollArea>
#include <QHBoxLayout> #include <QHBoxLayout>
@ -515,6 +515,10 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
} }
} }
if (mScroll)
QObject::connect(mScroll->horizontalScrollBar(),
SIGNAL(rangeChanged(int,int)), this, SLOT(moveScrollBarToEnd(int,int)));
// User setting for limiting the number of sub views per top level view. // User setting for limiting the number of sub views per top level view.
// Automatically open a new top level view if this number is exceeded // Automatically open a new top level view if this number is exceeded
// //
@ -586,12 +590,6 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
mSubViewWindow.setMinimumWidth(mSubViewWindow.width()+minWidth); mSubViewWindow.setMinimumWidth(mSubViewWindow.width()+minWidth);
move(0, y()); move(0, y());
} }
// Make the new subview visible, setFocus() or raise() don't seem to work
// On Ubuntu the scrollbar does not go right to the end, even if using
// mScroll->horizontalScrollBar()->setValue(mScroll->horizontalScrollBar()->maximum());
if (mSubViewWindow.width() > rect.width())
mScroll->horizontalScrollBar()->setValue(mSubViewWindow.width());
} }
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view); mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
@ -614,6 +612,17 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
view->useHint (hint); view->useHint (hint);
} }
void CSVDoc::View::moveScrollBarToEnd(int min, int max)
{
if (mScroll)
{
mScroll->horizontalScrollBar()->setValue(max);
QObject::disconnect(mScroll->horizontalScrollBar(),
SIGNAL(rangeChanged(int,int)), this, SLOT(moveScrollBarToEnd(int,int)));
}
}
void CSVDoc::View::newView() void CSVDoc::View::newView()
{ {
mViewManager.addView (mDocument); mViewManager.addView (mDocument);

View file

@ -233,6 +233,8 @@ namespace CSVDoc
void stop(); void stop();
void closeRequest (SubView *subView); void closeRequest (SubView *subView);
void moveScrollBarToEnd(int min, int max);
}; };
} }

View file

@ -6,6 +6,8 @@
#include <QApplication> #include <QApplication>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QMessageBox>
#include <QPushButton>
#include "../../model/doc/documentmanager.hpp" #include "../../model/doc/documentmanager.hpp"
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
@ -25,10 +27,6 @@
#include "view.hpp" #include "view.hpp"
#include <QMessageBox>
#include <QPushButton>
#include <QtGui/QApplication>
void CSVDoc::ViewManager::updateIndices() void CSVDoc::ViewManager::updateIndices()
{ {
std::map<CSMDoc::Document *, std::pair<int, int> > documents; std::map<CSMDoc::Document *, std::pair<int, int> > documents;

View file

@ -6,7 +6,7 @@
#include <OgreColourValue.h> #include <OgreColourValue.h>
#include <OgreCamera.h> #include <OgreCamera.h>
#include <QtGui/qevent.h> #include <QEvent>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"

View file

@ -7,7 +7,12 @@
#include <OgreSceneManager.h> #include <OgreSceneManager.h>
#include <OgreEntity.h> #include <OgreEntity.h>
#include <QtGui/qevent.h> #include <QEvent>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMouseEvent>
#include <QKeyEvent>
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"

View file

@ -8,19 +8,12 @@
#include <QStackedWidget> #include <QStackedWidget>
#include <QtGui> #include <QtGui>
#include <QSplitter> #include <QSplitter>
#include <QDesktopWidget>
#include "../../model/settings/usersettings.hpp" #include "../../model/settings/usersettings.hpp"
#include "page.hpp" #include "page.hpp"
#include <QApplication>
#include <QTreeView>
#include <QListView>
#include <QTableView>
#include <QStandardItemModel>
#include <QStandardItem>
CSVSettings::Dialog::Dialog(QMainWindow *parent) CSVSettings::Dialog::Dialog(QMainWindow *parent)
: SettingWindow (parent), mStackedWidget (0), mDebugMode (false) : SettingWindow (parent), mStackedWidget (0), mDebugMode (false)

View file

@ -3,7 +3,6 @@
#include "settingwindow.hpp" #include "settingwindow.hpp"
#include "resizeablestackedwidget.hpp" #include "resizeablestackedwidget.hpp"
#include <QStandardItem>
class QStackedWidget; class QStackedWidget;
class QListWidget; class QListWidget;
@ -26,10 +25,6 @@ namespace CSVSettings {
explicit Dialog (QMainWindow *parent = 0); explicit Dialog (QMainWindow *parent = 0);
///Enables setting debug mode. When the dialog opens, a page is created
///which displays the SettingModel's contents in a Tree view.
void enableDebugMode (bool state, QStandardItemModel *model = 0);
protected: protected:
/// Settings are written on close /// Settings are written on close

View file

@ -9,6 +9,8 @@
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QTextDocument> #include <QTextDocument>
#include <QPainter> #include <QPainter>
#include <QContextMenuEvent>
#include <QMouseEvent>
#include "../../model/tools/reportmodel.hpp" #include "../../model/tools/reportmodel.hpp"
@ -121,7 +123,11 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
const CSMWorld::UniversalId& id, bool richTextDescription, QWidget *parent) const CSMWorld::UniversalId& id, bool richTextDescription, QWidget *parent)
: CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id)) : CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id))
{ {
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive);
#else
horizontalHeader()->setResizeMode (QHeaderView::Interactive); horizontalHeader()->setResizeMode (QHeaderView::Interactive);
#endif
horizontalHeader()->setStretchLastSection (true); horizontalHeader()->setStretchLastSection (true);
verticalHeader()->hide(); verticalHeader()->hide();
setSortingEnabled (true); setSortingEnabled (true);

View file

@ -65,8 +65,13 @@ CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& tool
mTable->setShowGrid (false); mTable->setShowGrid (false);
mTable->verticalHeader()->hide(); mTable->verticalHeader()->hide();
mTable->horizontalHeader()->hide(); mTable->horizontalHeader()->hide();
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
mTable->horizontalHeader()->setSectionResizeMode (0, QHeaderView::Stretch);
mTable->horizontalHeader()->setSectionResizeMode (1, QHeaderView::ResizeToContents);
#else
mTable->horizontalHeader()->setResizeMode (0, QHeaderView::Stretch); mTable->horizontalHeader()->setResizeMode (0, QHeaderView::Stretch);
mTable->horizontalHeader()->setResizeMode (1, QHeaderView::ResizeToContents); mTable->horizontalHeader()->setResizeMode (1, QHeaderView::ResizeToContents);
#endif
mTable->setSelectionMode (QAbstractItemView::NoSelection); mTable->setSelectionMode (QAbstractItemView::NoSelection);
layout->addWidget (mTable); layout->addWidget (mTable);

View file

@ -1,4 +1,5 @@
#include <QDrag> #include <QDrag>
#include <QDragEnterEvent>
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "dragrecordtable.hpp" #include "dragrecordtable.hpp"

View file

@ -2,7 +2,7 @@
#define CSV_WORLD_DRAGRECORDTABLE_H #define CSV_WORLD_DRAGRECORDTABLE_H
#include <QTableView> #include <QTableView>
#include <QtGui/qevent.h> #include <QEvent>
class QWidget; class QWidget;
class QAction; class QAction;

View file

@ -23,7 +23,11 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
setSelectionBehavior (QAbstractItemView::SelectRows); setSelectionBehavior (QAbstractItemView::SelectRows);
setSelectionMode (QAbstractItemView::ExtendedSelection); setSelectionMode (QAbstractItemView::ExtendedSelection);
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive);
#else
horizontalHeader()->setResizeMode (QHeaderView::Interactive); horizontalHeader()->setResizeMode (QHeaderView::Interactive);
#endif
verticalHeader()->hide(); verticalHeader()->hide();
int columns = model->columnCount(QModelIndex()); int columns = model->columnCount(QModelIndex());

View file

@ -2,7 +2,7 @@
#define CSV_WORLD_NESTEDTABLE_H #define CSV_WORLD_NESTEDTABLE_H
#include <QTableView> #include <QTableView>
#include <QtGui/qevent.h> #include <QEvent>
class QUndoStack; class QUndoStack;
class QAction; class QAction;

View file

@ -282,7 +282,11 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
mDispatcher = new CSMWorld::CommandDispatcher (document, id, this); mDispatcher = new CSMWorld::CommandDispatcher (document, id, this);
setModel (mProxyModel); setModel (mProxyModel);
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive);
#else
horizontalHeader()->setResizeMode (QHeaderView::Interactive); horizontalHeader()->setResizeMode (QHeaderView::Interactive);
#endif
verticalHeader()->hide(); verticalHeader()->hide();
setSortingEnabled (sorting); setSortingEnabled (sorting);
setSelectionBehavior (QAbstractItemView::SelectRows); setSelectionBehavior (QAbstractItemView::SelectRows);

View file

@ -4,7 +4,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <QtGui/qevent.h> #include <QEvent>
#include "../../model/filter/node.hpp" #include "../../model/filter/node.hpp"
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"

View file

@ -6,6 +6,7 @@
#include <QHeaderView> #include <QHeaderView>
#include <QApplication> #include <QApplication>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QDropEvent>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"

View file

@ -91,17 +91,6 @@ add_openmw_dir (mwbase
) )
# Main executable # Main executable
if (ANDROID)
set(BOOST_COMPONENTS system filesystem program_options thread wave atomic)
else ()
set(BOOST_COMPONENTS system filesystem program_options thread wave)
endif ()
if(WIN32)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale)
endif(WIN32)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
if (NOT ANDROID) if (NOT ANDROID)
add_executable(openmw add_executable(openmw
@ -126,10 +115,14 @@ target_link_libraries(openmw
${OGRE_LIBRARIES} ${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS} ${OGRE_STATIC_PLUGINS}
${SHINY_LIBRARIES} ${SHINY_LIBRARIES}
${Boost_LIBRARIES}
${OPENAL_LIBRARY} ${OPENAL_LIBRARY}
${SOUND_INPUT_LIBRARY} ${SOUND_INPUT_LIBRARY}
${BULLET_LIBRARIES} ${BULLET_LIBRARIES}
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_WAVE_LIBRARY}
${MYGUI_LIBRARIES} ${MYGUI_LIBRARIES}
${SDL2_LIBRARY} ${SDL2_LIBRARY}
${MYGUI_PLATFORM_LIBRARIES} ${MYGUI_PLATFORM_LIBRARIES}

View file

@ -677,44 +677,32 @@ namespace MWMechanics
return false; return false;
} }
bool AiCombat::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
{
if (!mPathFinder.getPath().empty())
{
Ogre::Vector3 currPathTarget(PathFinder::MakeOgreVector3(mPathFinder.getPath().back()));
Ogre::Vector3 newPathTarget = PathFinder::MakeOgreVector3(dest);
float dist = (newPathTarget - currPathTarget).length();
float targetPosThreshold = (cell->isExterior()) ? 300.0f : 100.0f;
return dist > targetPosThreshold;
}
else
{
// necessarily construct a new path
return true;
}
}
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target) void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
{ {
Ogre::Vector3 newPathTarget = Ogre::Vector3(target.getRefData().getPosition().pos); ESM::Pathgrid::Point newPathTarget = PathFinder::MakePathgridPoint(target.getRefData().getPosition());
float dist;
if(!mPathFinder.getPath().empty())
{
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
Ogre::Vector3 currPathTarget(PathFinder::MakeOgreVector3(lastPt));
dist = (newPathTarget - currPathTarget).length();
}
else dist = 1e+38F; // necessarily construct a new path
float targetPosThreshold = (actor.getCell()->getCell()->isExterior())? 300.0f : 100.0f;
//construct new path only if target has moved away more than on [targetPosThreshold] //construct new path only if target has moved away more than on [targetPosThreshold]
if(dist > targetPosThreshold) if (doesPathNeedRecalc(newPathTarget, actor.getCell()->getCell()))
{ {
ESM::Position pos = actor.getRefData().getPosition(); ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(actor.getRefData().getPosition()));
mPathFinder.buildSyncedPath(start, newPathTarget, actor.getCell(), false);
ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(pos));
ESM::Pathgrid::Point dest(PathFinder::MakePathgridPoint(newPathTarget));
if(!mPathFinder.isPathConstructed())
mPathFinder.buildPath(start, dest, actor.getCell(), false);
else
{
PathFinder newPathFinder;
newPathFinder.buildPath(start, dest, actor.getCell(), false);
if(!mPathFinder.getPath().empty())
{
newPathFinder.syncStart(mPathFinder.getPath());
mPathFinder = newPathFinder;
}
}
} }
} }

View file

@ -53,6 +53,9 @@ namespace MWMechanics
virtual void writeState(ESM::AiSequence::AiSequence &sequence) const; virtual void writeState(ESM::AiSequence::AiSequence &sequence) const;
protected:
virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell);
private: private:
int mTargetActorId; int mTargetActorId;

View file

@ -30,9 +30,9 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor ESM::Position pos = actor.getRefData().getPosition(); //position of the actor
/// Stops the actor when it gets too close to a unloaded cell /// Stops the actor when it gets too close to a unloaded cell
const ESM::Cell *cell = actor.getCell()->getCell();
{ {
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
const ESM::Cell *cell = actor.getCell()->getCell();
Movement &movement = actor.getClass().getMovementSettings(actor); Movement &movement = actor.getClass().getMovementSettings(actor);
//Ensure pursuer doesn't leave loaded cells //Ensure pursuer doesn't leave loaded cells
@ -67,8 +67,8 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
//*********************** //***********************
if(mTimer > 0.25) if(mTimer > 0.25)
{ {
if(distance(mPrevDest, dest) > 10) { //Only rebuild path if it's moved if (doesPathNeedRecalc(dest, cell)) { //Only rebuild path if it's moved
mPathFinder.buildPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved mPathFinder.buildSyncedPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved
mPrevDest = dest; mPrevDest = dest;
} }
@ -123,3 +123,8 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
return false; return false;
} }
bool MWMechanics::AiPackage::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
{
return distance(mPrevDest, dest) > 10;
}

View file

@ -4,6 +4,8 @@
#include "pathfinding.hpp" #include "pathfinding.hpp"
#include <components/esm/defs.hpp> #include <components/esm/defs.hpp>
#include "../mwworld/cellstore.hpp"
#include "obstacle.hpp" #include "obstacle.hpp"
#include "aistate.hpp" #include "aistate.hpp"
@ -71,6 +73,8 @@ namespace MWMechanics
/** \return If the actor has arrived at his destination **/ /** \return If the actor has arrived at his destination **/
bool pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Point dest, float duration); bool pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Point dest, float duration);
virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell);
// TODO: all this does not belong here, move into temporary storage // TODO: all this does not belong here, move into temporary storage
PathFinder mPathFinder; PathFinder mPathFinder;
ObstacleCheck mObstacleCheck; ObstacleCheck mObstacleCheck;

View file

@ -51,64 +51,31 @@ namespace MWMechanics
bool AiTravel::execute (const MWWorld::Ptr& actor, AiState& state, float duration) bool AiTravel::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld();
ESM::Position pos = actor.getRefData().getPosition(); ESM::Position pos = actor.getRefData().getPosition();
Movement &movement = actor.getClass().getMovementSettings(actor);
const ESM::Cell *cell = actor.getCell()->getCell();
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false); actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false);
actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
MWWorld::Ptr player = world->getPlayerPtr();
if(cell->mData.mX != player.getCell()->getCell()->mData.mX)
{
int sideX = PathFinder::sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX);
//check if actor is near the border of an inactive cell. If so, stop walking.
if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) >
sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
{
movement.mPosition[1] = 0;
return false;
}
}
if(cell->mData.mY != player.getCell()->getCell()->mData.mY)
{
int sideY = PathFinder::sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY);
//check if actor is near the border of an inactive cell. If so, stop walking.
if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) >
sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
{
movement.mPosition[1] = 0;
return false;
}
}
if (!isWithinMaxRange(Ogre::Vector3(mX, mY, mZ), Ogre::Vector3(pos.pos))) if (!isWithinMaxRange(Ogre::Vector3(mX, mY, mZ), Ogre::Vector3(pos.pos)))
return false; return false;
if (pathTo(actor, ESM::Pathgrid::Point(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ)), duration))
{
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
return true;
}
return false;
}
bool AiTravel::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
{
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY; bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
if(!mPathFinder.isPathConstructed() || cellChange) if (!mPathFinder.isPathConstructed() || cellChange)
{ {
mCellX = cell->mData.mX; mCellX = cell->mData.mX;
mCellY = cell->mData.mY; mCellY = cell->mData.mY;
ESM::Pathgrid::Point dest(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ));
ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(pos));
mPathFinder.buildPath(start, dest, actor.getCell(), true);
}
if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1]))
{
movement.mPosition[1] = 0;
return true; return true;
} }
zTurn(actor, Ogre::Degree(mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
movement.mPosition[1] = 1;
return false; return false;
} }

View file

@ -34,6 +34,9 @@ namespace MWMechanics
virtual int getTypeId() const; virtual int getTypeId() const;
protected:
virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell);
private: private:
float mX; float mX;
float mY; float mY;

View file

@ -651,6 +651,9 @@ namespace MWMechanics
if (mAllowedNodes.empty()) if (mAllowedNodes.empty())
return; return;
if (actor.getClass().isPureWaterCreature(actor))
return;
state.moveIn(new AiWanderStorage()); state.moveIn(new AiWanderStorage());
int index = OEngine::Misc::Rng::rollDice(mAllowedNodes.size()); int index = OEngine::Misc::Rng::rollDice(mAllowedNodes.size());
@ -669,6 +672,9 @@ namespace MWMechanics
MWBase::Environment::get().getWorld()->moveObject(actor, static_cast<float>(dest.mX), MWBase::Environment::get().getWorld()->moveObject(actor, static_cast<float>(dest.mX),
static_cast<float>(dest.mY), static_cast<float>(dest.mZ)); static_cast<float>(dest.mY), static_cast<float>(dest.mZ));
actor.getClass().adjustPosition(actor, false); actor.getClass().adjustPosition(actor, false);
// may have changed cell
mStoredAvailableNodes = false;
} }
void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell) void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell)

View file

@ -301,23 +301,35 @@ namespace MWMechanics
return false; return false;
} }
// used by AiCombat, see header for the rationale // see header for the rationale
bool PathFinder::syncStart(const std::list<ESM::Pathgrid::Point> &path) void PathFinder::buildSyncedPath(const ESM::Pathgrid::Point &startPoint,
const ESM::Pathgrid::Point &endPoint,
const MWWorld::CellStore* cell,
bool allowShortcuts)
{ {
if (mPath.size() < 2) if (mPath.size() < 2)
return false; //nothing to pop
std::list<ESM::Pathgrid::Point>::const_iterator oldStart = path.begin();
std::list<ESM::Pathgrid::Point>::iterator iter = ++mPath.begin();
if( (*iter).mX == oldStart->mX
&& (*iter).mY == oldStart->mY
&& (*iter).mZ == oldStart->mZ)
{ {
mPath.pop_front(); // if path has one point, then it's the destination.
return true; // don't need to worry about bad path for this case
buildPath(startPoint, endPoint, cell, allowShortcuts);
}
else
{
const ESM::Pathgrid::Point oldStart(*getPath().begin());
buildPath(startPoint, endPoint, cell, allowShortcuts);
if (mPath.size() >= 2)
{
// if 2nd waypoint of new path == 1st waypoint of old,
// delete 1st waypoint of new path.
std::list<ESM::Pathgrid::Point>::iterator iter = ++mPath.begin();
if (iter->mX == oldStart.mX
&& iter->mY == oldStart.mY
&& iter->mZ == oldStart.mZ)
{
mPath.pop_front();
}
}
} }
return false;
} }
} }

View file

@ -63,13 +63,13 @@ namespace MWMechanics
/** Synchronize new path with old one to avoid visiting 1 waypoint 2 times /** Synchronize new path with old one to avoid visiting 1 waypoint 2 times
@note @note
If the first point is chosen as the nearest one BuildPath() takes closest PathGrid point to NPC as first point of path.
the situation can occur when the 1st point of the new path is undesirable This is undesireable if NPC has just passed a Pathgrid point, as this
(i.e. the 2nd point of new path == the 1st point of old path). makes the 2nd point of the new path == the 1st point of old path.
@param path - old path Which results in NPC "running in a circle" back to the just passed waypoint.
@return true if such point was found and deleted
*/ */
bool syncStart(const std::list<ESM::Pathgrid::Point> &path); void buildSyncedPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint,
const MWWorld::CellStore* cell, bool allowShortcuts = true);
void addPointToPath(ESM::Pathgrid::Point &point) void addPointToPath(ESM::Pathgrid::Point &point)
{ {

View file

@ -188,7 +188,7 @@ namespace MWWorld
const T *ptr = search(id); const T *ptr = search(id);
if (ptr == 0) { if (ptr == 0) {
std::ostringstream msg; std::ostringstream msg;
msg << "Object '" << id << "' not found (const)"; msg << T::getRecordType() << " '" << id << "' not found";
throw std::runtime_error(msg.str()); throw std::runtime_error(msg.str());
} }
return ptr; return ptr;
@ -202,7 +202,7 @@ namespace MWWorld
if(ptr == 0) if(ptr == 0)
{ {
std::ostringstream msg; std::ostringstream msg;
msg << "Object starting with '"<<id<<"' not found (const)"; msg << T::getRecordType() << " starting with '"<<id<<"' not found";
throw std::runtime_error(msg.str()); throw std::runtime_error(msg.str());
} }
return ptr; return ptr;
@ -989,7 +989,7 @@ namespace MWWorld
const T *ptr = search(index); const T *ptr = search(index);
if (ptr == 0) { if (ptr == 0) {
std::ostringstream msg; std::ostringstream msg;
msg << "Object with index " << index << " not found"; msg << T::getRecordType() << " with index " << index << " not found";
throw std::runtime_error(msg.str()); throw std::runtime_error(msg.str());
} }
return ptr; return ptr;

View file

@ -81,7 +81,6 @@ endif (OPENMW_USE_UNSHIELD)
source_group(wizard FILES ${WIZARD} ${WIZARD_HEADER}) source_group(wizard FILES ${WIZARD} ${WIZARD_HEADER})
find_package(Qt4 REQUIRED)
set(QT_USE_QTGUI 1) set(QT_USE_QTGUI 1)
# Set some platform specific settings # Set some platform specific settings
@ -90,12 +89,17 @@ if(WIN32)
set(QT_USE_QTMAIN TRUE) set(QT_USE_QTMAIN TRUE)
endif(WIN32) endif(WIN32)
QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/wizard/wizard.qrc) if (DESIRED_QT_VERSION MATCHES 4)
QT4_WRAP_CPP(MOC_SRCS ${WIZARD_HEADER_MOC}) include(${QT_USE_FILE})
QT4_WRAP_UI(UI_HDRS ${WIZARD_UI}) QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/wizard/wizard.qrc)
QT4_WRAP_CPP(MOC_SRCS ${WIZARD_HEADER_MOC})
QT4_WRAP_UI(UI_HDRS ${WIZARD_UI})
else()
QT5_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/wizard/wizard.qrc)
QT5_WRAP_CPP(MOC_SRCS ${WIZARD_HEADER_MOC})
QT5_WRAP_UI(UI_HDRS ${WIZARD_UI})
endif()
include(${QT_USE_FILE})
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
if (OPENMW_USE_UNSHIELD) if (OPENMW_USE_UNSHIELD)
@ -112,11 +116,24 @@ add_executable(openmw-wizard
) )
target_link_libraries(openmw-wizard target_link_libraries(openmw-wizard
${Boost_LIBRARIES}
${QT_LIBRARIES}
components components
) )
if (DESIRED_QT_VERSION MATCHES 4)
target_link_libraries(openmw-wizard
${QT_QTGUI_LIBRARY}
${QT_QTCORE_LIBRARY})
if (WIN32)
target_link_libraries(openmw-wizard ${QT_QTMAIN_LIBRARY})
endif()
else()
qt5_use_modules(openmw-wizard Widgets Core)
if (WIN32)
target_link_libraries(Qt5::WinMain)
endif()
endif()
if (OPENMW_USE_UNSHIELD) if (OPENMW_USE_UNSHIELD)
target_link_libraries(openmw-wizard ${LIBUNSHIELD_LIBRARY}) target_link_libraries(openmw-wizard ${LIBUNSHIELD_LIBRARY})
endif() endif()

View file

@ -38,9 +38,6 @@ int main(int argc, char *argv[])
QDir::setCurrent(dir.absolutePath()); QDir::setCurrent(dir.absolutePath());
// Support non-latin characters
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
Wizard::MainWizard wizard; Wizard::MainWizard wizard;
wizard.show(); wizard.show();

View file

@ -6,7 +6,6 @@
#include <QWriteLocker> #include <QWriteLocker>
#include <QFileDialog> #include <QFileDialog>
#include <QFileInfo> #include <QFileInfo>
#include <QFileInfoListIterator>
#include <QStringList> #include <QStringList>
#include <QTextStream> #include <QTextStream>
#include <QTextCodec> #include <QTextCodec>

View file

@ -24,7 +24,6 @@ namespace Wizard
class UnshieldWorker : public QObject class UnshieldWorker : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_ENUMS(Wizard::Component)
public: public:
UnshieldWorker(QObject *parent = 0); UnshieldWorker(QObject *parent = 0);

View file

@ -126,32 +126,30 @@ add_component_dir (version
set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
) )
find_package(Qt4 COMPONENTS QtCore QtGui) add_component_qt_dir (contentselector
if(MINGW) model/modelitem model/esmfile
find_package(Bullet REQUIRED COMPONENTS Collision) model/naturalsort model/contentmodel
endif() model/loadordererror
view/combobox view/contentselector
if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) )
add_component_qt_dir (contentselector add_component_qt_dir (config
model/modelitem model/esmfile gamesettings
model/naturalsort model/contentmodel launchersettings
model/loadordererror settingsbase
view/combobox view/contentselector
)
add_component_qt_dir (config
gamesettings
launchersettings
settingsbase
)
add_component_qt_dir (process
processinvoker
) )
include(${QT_USE_FILE}) add_component_qt_dir (process
processinvoker
)
if (DESIRED_QT_VERSION MATCHES 4)
include(${QT_USE_FILE})
QT4_WRAP_UI(ESM_UI_HDR ${ESM_UI}) QT4_WRAP_UI(ESM_UI_HDR ${ESM_UI})
QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES}) QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES})
endif(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) else()
QT5_WRAP_UI(ESM_UI_HDR ${ESM_UI})
QT5_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES})
endif()
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" AND NOT APPLE) if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" AND NOT APPLE)
@ -164,19 +162,33 @@ include_directories(${BULLET_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR}) add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR})
target_link_libraries(components target_link_libraries(components
${Boost_LIBRARIES} ${Boost_SYSTEM_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_WAVE_LIBRARY}
${OGRE_LIBRARIES} ${OGRE_LIBRARIES}
${OENGINE_LIBRARY} ${OENGINE_LIBRARY}
${BULLET_LIBRARIES}
) )
if (WIN32)
target_link_libraries(components
${Boost_LOCALE_LIBRARY})
endif()
if (DESIRED_QT_VERSION MATCHES 4)
target_link_libraries(components
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY})
else()
qt5_use_modules(components Widgets Core)
endif()
if (GIT_CHECKOUT) if (GIT_CHECKOUT)
add_dependencies (components git-version) add_dependencies (components git-version)
endif (GIT_CHECKOUT) endif (GIT_CHECKOUT)
if(MINGW)
target_link_libraries(components ${QT_LIBRARIES} ${BULLET_LIBRARIES})
endif()
if (WIN32) if (WIN32)
target_link_libraries(components shlwapi) target_link_libraries(components shlwapi)
endif() endif()

View file

@ -174,16 +174,30 @@ bool Config::GameSettings::writeFile(QTextStream &stream)
return true; return true;
} }
bool Config::GameSettings::isOrderedLine(const QString& line) const
{
return line.contains(QRegExp("^\\s*fallback-archive\\s*="))
|| line.contains(QRegExp("^\\s*fallback\\s*="))
|| line.contains(QRegExp("^\\s*data\\s*="))
|| line.contains(QRegExp("^\\s*data-local\\s*="))
|| line.contains(QRegExp("^\\s*resources\\s*="))
|| line.contains(QRegExp("^\\s*content\\s*="));
}
// Policy: // Policy:
// //
// - Always ignore a line beginning with '#' or empty lines // - Always ignore a line beginning with '#' or empty lines; added above a config
// entry.
// //
// - If a line in file exists with matching key and first part of value (before ',', // - If a line in file exists with matching key and first part of value (before ',',
// '\n', etc) also matches, then replace the line with that of mUserSettings. // '\n', etc) also matches, then replace the line with that of mUserSettings.
// - else remove line (TODO: maybe replace the line with '#' in front instead?) // - else remove line
// //
// - If there is no corresponding line in file, add at the end // - If there is no corresponding line in file, add at the end
// //
// - Removed content items are saved as comments if the item had any comments.
// Content items prepended with '##' are considered previously removed.
//
bool Config::GameSettings::writeFileWithComments(QFile &file) bool Config::GameSettings::writeFileWithComments(QFile &file)
{ {
QTextStream stream(&file); QTextStream stream(&file);
@ -203,60 +217,124 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
if (fileCopy.empty()) if (fileCopy.empty())
return writeFile(stream); return writeFile(stream);
// Temp copy of settings to save, but with the keys appended with the first part of the value // start
// |
// | +----------------------------------------------------------+
// | | |
// v v |
// skip non-"ordered" lines (remove "ordered" lines) |
// | ^ |
// | | |
// | non-"ordered" line, write saved comments |
// | ^ |
// v | |
// blank or comment line, save in temp buffer <--------+ |
// | | | |
// | +------- comment line ------+ |
// v (special processing '##') |
// "ordered" line |
// | |
// v |
// save in a separate map of comments keyed by "ordered" line |
// | |
// +----------------------------------------------------------+
// //
// ATTENTION!
// //
// A hack to avoid looping through each line, makes use of the fact that fallbacks values
// are comma separated.
QMap<QString, QString> userSettingsCopy;
QRegExp settingRegex("^([^=]+)\\s*=\\s*([^,]+)(.*)$"); QRegExp settingRegex("^([^=]+)\\s*=\\s*([^,]+)(.*)$");
QString settingLine; std::vector<QString> comments;
QMap<QString, QString>::const_iterator settingsIter = mUserSettings.begin(); std::vector<QString>::iterator commentStart = fileCopy.end();
for (; settingsIter != mUserSettings.end(); ++settingsIter) std::map<QString, std::vector<QString> > commentsMap;
{
settingLine = settingsIter.key()+"="+settingsIter.value();
if (settingRegex.indexIn(settingLine) != -1)
{
userSettingsCopy[settingRegex.cap(1)+"="+settingRegex.cap(2)] =
(settingRegex.captureCount() < 3) ? "" : settingRegex.cap(3);
}
}
QString keyVal;
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
{ {
// skip empty or comment lines if (isOrderedLine(*iter))
if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#")))
continue;
// look for a key in the line
if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2)
{ {
// no key or first part of value found in line, replace with a null string which // save in a separate map of comments keyed by "ordered" line
// will be remved later if (!comments.empty())
*iter = QString(); {
continue; if (settingRegex.indexIn(*iter) != -1)
{
commentsMap[settingRegex.cap(1)+"="+settingRegex.cap(2)] = comments;
comments.clear();
commentStart = fileCopy.end();
}
// else do nothing, malformed line
}
*iter = QString(); // "ordered" lines to be removed later
} }
else if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#")))
// look for a matching key in user settings
keyVal = settingRegex.cap(1)+"="+settingRegex.cap(2);
QMap<QString, QString>::iterator it = userSettingsCopy.find(keyVal);
if (it == userSettingsCopy.end())
{ {
// no such key+valStart, replace with a null string which will be remved later // comment line, save in temp buffer
*iter = QString(); if (comments.empty())
commentStart = iter;
// special removed content processing
if ((*iter).contains(QRegExp("^##content\\s*=")))
{
if (!comments.empty())
{
commentsMap[*iter] = comments;
comments.clear();
commentStart = fileCopy.end();
}
}
else
comments.push_back(*iter);
*iter = QString(); // assume to be deleted later
} }
else else
{ {
*iter = QString(it.key()+it.value()); int index = settingRegex.indexIn(*iter);
userSettingsCopy.erase(it);
// blank or non-"ordered" line, write saved comments
if (!comments.empty() && index != -1 && settingRegex.captureCount() >= 2 &&
mUserSettings.find(settingRegex.cap(1)) != mUserSettings.end())
{
for (std::vector<QString>::const_iterator it = comments.begin(); it != comments.end(); ++it)
{
*commentStart = *it;
++commentStart;
}
comments.clear();
commentStart = fileCopy.end();
}
// keep blank lines and non-"ordered" lines other than comments
// look for a key in the line
if (index == -1 || settingRegex.captureCount() < 2)
{
// no key or first part of value found in line, replace with a null string which
// will be remved later
*iter = QString();
comments.clear();
commentStart = fileCopy.end();
continue;
}
// look for a matching key in user settings
*iter = QString(); // assume no match
QString key = settingRegex.cap(1);
QString keyVal = settingRegex.cap(1)+"="+settingRegex.cap(2);
QMap<QString, QString>::const_iterator i = mUserSettings.find(key);
while (i != mUserSettings.end() && i.key() == key)
{
QString settingLine = i.key() + "=" + i.value();
if (settingRegex.indexIn(settingLine) != -1)
{
if ((settingRegex.cap(1)+"="+settingRegex.cap(2)) == keyVal)
{
*iter = settingLine;
break;
}
}
++i;
}
} }
} }
// write the new config file // comments at top of file
QString key;
QString value;
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
{ {
if ((*iter).isNull()) if ((*iter).isNull())
@ -264,41 +342,82 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
// Below is based on readFile() code, if that changes corresponding change may be // Below is based on readFile() code, if that changes corresponding change may be
// required (for example duplicates may be inserted if the rules don't match) // required (for example duplicates may be inserted if the rules don't match)
if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#"))) if (/*(*iter).isEmpty() ||*/ (*iter).contains(QRegExp("^\\s*#")))
{ {
stream << *iter << "\n"; stream << *iter << "\n";
continue; continue;
} }
if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2)
continue;
// Quote paths with spaces
key = settingRegex.cap(1);
value = settingRegex.cap(2)+settingRegex.cap(3);
if (key == QLatin1String("data")
|| key == QLatin1String("data-local")
|| key == QLatin1String("resources"))
{
if (value.contains(QChar(' ')))
{
value.remove(QChar('\"')); // Remove quotes
stream << key << "=\"" << value << "\"\n";
continue;
}
}
stream << key << "=" << value << "\n";
} }
if (!userSettingsCopy.empty()) // Iterate in reverse order to preserve insertion order
QString settingLine;
QMapIterator<QString, QString> it(mUserSettings);
it.toBack();
while (it.hasPrevious())
{ {
stream << "# new entries" << "\n"; it.previous();
QMap<QString, QString>::const_iterator it = userSettingsCopy.begin();
for (; it != userSettingsCopy.end(); ++it) // Quote paths with spaces
if ((it.key() == QLatin1String("data")
|| it.key() == QLatin1String("data-local")
|| it.key() == QLatin1String("resources")) && it.value().contains(QChar(' ')))
{ {
stream << it.key() << it.value() << "\n"; QString stripped = it.value();
stripped.remove(QChar('\"')); // Remove quotes
settingLine = it.key() + "=\"" + stripped + "\"";
} }
else
settingLine = it.key() + "=" + it.value();
if (settingRegex.indexIn(settingLine) != -1)
{
std::map<QString, std::vector<QString> >::iterator i =
commentsMap.find(settingRegex.cap(1)+"="+settingRegex.cap(2));
// check if previous removed content item with comments
if (i == commentsMap.end())
i = commentsMap.find("##"+settingRegex.cap(1)+"="+settingRegex.cap(2));
if (i != commentsMap.end())
{
std::vector<QString> cLines = i->second;
for (std::vector<QString>::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci)
stream << *ci << "\n";
commentsMap.erase(i);
}
}
stream << settingLine << "\n";
}
// flush any removed settings
if (!commentsMap.empty())
{
std::map<QString, std::vector<QString> >::const_iterator i = commentsMap.begin();
for (; i != commentsMap.end(); ++i)
{
if (i->first.contains(QRegExp("^\\s*content\\s*=")))
{
std::vector<QString> cLines = i->second;
for (std::vector<QString>::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci)
stream << *ci << "\n";
// mark the content line entry for future preocessing
stream << "##" << i->first << "\n";
//commentsMap.erase(i);
}
}
}
// flush any end comments
if (!comments.empty())
{
for (std::vector<QString>::const_iterator ci = comments.begin(); ci != comments.end(); ++ci)
stream << *ci << "\n";
} }
file.resize(file.pos()); file.resize(file.pos());

View file

@ -83,6 +83,8 @@ namespace Config
QString mDataLocal; QString mDataLocal;
static const char sContentKey[]; static const char sContentKey[];
bool isOrderedLine(const QString& line) const;
}; };
} }
#endif // GAMESETTINGS_HPP #endif // GAMESETTINGS_HPP

View file

@ -30,17 +30,6 @@ ContentSelectorModel::ContentModel::~ContentModel()
void ContentSelectorModel::ContentModel::setEncoding(const QString &encoding) void ContentSelectorModel::ContentModel::setEncoding(const QString &encoding)
{ {
mEncoding = encoding; mEncoding = encoding;
if (encoding == QLatin1String("win1252"))
mCodec = QTextCodec::codecForName("windows-1252");
else if (encoding == QLatin1String("win1251"))
mCodec = QTextCodec::codecForName("windows-1251");
else if (encoding == QLatin1String("win1250"))
mCodec = QTextCodec::codecForName("windows-1250");
else
return; // This should never happen;
} }
int ContentSelectorModel::ContentModel::columnCount(const QModelIndex &parent) const int ContentSelectorModel::ContentModel::columnCount(const QModelIndex &parent) const
@ -484,6 +473,13 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path)
sortFiles(); sortFiles();
} }
void ContentSelectorModel::ContentModel::clearFiles()
{
beginRemoveRows(QModelIndex(), 0, mFiles.count()-1);
mFiles.clear();
endRemoveRows();
}
QStringList ContentSelectorModel::ContentModel::gameFiles() const QStringList ContentSelectorModel::ContentModel::gameFiles() const
{ {
QStringList gameFiles; QStringList gameFiles;

View file

@ -44,6 +44,7 @@ namespace ContentSelectorModel
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
void addFiles(const QString &path); void addFiles(const QString &path);
void clearFiles();
QModelIndex indexFromItem(const EsmFile *item) const; QModelIndex indexFromItem(const EsmFile *item) const;
const EsmFile *item(const QString &name) const; const EsmFile *item(const QString &name) const;
@ -81,7 +82,6 @@ namespace ContentSelectorModel
ContentFileList mFiles; ContentFileList mFiles;
QHash<QString, Qt::CheckState> mCheckStates; QHash<QString, Qt::CheckState> mCheckStates;
QSet<QString> mPluginsWithLoadOrderError; QSet<QString> mPluginsWithLoadOrderError;
QTextCodec *mCodec;
QString mEncoding; QString mEncoding;
QIcon mWarningIcon; QIcon mWarningIcon;

View file

@ -150,6 +150,11 @@ void ContentSelectorView::ContentSelector::addFiles(const QString &path)
mContentModel->uncheckAll(); mContentModel->uncheckAll();
} }
void ContentSelectorView::ContentSelector::clearFiles()
{
mContentModel->clearFiles();
}
QString ContentSelectorView::ContentSelector::currentFile() const QString ContentSelectorView::ContentSelector::currentFile() const
{ {
QModelIndex currentIdx = ui.addonView->currentIndex(); QModelIndex currentIdx = ui.addonView->currentIndex();

View file

@ -29,6 +29,7 @@ namespace ContentSelectorView
QString currentFile() const; QString currentFile() const;
void addFiles(const QString &path); void addFiles(const QString &path);
void clearFiles();
void setProfileContent (const QStringList &fileList); void setProfileContent (const QStringList &fileList);
void clearCheckStates(); void clearCheckStates();

View file

@ -12,6 +12,8 @@ class ESMWriter;
struct Activator struct Activator
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Activator"; }
std::string mId, mName, mScript, mModel; std::string mId, mName, mScript, mModel;

View file

@ -19,6 +19,9 @@ struct Potion
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Potion"; }
struct ALDTstruct struct ALDTstruct
{ {
float mWeight; float mWeight;

View file

@ -16,6 +16,8 @@ class ESMWriter;
struct Apparatus struct Apparatus
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Apparatus"; }
enum AppaType enum AppaType
{ {

View file

@ -66,6 +66,8 @@ struct PartReferenceList
struct Armor struct Armor
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Armor"; }
enum Type enum Type
{ {

View file

@ -12,6 +12,8 @@ class ESMWriter;
struct BodyPart struct BodyPart
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "BodyPart"; }
enum MeshPart enum MeshPart
{ {

View file

@ -15,6 +15,8 @@ class ESMWriter;
struct Book struct Book
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Book"; }
struct BKDTstruct struct BKDTstruct
{ {

View file

@ -14,6 +14,8 @@ class ESMWriter;
struct BirthSign struct BirthSign
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "BirthSign"; }
std::string mId, mName, mDescription, mTexture; std::string mId, mName, mDescription, mTexture;

View file

@ -56,6 +56,8 @@ typedef std::list<CellRef> CellRefTracker;
struct Cell struct Cell
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Cell"; }
enum Flags enum Flags
{ {

View file

@ -18,6 +18,8 @@ class ESMWriter;
struct Class struct Class
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Class"; }
enum AutoCalc enum AutoCalc
{ {

View file

@ -18,6 +18,8 @@ class ESMWriter;
struct Clothing struct Clothing
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Clothing"; }
enum Type enum Type
{ {

View file

@ -36,6 +36,8 @@ struct InventoryList
struct Container struct Container
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Container"; }
enum Flags enum Flags
{ {

View file

@ -22,6 +22,8 @@ class ESMWriter;
struct Creature struct Creature
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Creature"; }
// Default is 0x48? // Default is 0x48?
enum Flags enum Flags

View file

@ -21,6 +21,8 @@ class ESMWriter;
struct Dialogue struct Dialogue
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Dialogue"; }
enum Type enum Type
{ {

View file

@ -12,6 +12,8 @@ class ESMWriter;
struct Door struct Door
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Door"; }
std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound; std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound;

View file

@ -18,6 +18,8 @@ class ESMWriter;
struct Enchantment struct Enchantment
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Enchantment"; }
enum Type enum Type
{ {

View file

@ -30,6 +30,8 @@ struct RankData
struct Faction struct Faction
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Faction"; }
std::string mId, mName; std::string mId, mName;

View file

@ -18,6 +18,8 @@ class ESMWriter;
struct Global struct Global
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Global"; }
std::string mId; std::string mId;
Variant mValue; Variant mValue;

View file

@ -19,6 +19,8 @@ class ESMWriter;
struct GameSetting struct GameSetting
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "GameSetting"; }
std::string mId; std::string mId;

View file

@ -21,6 +21,8 @@ class ESMWriter;
struct DialInfo struct DialInfo
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "DialInfo"; }
enum Gender enum Gender
{ {

View file

@ -16,6 +16,8 @@ class ESMWriter;
struct Ingredient struct Ingredient
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Ingredient"; }
struct IRDTstruct struct IRDTstruct
{ {

View file

@ -18,6 +18,8 @@ class ESMWriter;
struct Land struct Land
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Land"; }
Land(); Land();
~Land(); ~Land();

View file

@ -46,6 +46,8 @@ struct LevelledListBase
struct CreatureLevList: LevelledListBase struct CreatureLevList: LevelledListBase
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "CreatureLevList"; }
enum Flags enum Flags
{ {
@ -64,6 +66,8 @@ struct CreatureLevList: LevelledListBase
struct ItemLevList: LevelledListBase struct ItemLevList: LevelledListBase
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "ItemLevList"; }
enum Flags enum Flags
{ {

View file

@ -17,6 +17,8 @@ class ESMWriter;
struct Light struct Light
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Light"; }
enum Flags enum Flags
{ {

View file

@ -12,6 +12,8 @@ class ESMWriter;
struct Lockpick struct Lockpick
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Lockpick"; }
struct Data struct Data
{ {

View file

@ -28,6 +28,8 @@ class ESMWriter;
struct LandTexture struct LandTexture
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "LandTexture"; }
std::string mId, mTexture; std::string mId, mTexture;
int mIndex; int mIndex;

View file

@ -13,6 +13,8 @@ class ESMWriter;
struct MagicEffect struct MagicEffect
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "MagicEffect"; }
std::string mId; std::string mId;

View file

@ -17,6 +17,8 @@ class ESMWriter;
struct Miscellaneous struct Miscellaneous
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Miscellaneous"; }
struct MCDTstruct struct MCDTstruct
{ {

View file

@ -23,6 +23,8 @@ class ESMWriter;
struct NPC struct NPC
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "NPC"; }
// Services // Services
enum Services enum Services
@ -52,12 +54,12 @@ struct NPC
enum Flags enum Flags
{ {
Female = 0x0001, Female = 0x0001,
Essential = 0x0002, Essential = 0x0002,
Respawn = 0x0004, Respawn = 0x0004,
Autocalc = 0x0008, Autocalc = 0x0010,
Skeleton = 0x0400, // Skeleton blood effect (white) Skeleton = 0x0400, // Skeleton blood effect (white)
Metal = 0x0800 // Metal blood effect (golden?) Metal = 0x0800 // Metal blood effect (golden?)
}; };
enum NpcType enum NpcType

View file

@ -16,6 +16,8 @@ class ESMWriter;
struct Pathgrid struct Pathgrid
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Pathgrid"; }
struct DATAstruct struct DATAstruct
{ {

View file

@ -12,6 +12,8 @@ class ESMWriter;
struct Probe struct Probe
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Probe"; }
struct Data struct Data
{ {

View file

@ -18,6 +18,8 @@ class ESMWriter;
struct Race struct Race
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Race"; }
struct SkillBonus struct SkillBonus
{ {

View file

@ -19,6 +19,8 @@ class ESMWriter;
struct Region struct Region
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Region"; }
#pragma pack(push) #pragma pack(push)
#pragma pack(1) #pragma pack(1)

View file

@ -12,6 +12,8 @@ class ESMWriter;
struct Repair struct Repair
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Repair"; }
struct Data struct Data
{ {

View file

@ -20,6 +20,8 @@ class Script
{ {
public: public:
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Script"; }
struct SCHDstruct struct SCHDstruct
{ {

View file

@ -20,6 +20,8 @@ class ESMWriter;
struct Skill struct Skill
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Skill"; }
std::string mId; std::string mId;

View file

@ -16,6 +16,8 @@ class ESMWriter;
struct SoundGenerator struct SoundGenerator
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "SoundGenerator"; }
enum Type enum Type
{ {

View file

@ -17,6 +17,8 @@ struct SOUNstruct
struct Sound struct Sound
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Sound"; }
SOUNstruct mData; SOUNstruct mData;
std::string mId, mSound; std::string mId, mSound;

View file

@ -14,6 +14,8 @@ class ESMWriter;
struct Spell struct Spell
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Spell"; }
enum SpellType enum SpellType
{ {

View file

@ -20,6 +20,8 @@ class ESMWriter;
struct StartScript struct StartScript
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "StartScript"; }
std::string mData; std::string mData;
std::string mId; std::string mId;

View file

@ -23,6 +23,8 @@ class ESMWriter;
struct Static struct Static
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Static"; }
std::string mId, mModel; std::string mId, mModel;

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