Merge branch 'master' into feature-color-picking

pull/35/head
Stanislav Bas 10 years ago
commit 850f612c8b

@ -38,7 +38,7 @@ before_script:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi
script:
- 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
after_script:
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi

@ -98,25 +98,29 @@ endif()
cmake_minimum_required(VERSION 2.6)
# Sound setup
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE)
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 )
message(FATAL_ERROR "FFmpeg component required, but not found!")
endif()
set(SOUND_INPUT_INCLUDES ${FFMPEG_INCLUDE_DIRS})
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARIES})
if( SWRESAMPLE_FOUND )
add_definitions(-DHAVE_LIBSWRESAMPLE)
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES})
set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES})
else()
if( AVRESAMPLE_FOUND )
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES})
set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES})
else()
message(FATAL_ERROR "Install either libswresample (FFmpeg) or libavresample (Libav).")
endif()
endif()
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES})
# TinyXML
option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF)
if(USE_SYSTEM_TINYXML)
@ -151,6 +155,19 @@ endif()
# 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
if (UNIX AND NOT APPLE)
find_package (Threads)
@ -171,7 +188,7 @@ if (HAVE_UNORDERED_MAP)
endif ()
set(BOOST_COMPONENTS system filesystem program_options)
set(BOOST_COMPONENTS system filesystem program_options thread wave)
if(WIN32)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale)
endif(WIN32)

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

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

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

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

@ -57,7 +57,6 @@ set(LAUNCHER_UI
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER})
find_package(Qt4 REQUIRED)
set(QT_USE_QTGUI 1)
# Set some platform specific settings
@ -66,12 +65,17 @@ if(WIN32)
set(QT_USE_QTMAIN TRUE)
endif(WIN32)
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})
if (DESIRED_QT_VERSION MATCHES 4)
include(${QT_USE_FILE})
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})
if(NOT WIN32)
include_directories(${LIBUNSHIELD_INCLUDE_DIR})
@ -88,17 +92,27 @@ add_executable(openmw-launcher
)
target_link_libraries(openmw-launcher
${Boost_LIBRARIES}
${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS}
${SDL2_LIBRARY_ONLY}
${QT_LIBRARIES}
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)
add_definitions (--coverage)
target_link_libraries(openmw-launcher gcov)
endif()

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

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

@ -41,7 +41,7 @@ opencs_units (model/tools
opencs_units_noqt (model/tools
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
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)
endif(WIN32)
set(BOOST_COMPONENTS system filesystem program_options thread wave)
if(WIN32)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale)
endif(WIN32)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED)
include(${QT_USE_FILE})
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})
if (DESIRED_QT_VERSION MATCHES 4)
include(${QT_USE_FILE})
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})
else()
qt5_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
qt5_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
qt5_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
endif()
# for compiled .ui files
include_directories(${CMAKE_CURRENT_BINARY_DIR})
@ -207,12 +204,36 @@ target_link_libraries(openmw-cs
${OGRE_Overlay_LIBRARIES}
${OGRE_STATIC_PLUGINS}
${SHINY_LIBRARIES}
${Boost_LIBRARIES}
${Boost_SYSTEM_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_WAVE_LIBRARY}
${BULLET_LIBRARIES}
${QT_LIBRARIES}
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)
INSTALL(TARGETS openmw-cs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE)
endif()

@ -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::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);
mCfgMgr.readConfiguration(variables, desc);
mCfgMgr.readConfiguration(variables, desc, quiet);
mDocumentManager.setEncoding (
ToUTF8::calculateEncoding (variables["encoding"].as<std::string>()));
@ -195,6 +195,11 @@ void CS::Editor::cancelCreateGame()
void CS::Editor::createAddon()
{
mStartup.hide();
mFileDialog.clearFiles();
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig(/*quiet*/true);
setupDataFiles (config.first);
mFileDialog.showDialog (CSVDoc::ContentAction_New);
}
@ -215,6 +220,11 @@ void CS::Editor::cancelFileDialog()
void CS::Editor::loadDocument()
{
mStartup.hide();
mFileDialog.clearFiles();
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig(/*quiet*/true);
setupDataFiles (config.first);
mFileDialog.showDialog (CSVDoc::ContentAction_Edit);
}
@ -307,12 +317,12 @@ bool CS::Editor::makeIPCServer()
mServer->close();
fullPath.remove(QRegExp("dummy$"));
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
std::cout << "Detected unclean shutdown." << std::endl;
// delete the stale file
if(remove(fullPath.toStdString().c_str()))
if(remove(fullPath.toUtf8().constData()))
std::cerr << "ERROR removing stale connection file" << std::endl;
}
}

@ -62,7 +62,7 @@ namespace CS
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
// not implemented

@ -2272,7 +2272,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
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
{

@ -648,7 +648,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
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?
return;

@ -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 + "'"));
}
}

@ -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

@ -27,6 +27,7 @@
#include "startscriptcheck.hpp"
#include "searchoperation.hpp"
#include "pathgridcheck.hpp"
#include "soundgencheck.hpp"
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 SoundGenCheckStage (mData.getSoundGens(),
mData.getSounds(),
mData.getReferenceables()));
mVerifier.setOperation (mVerifierOperation);
}

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

@ -37,10 +37,18 @@ void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData
Record<ESM::Potion>& record = static_cast<Record<ESM::Potion>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion)));
ESM::Potion potion = record.get();
if (column==mAutoCalc)
record.get().mData.mAutoCalc = value.toInt();
potion.mData.mAutoCalc = value.toInt();
else
{
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus)));
ESM::Apparatus apparatus = record.get();
if (column==mType)
record.get().mData.mType = value.toInt();
apparatus.mData.mType = value.toInt();
else if (column==mQuality)
record.get().mData.mQuality = value.toFloat();
apparatus.mData.mQuality = value.toFloat();
else
{
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor)));
ESM::Armor armor = record.get();
if (column==mType)
record.get().mData.mType = value.toInt();
armor.mData.mType = value.toInt();
else if (column==mHealth)
record.get().mData.mHealth = value.toInt();
armor.mData.mHealth = value.toInt();
else if (column==mArmor)
record.get().mData.mArmor = value.toInt();
armor.mData.mArmor = value.toInt();
else
{
EnchantableRefIdAdapter<ESM::Armor>::setData (column, data, index, value);
return;
}
record.setModified(armor);
}
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book)));
ESM::Book book = record.get();
if (column==mScroll)
record.get().mData.mIsScroll = value.toInt();
book.mData.mIsScroll = value.toInt();
else if (column==mSkill)
record.get().mData.mSkillID = value.toInt();
book.mData.mSkillID = value.toInt();
else
{
EnchantableRefIdAdapter<ESM::Book>::setData (column, data, index, value);
return;
}
record.setModified(book);
}
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing)));
ESM::Clothing clothing = record.get();
if (column==mType)
record.get().mData.mType = value.toInt();
clothing.mData.mType = value.toInt();
else
{
EnchantableRefIdAdapter<ESM::Clothing>::setData (column, data, index, value);
return;
}
record.setModified(clothing);
}
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
ESM::Container container = record.get();
if (column==mWeight)
record.get().mWeight = value.toFloat();
container.mWeight = value.toFloat();
else if (column==mOrganic)
{
if (value.toInt())
record.get().mFlags |= ESM::Container::Organic;
container.mFlags |= ESM::Container::Organic;
else
record.get().mFlags &= ~ESM::Container::Organic;
container.mFlags &= ~ESM::Container::Organic;
}
else if (column==mRespawn)
{
if (value.toInt())
record.get().mFlags |= ESM::Container::Respawn;
container.mFlags |= ESM::Container::Respawn;
else
record.get().mFlags &= ~ESM::Container::Respawn;
container.mFlags &= ~ESM::Container::Respawn;
}
else
{
NameRefIdAdapter<ESM::Container>::setData (column, data, index, value);
return;
}
record.setModified(container);
}
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
ESM::Creature creature = record.get();
if (column==mColumns.mType)
record.get().mData.mType = value.toInt();
creature.mData.mType = value.toInt();
else if (column==mColumns.mSoul)
record.get().mData.mSoul = value.toInt();
creature.mData.mSoul = value.toInt();
else if (column==mColumns.mScale)
record.get().mScale = value.toFloat();
creature.mScale = value.toFloat();
else if (column==mColumns.mOriginal)
record.get().mOriginal = value.toString().toUtf8().constData();
creature.mOriginal = value.toString().toUtf8().constData();
else if (column==mColumns.mCombat)
record.get().mData.mCombat = value.toInt();
creature.mData.mCombat = value.toInt();
else if (column==mColumns.mMagic)
record.get().mData.mMagic = value.toInt();
creature.mData.mMagic = value.toInt();
else if (column==mColumns.mStealth)
record.get().mData.mStealth = value.toInt();
creature.mData.mStealth = value.toInt();
else
{
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 (value.toInt()!=0)
record.get().mFlags |= iter->second;
creature.mFlags |= iter->second;
else
record.get().mFlags &= ~iter->second;
creature.mFlags &= ~iter->second;
}
else
{
ActorRefIdAdapter<ESM::Creature>::setData (column, data, index, value);
return;
}
}
record.setModified(creature);
}
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door)));
ESM::Door door = record.get();
if (column==mOpenSound)
record.get().mOpenSound = value.toString().toUtf8().constData();
door.mOpenSound = value.toString().toUtf8().constData();
else if (column==mCloseSound)
record.get().mCloseSound = value.toString().toUtf8().constData();
door.mCloseSound = value.toString().toUtf8().constData();
else
{
NameRefIdAdapter<ESM::Door>::setData (column, data, index, value);
return;
}
record.setModified(door);
}
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light)));
ESM::Light light = record.get();
if (column==mColumns.mTime)
record.get().mData.mTime = value.toInt();
light.mData.mTime = value.toInt();
else if (column==mColumns.mRadius)
record.get().mData.mRadius = value.toInt();
light.mData.mRadius = value.toInt();
else if (column==mColumns.mColor)
record.get().mData.mColor = value.toInt();
light.mData.mColor = value.toInt();
else if (column==mColumns.mSound)
record.get().mSound = value.toString().toUtf8().constData();
light.mSound = value.toString().toUtf8().constData();
else
{
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 (value.toInt()!=0)
record.get().mData.mFlags |= iter->second;
light.mData.mFlags |= iter->second;
else
record.get().mData.mFlags &= ~iter->second;
light.mData.mFlags &= ~iter->second;
}
else
{
InventoryRefIdAdapter<ESM::Light>::setData (column, data, index, value);
return;
}
}
record.setModified (light);
}
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous)));
ESM::Miscellaneous misc = record.get();
if (column==mKey)
record.get().mData.mIsKey = value.toInt();
misc.mData.mIsKey = value.toInt();
else
{
InventoryRefIdAdapter<ESM::Miscellaneous>::setData (column, data, index, value);
return;
}
record.setModified(misc);
}
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>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
ESM::NPC npc = record.get();
if (column==mColumns.mRace)
record.get().mRace = value.toString().toUtf8().constData();
npc.mRace = value.toString().toUtf8().constData();
else if (column==mColumns.mClass)
record.get().mClass = value.toString().toUtf8().constData();
npc.mClass = value.toString().toUtf8().constData();
else if (column==mColumns.mFaction)
record.get().mFaction = value.toString().toUtf8().constData();
npc.mFaction = value.toString().toUtf8().constData();
else if (column==mColumns.mHair)
record.get().mHair = value.toString().toUtf8().constData();
npc.mHair = value.toString().toUtf8().constData();
else if (column==mColumns.mHead)
record.get().mHead = value.toString().toUtf8().constData();
npc.mHead = value.toString().toUtf8().constData();
else
{
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 (value.toInt()!=0)
record.get().mFlags |= iter->second;
npc.mFlags |= iter->second;
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
{
ActorRefIdAdapter<ESM::NPC>::setData (column, data, index, value);
return;
}
}
record.setModified (npc);
}
CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter ()

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

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

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

@ -7,7 +7,7 @@
#include <QMenuBar>
#include <QMdiArea>
#include <QDockWidget>
#include <QtGui/QApplication>
#include <QApplication>
#include <QDesktopWidget>
#include <QScrollArea>
#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.
// 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);
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);
@ -614,6 +612,17 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
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()
{
mViewManager.addView (mDocument);

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

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

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

@ -7,7 +7,12 @@
#include <OgreSceneManager.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/idtable.hpp"

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

@ -3,7 +3,6 @@
#include "settingwindow.hpp"
#include "resizeablestackedwidget.hpp"
#include <QStandardItem>
class QStackedWidget;
class QListWidget;
@ -26,10 +25,6 @@ namespace CSVSettings {
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:
/// Settings are written on close

@ -9,6 +9,8 @@
#include <QStyledItemDelegate>
#include <QTextDocument>
#include <QPainter>
#include <QContextMenuEvent>
#include <QMouseEvent>
#include "../../model/tools/reportmodel.hpp"
@ -121,7 +123,11 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
const CSMWorld::UniversalId& id, bool richTextDescription, QWidget *parent)
: 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);
#endif
horizontalHeader()->setStretchLastSection (true);
verticalHeader()->hide();
setSortingEnabled (true);

@ -65,8 +65,13 @@ CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& tool
mTable->setShowGrid (false);
mTable->verticalHeader()->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 (1, QHeaderView::ResizeToContents);
#endif
mTable->setSelectionMode (QAbstractItemView::NoSelection);
layout->addWidget (mTable);

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

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

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

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

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

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

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

@ -91,17 +91,6 @@ add_openmw_dir (mwbase
)
# 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)
add_executable(openmw
@ -126,10 +115,14 @@ target_link_libraries(openmw
${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS}
${SHINY_LIBRARIES}
${Boost_LIBRARIES}
${OPENAL_LIBRARY}
${SOUND_INPUT_LIBRARY}
${BULLET_LIBRARIES}
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_WAVE_LIBRARY}
${MYGUI_LIBRARIES}
${SDL2_LIBRARY}
${MYGUI_PLATFORM_LIBRARIES}

@ -677,44 +677,32 @@ namespace MWMechanics
return false;
}
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
bool AiCombat::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
{
Ogre::Vector3 newPathTarget = Ogre::Vector3(target.getRefData().getPosition().pos);
float dist;
if(!mPathFinder.getPath().empty())
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
{
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
Ogre::Vector3 currPathTarget(PathFinder::MakeOgreVector3(lastPt));
dist = (newPathTarget - currPathTarget).length();
// necessarily construct a new path
return true;
}
else dist = 1e+38F; // necessarily construct a new path
}
float targetPosThreshold = (actor.getCell()->getCell()->isExterior())? 300.0f : 100.0f;
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
{
ESM::Pathgrid::Point newPathTarget = PathFinder::MakePathgridPoint(target.getRefData().getPosition());
//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(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;
}
}
ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(actor.getRefData().getPosition()));
mPathFinder.buildSyncedPath(start, newPathTarget, actor.getCell(), false);
}
}

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

@ -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
/// 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();
const ESM::Cell *cell = actor.getCell()->getCell();
Movement &movement = actor.getClass().getMovementSettings(actor);
//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(distance(mPrevDest, dest) > 10) { //Only rebuild path if it's moved
mPathFinder.buildPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved
if (doesPathNeedRecalc(dest, cell)) { //Only rebuild path if it's moved
mPathFinder.buildSyncedPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved
mPrevDest = dest;
}
@ -123,3 +123,8 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
return false;
}
bool MWMechanics::AiPackage::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
{
return distance(mPrevDest, dest) > 10;
}

@ -4,6 +4,8 @@
#include "pathfinding.hpp"
#include <components/esm/defs.hpp>
#include "../mwworld/cellstore.hpp"
#include "obstacle.hpp"
#include "aistate.hpp"
@ -71,6 +73,8 @@ namespace MWMechanics
/** \return If the actor has arrived at his destination **/
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
PathFinder mPathFinder;
ObstacleCheck mObstacleCheck;

@ -51,64 +51,31 @@ namespace MWMechanics
bool AiTravel::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
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).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)))
return false;
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
if(!mPathFinder.isPathConstructed() || cellChange)
if (pathTo(actor, ESM::Pathgrid::Point(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ)), duration))
{
mCellX = cell->mData.mX;
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);
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
return true;
}
return false;
}
if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1]))
bool AiTravel::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
{
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
if (!mPathFinder.isPathConstructed() || cellChange)
{
movement.mPosition[1] = 0;
mCellX = cell->mData.mX;
mCellY = cell->mData.mY;
return true;
}
zTurn(actor, Ogre::Degree(mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
movement.mPosition[1] = 1;
return false;
}

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

@ -651,6 +651,9 @@ namespace MWMechanics
if (mAllowedNodes.empty())
return;
if (actor.getClass().isPureWaterCreature(actor))
return;
state.moveIn(new AiWanderStorage());
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),
static_cast<float>(dest.mY), static_cast<float>(dest.mZ));
actor.getClass().adjustPosition(actor, false);
// may have changed cell
mStoredAvailableNodes = false;
}
void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell)

@ -301,23 +301,35 @@ namespace MWMechanics
return false;
}
// used by AiCombat, see header for the rationale
bool PathFinder::syncStart(const std::list<ESM::Pathgrid::Point> &path)
// see header for the rationale
void PathFinder::buildSyncedPath(const ESM::Pathgrid::Point &startPoint,
const ESM::Pathgrid::Point &endPoint,
const MWWorld::CellStore* cell,
bool allowShortcuts)
{
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();
return true;
// if path has one point, then it's the destination.
// 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;
}
}

@ -63,13 +63,13 @@ namespace MWMechanics
/** Synchronize new path with old one to avoid visiting 1 waypoint 2 times
@note
If the first point is chosen as the nearest one
the situation can occur when the 1st point of the new path is undesirable
(i.e. the 2nd point of new path == the 1st point of old path).
@param path - old path
@return true if such point was found and deleted
BuildPath() takes closest PathGrid point to NPC as first point of path.
This is undesireable if NPC has just passed a Pathgrid point, as this
makes the 2nd point of the new path == the 1st point of old path.
Which results in NPC "running in a circle" back to the just passed waypoint.
*/
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)
{

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

@ -81,7 +81,6 @@ endif (OPENMW_USE_UNSHIELD)
source_group(wizard FILES ${WIZARD} ${WIZARD_HEADER})
find_package(Qt4 REQUIRED)
set(QT_USE_QTGUI 1)
# Set some platform specific settings
@ -90,12 +89,17 @@ if(WIN32)
set(QT_USE_QTMAIN TRUE)
endif(WIN32)
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})
if (DESIRED_QT_VERSION MATCHES 4)
include(${QT_USE_FILE})
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})
if (OPENMW_USE_UNSHIELD)
@ -112,11 +116,24 @@ add_executable(openmw-wizard
)
target_link_libraries(openmw-wizard
${Boost_LIBRARIES}
${QT_LIBRARIES}
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)
target_link_libraries(openmw-wizard ${LIBUNSHIELD_LIBRARY})
endif()

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

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

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

@ -126,32 +126,30 @@ add_component_dir (version
set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
)
find_package(Qt4 COMPONENTS QtCore QtGui)
if(MINGW)
find_package(Bullet REQUIRED COMPONENTS Collision)
endif()
if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
add_component_qt_dir (contentselector
model/modelitem model/esmfile
model/naturalsort model/contentmodel
model/loadordererror
view/combobox view/contentselector
)
add_component_qt_dir (config
gamesettings
launchersettings
settingsbase
)
add_component_qt_dir (process
processinvoker
add_component_qt_dir (contentselector
model/modelitem model/esmfile
model/naturalsort model/contentmodel
model/loadordererror
view/combobox view/contentselector
)
add_component_qt_dir (config
gamesettings
launchersettings
settingsbase
)
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_CPP(MOC_SRCS ${COMPONENT_MOC_FILES})
endif(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES})
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_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})
target_link_libraries(components
${Boost_LIBRARIES}
${Boost_SYSTEM_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_WAVE_LIBRARY}
${OGRE_LIBRARIES}
${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)
add_dependencies (components git-version)
endif (GIT_CHECKOUT)
if(MINGW)
target_link_libraries(components ${QT_LIBRARIES} ${BULLET_LIBRARIES})
endif()
if (WIN32)
target_link_libraries(components shlwapi)
endif()

@ -174,16 +174,30 @@ bool Config::GameSettings::writeFile(QTextStream &stream)
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:
//
// - 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 ',',
// '\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
//
// - 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)
{
QTextStream stream(&file);
@ -203,60 +217,124 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
if (fileCopy.empty())
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*([^,]+)(.*)$");
QString settingLine;
QMap<QString, QString>::const_iterator settingsIter = mUserSettings.begin();
for (; settingsIter != mUserSettings.end(); ++settingsIter)
{
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;
std::vector<QString> comments;
std::vector<QString>::iterator commentStart = fileCopy.end();
std::map<QString, std::vector<QString> > commentsMap;
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
{
// skip empty or comment lines
if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#")))
continue;
// look for a key in the line
if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2)
if (isOrderedLine(*iter))
{
// no key or first part of value found in line, replace with a null string which
// will be remved later
*iter = QString();
continue;
}
// save in a separate map of comments keyed by "ordered" line
if (!comments.empty())
{
if (settingRegex.indexIn(*iter) != -1)
{
commentsMap[settingRegex.cap(1)+"="+settingRegex.cap(2)] = comments;
comments.clear();
commentStart = fileCopy.end();
}
// else do nothing, malformed line
}
// 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())
*iter = QString(); // "ordered" lines to be removed later
}
else if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#")))
{
// no such key+valStart, replace with a null string which will be remved later
*iter = QString();
// comment line, save in temp buffer
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
{
*iter = QString(it.key()+it.value());
userSettingsCopy.erase(it);
int index = settingRegex.indexIn(*iter);
// 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
QString key;
QString value;
// comments at top of file
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
{
if ((*iter).isNull())
@ -264,43 +342,84 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
// 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)
if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#")))
if (/*(*iter).isEmpty() ||*/ (*iter).contains(QRegExp("^\\s*#")))
{
stream << *iter << "\n";
continue;
}
}
if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2)
continue;
// Iterate in reverse order to preserve insertion order
QString settingLine;
QMapIterator<QString, QString> it(mUserSettings);
it.toBack();
while (it.hasPrevious())
{
it.previous();
// 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 ((it.key() == QLatin1String("data")
|| it.key() == QLatin1String("data-local")
|| it.key() == QLatin1String("resources")) && it.value().contains(QChar(' ')))
{
QString stripped = it.value();
stripped.remove(QChar('\"')); // Remove quotes
settingLine = it.key() + "=\"" + stripped + "\"";
}
else
settingLine = it.key() + "=" + it.value();
if (settingRegex.indexIn(settingLine) != -1)
{
if (value.contains(QChar(' ')))
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())
{
value.remove(QChar('\"')); // Remove quotes
std::vector<QString> cLines = i->second;
for (std::vector<QString>::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci)
stream << *ci << "\n";
stream << key << "=\"" << value << "\"\n";
continue;
commentsMap.erase(i);
}
}
stream << key << "=" << value << "\n";
stream << settingLine << "\n";
}
if (!userSettingsCopy.empty())
// flush any removed settings
if (!commentsMap.empty())
{
stream << "# new entries" << "\n";
QMap<QString, QString>::const_iterator it = userSettingsCopy.begin();
for (; it != userSettingsCopy.end(); ++it)
std::map<QString, std::vector<QString> >::const_iterator i = commentsMap.begin();
for (; i != commentsMap.end(); ++i)
{
stream << it.key() << it.value() << "\n";
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());
return true;

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

@ -30,17 +30,6 @@ ContentSelectorModel::ContentModel::~ContentModel()
void ContentSelectorModel::ContentModel::setEncoding(const QString &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
@ -484,6 +473,13 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path)
sortFiles();
}
void ContentSelectorModel::ContentModel::clearFiles()
{
beginRemoveRows(QModelIndex(), 0, mFiles.count()-1);
mFiles.clear();
endRemoveRows();
}
QStringList ContentSelectorModel::ContentModel::gameFiles() const
{
QStringList gameFiles;

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

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

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

@ -12,6 +12,8 @@ class ESMWriter;
struct Activator
{
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;

@ -19,6 +19,9 @@ struct Potion
{
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
{
float mWeight;

@ -16,6 +16,8 @@ class ESMWriter;
struct Apparatus
{
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
{

@ -66,6 +66,8 @@ struct PartReferenceList
struct Armor
{
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
{

@ -12,6 +12,8 @@ class ESMWriter;
struct BodyPart
{
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
{

@ -15,6 +15,8 @@ class ESMWriter;
struct Book
{
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
{

@ -14,6 +14,8 @@ class ESMWriter;
struct BirthSign
{
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;

@ -56,6 +56,8 @@ typedef std::list<CellRef> CellRefTracker;
struct Cell
{
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
{

@ -18,6 +18,8 @@ class ESMWriter;
struct Class
{
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
{

@ -18,6 +18,8 @@ class ESMWriter;
struct Clothing
{
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
{

@ -36,6 +36,8 @@ struct InventoryList
struct Container
{
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
{

@ -22,6 +22,8 @@ class ESMWriter;
struct Creature
{
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?
enum Flags

@ -21,6 +21,8 @@ class ESMWriter;
struct Dialogue
{
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
{

@ -12,6 +12,8 @@ class ESMWriter;
struct Door
{
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;

@ -18,6 +18,8 @@ class ESMWriter;
struct Enchantment
{
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
{

@ -30,6 +30,8 @@ struct RankData
struct Faction
{
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;

@ -18,6 +18,8 @@ class ESMWriter;
struct Global
{
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;
Variant mValue;

@ -19,6 +19,8 @@ class ESMWriter;
struct GameSetting
{
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;

@ -21,6 +21,8 @@ class ESMWriter;
struct DialInfo
{
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
{

@ -16,6 +16,8 @@ class ESMWriter;
struct Ingredient
{
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
{

@ -18,6 +18,8 @@ class ESMWriter;
struct Land
{
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();

@ -46,6 +46,8 @@ struct LevelledListBase
struct CreatureLevList: LevelledListBase
{
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
{
@ -64,6 +66,8 @@ struct CreatureLevList: LevelledListBase
struct ItemLevList: LevelledListBase
{
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
{

@ -17,6 +17,8 @@ class ESMWriter;
struct Light
{
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
{

@ -12,6 +12,8 @@ class ESMWriter;
struct Lockpick
{
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
{

@ -28,6 +28,8 @@ class ESMWriter;
struct LandTexture
{
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;
int mIndex;

@ -13,6 +13,8 @@ class ESMWriter;
struct MagicEffect
{
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;

@ -17,6 +17,8 @@ class ESMWriter;
struct Miscellaneous
{
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
{

@ -23,6 +23,8 @@ class ESMWriter;
struct NPC
{
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
enum Services
@ -52,12 +54,12 @@ struct NPC
enum Flags
{
Female = 0x0001,
Essential = 0x0002,
Respawn = 0x0004,
Autocalc = 0x0008,
Skeleton = 0x0400, // Skeleton blood effect (white)
Metal = 0x0800 // Metal blood effect (golden?)
Female = 0x0001,
Essential = 0x0002,
Respawn = 0x0004,
Autocalc = 0x0010,
Skeleton = 0x0400, // Skeleton blood effect (white)
Metal = 0x0800 // Metal blood effect (golden?)
};
enum NpcType

@ -16,6 +16,8 @@ class ESMWriter;
struct Pathgrid
{
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
{

@ -12,6 +12,8 @@ class ESMWriter;
struct Probe
{
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
{

@ -18,6 +18,8 @@ class ESMWriter;
struct Race
{
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
{

@ -19,6 +19,8 @@ class ESMWriter;
struct Region
{
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(1)

@ -12,6 +12,8 @@ class ESMWriter;
struct Repair
{
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
{

@ -20,6 +20,8 @@ class Script
{
public:
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
{

@ -20,6 +20,8 @@ class ESMWriter;
struct Skill
{
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;

@ -16,6 +16,8 @@ class ESMWriter;
struct SoundGenerator
{
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
{

@ -17,6 +17,8 @@ struct SOUNstruct
struct Sound
{
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;
std::string mId, mSound;

@ -14,6 +14,8 @@ class ESMWriter;
struct Spell
{
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
{

@ -20,6 +20,8 @@ class ESMWriter;
struct StartScript
{
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 mId;

@ -23,6 +23,8 @@ class ESMWriter;
struct Static
{
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;

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

Loading…
Cancel
Save